commit 499e068e4f90756bcc833d504c6e063b12683ee3 Author: Hoang Huu Date: Tue Sep 10 11:27:33 2019 +0700 Origin commit diff --git a/.DS_Store b/.DS_Store new file mode 100755 index 00000000..5205550e Binary files /dev/null and b/.DS_Store differ diff --git a/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_clearfix.scssc b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_clearfix.scssc new file mode 100755 index 00000000..693a1794 Binary files /dev/null and b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_clearfix.scssc differ diff --git a/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_grid-framework.scssc b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_grid-framework.scssc new file mode 100755 index 00000000..e52750f4 Binary files /dev/null and b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_grid-framework.scssc differ diff --git a/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_grid.scssc b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_grid.scssc new file mode 100755 index 00000000..06e40323 Binary files /dev/null and b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_grid.scssc differ diff --git a/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_opacity.scssc b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_opacity.scssc new file mode 100755 index 00000000..78ecec99 Binary files /dev/null and b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_opacity.scssc differ diff --git a/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_size.scssc b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_size.scssc new file mode 100755 index 00000000..3f0e744e Binary files /dev/null and b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_size.scssc differ diff --git a/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_vendor-prefixes.scssc b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_vendor-prefixes.scssc new file mode 100755 index 00000000..f298c72d Binary files /dev/null and b/.sass-cache/1d21e5e780fad030823ad74a2af6d1a27bcd8d48/_vendor-prefixes.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_collapsible_ui.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_collapsible_ui.scssc new file mode 100644 index 00000000..ae6afd02 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_collapsible_ui.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_context_metaboxes.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_context_metaboxes.scssc new file mode 100644 index 00000000..f9ebfca3 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_context_metaboxes.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_display.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_display.scssc new file mode 100644 index 00000000..9a9916e5 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_display.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_front.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_front.scssc new file mode 100644 index 00000000..c0ea03c4 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_front.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_jquery_ui.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_jquery_ui.scssc new file mode 100644 index 00000000..0e380588 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_jquery_ui.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_main_wrap.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_main_wrap.scssc new file mode 100644 index 00000000..d9787dcb Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_main_wrap.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_misc.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_misc.scssc new file mode 100644 index 00000000..7f52a5b5 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_misc.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_mixins.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_mixins.scssc new file mode 100644 index 00000000..b9c8d522 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_mixins.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_new_term.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_new_term.scssc new file mode 100644 index 00000000..6465e8d0 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_new_term.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_options-page.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_options-page.scssc new file mode 100644 index 00000000..11a5cbea Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_options-page.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_post_metaboxes.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_post_metaboxes.scssc new file mode 100644 index 00000000..291d4b6b Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_post_metaboxes.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_sidebar_placements.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_sidebar_placements.scssc new file mode 100644 index 00000000..a96bb9ec Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_sidebar_placements.scssc differ diff --git a/.sass-cache/3576b663924608e39840956c643af6db831a264b/_variables.scssc b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_variables.scssc new file mode 100644 index 00000000..1191f8a7 Binary files /dev/null and b/.sass-cache/3576b663924608e39840956c643af6db831a264b/_variables.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_3rd.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_3rd.scssc new file mode 100755 index 00000000..8b6e3938 Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_3rd.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_agency-loop.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_agency-loop.scssc new file mode 100755 index 00000000..70e6ca1a Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_agency-loop.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_archive.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_archive.scssc new file mode 100755 index 00000000..2776df2b Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_archive.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_dashboard.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_dashboard.scssc new file mode 100755 index 00000000..f9397324 Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_dashboard.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_elements.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_elements.scssc new file mode 100644 index 00000000..f2203113 Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_elements.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_form.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_form.scssc new file mode 100644 index 00000000..bab1a681 Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_form.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_layout.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_layout.scssc new file mode 100755 index 00000000..890378ea Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_layout.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_modules.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_modules.scssc new file mode 100755 index 00000000..9d073c5f Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_modules.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_page.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_page.scssc new file mode 100755 index 00000000..a5878daf Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_page.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_properties-loop.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_properties-loop.scssc new file mode 100755 index 00000000..da47921a Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_properties-loop.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_shortcodes.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_shortcodes.scssc new file mode 100755 index 00000000..395eace6 Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_shortcodes.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_single.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_single.scssc new file mode 100644 index 00000000..b63cfb62 Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_single.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_styles.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_styles.scssc new file mode 100755 index 00000000..6c6eb338 Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_styles.scssc differ diff --git a/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_vars.scssc b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_vars.scssc new file mode 100755 index 00000000..8a776def Binary files /dev/null and b/.sass-cache/4502ca9378c9dcd7fc7204391f0bf71ee53c5c0b/_vars.scssc differ diff --git a/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_functions.scssc b/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_functions.scssc new file mode 100755 index 00000000..18817ef1 Binary files /dev/null and b/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_functions.scssc differ diff --git a/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_rtl.scssc b/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_rtl.scssc new file mode 100755 index 00000000..58b93b61 Binary files /dev/null and b/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_rtl.scssc differ diff --git a/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_template-mixins.scssc b/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_template-mixins.scssc new file mode 100755 index 00000000..aa88a962 Binary files /dev/null and b/.sass-cache/89d4189bdcf0dcae9ab52aa7cc9459d0e9ac7109/_template-mixins.scssc differ diff --git a/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2-display.scssc b/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2-display.scssc new file mode 100644 index 00000000..3f5e87b1 Binary files /dev/null and b/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2-display.scssc differ diff --git a/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2-front.scssc b/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2-front.scssc new file mode 100644 index 00000000..6e70c706 Binary files /dev/null and b/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2-front.scssc differ diff --git a/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2.scssc b/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2.scssc new file mode 100644 index 00000000..ef0e7882 Binary files /dev/null and b/.sass-cache/99848c0c56d474befdaf34ec4dac5d06223608ca/cmb2.scssc differ diff --git a/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_grid.scssc b/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_grid.scssc new file mode 100755 index 00000000..70350a1d Binary files /dev/null and b/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_grid.scssc differ diff --git a/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_mixins.scssc b/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_mixins.scssc new file mode 100755 index 00000000..50829c8a Binary files /dev/null and b/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_mixins.scssc differ diff --git a/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_variables.scssc b/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_variables.scssc new file mode 100755 index 00000000..78754984 Binary files /dev/null and b/.sass-cache/bad35fbdbd98634079887c6e2cfb73376fdcb26d/_variables.scssc differ diff --git a/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/admin.scssc b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/admin.scssc new file mode 100644 index 00000000..e1206f0b Binary files /dev/null and b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/admin.scssc differ diff --git a/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/cmb2-front.scssc b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/cmb2-front.scssc new file mode 100644 index 00000000..b3a7e8c9 Binary files /dev/null and b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/cmb2-front.scssc differ diff --git a/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/opalestate.scssc b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/opalestate.scssc new file mode 100755 index 00000000..c42e8b43 Binary files /dev/null and b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/opalestate.scssc differ diff --git a/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/submission.scssc b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/submission.scssc new file mode 100755 index 00000000..8e0231bc Binary files /dev/null and b/.sass-cache/c8d4f7249a62e232d9642ac78c611abb8f19f1ca/submission.scssc differ diff --git a/.sass-cache/f0cbe895c687b32732395abffe5c1daa8c9ae272/_mixins.scssc b/.sass-cache/f0cbe895c687b32732395abffe5c1daa8c9ae272/_mixins.scssc new file mode 100755 index 00000000..b0be5004 Binary files /dev/null and b/.sass-cache/f0cbe895c687b32732395abffe5c1daa8c9ae272/_mixins.scssc differ diff --git a/.sass-cache/f0cbe895c687b32732395abffe5c1daa8c9ae272/_variables.scssc b/.sass-cache/f0cbe895c687b32732395abffe5c1daa8c9ae272/_variables.scssc new file mode 100755 index 00000000..df692ac2 Binary files /dev/null and b/.sass-cache/f0cbe895c687b32732395abffe5c1daa8c9ae272/_variables.scssc differ diff --git a/assets/.DS_Store b/assets/.DS_Store new file mode 100644 index 00000000..2a5e01d6 Binary files /dev/null and b/assets/.DS_Store differ diff --git a/assets/3rd/datepicker.css b/assets/3rd/datepicker.css new file mode 100755 index 00000000..3b16a2f1 --- /dev/null +++ b/assets/3rd/datepicker.css @@ -0,0 +1,356 @@ +/* Date Picker Default Styles */ +.ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + width: 350px; + z-index: 10000 !important; +} + +body.wp-admin:not(.rtl) .ui-datepicker { + margin-left: -1px; +} + +body.wp-admin.rtl .ui-datepicker { + margin-right: -1px; +} + +.ui-datepicker * { + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} + +.ui-datepicker .ui-widget-header, +.ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} + +.ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} + +.ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} + +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: relative; + top: 0; + height: 34px; + width: 34px; +} + +.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} + +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-prev-hover { + left: 0; +} + +.ui-datepicker .ui-datepicker-next, +.ui-datepicker .ui-datepicker-next-hover { + right: 0; +} + +.ui-datepicker .ui-datepicker-next span, +.ui-datepicker .ui-datepicker-prev span { + display: none; +} + +.ui-datepicker .ui-datepicker-prev { + float: left; +} + +.ui-datepicker .ui-datepicker-next { + float: right; +} + +.ui-datepicker .ui-datepicker-prev:before, +.ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-left: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} + +.ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} + +.ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} + +.ui-datepicker .ui-datepicker-prev-hover:before, +.ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} + +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 33%; +} + +.ui-datepicker thead { + color: #fff; + font-weight: 600; +} + +.ui-datepicker th { + padding: 10px; +} + +.ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} + +.ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} + +.ui-datepicker tr:first-of-type td { + border-top: 1px solid #f0f0f0; +} + +.ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f0f0f0; +} + +.ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} + +.ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} + +.ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} + +.ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} + +/* Default Color Scheme */ +.ui-datepicker .ui-widget-header, +.ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +.ui-datepicker thead { + background: #32373c; +} + +.ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* WordPress Color Schemes */ + +/* Fresh */ +.admin-color-fresh .ui-datepicker .ui-widget-header, +.admin-color-fresh .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +.admin-color-fresh .ui-datepicker thead { + background: #32373c; +} + +.admin-color-fresh .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* Blue */ +.admin-color-blue .ui-datepicker .ui-widget-header, +.admin-color-blue .ui-datepicker .ui-datepicker-header { + background: #52accc; +} + +.admin-color-blue .ui-datepicker thead { + background: #4796b3; +} + +.admin-color-blue .ui-datepicker td .ui-state-hover { + background: #096484; + color: #fff; +} + +/* Coffee */ +.admin-color-coffee .ui-datepicker .ui-widget-header, +.admin-color-coffee .ui-datepicker .ui-datepicker-header { + background: #59524c; +} + +.admin-color-coffee .ui-datepicker thead { + background: #46403c; +} + +.admin-color-coffee .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +/* Ectoplasm */ +.admin-color-ectoplasm .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} + +.admin-color-ectoplasm .ui-datepicker thead { + background: #413256; +} + +.admin-color-ectoplasm .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +/* Midnight */ +.admin-color-midnight .ui-datepicker .ui-widget-header, +.admin-color-midnight .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} + +.admin-color-midnight .ui-datepicker thead { + background: #26292c; +} + +.admin-color-midnight .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +/* Ocean */ +.admin-color-ocean .ui-datepicker .ui-widget-header, +.admin-color-ocean .ui-datepicker .ui-datepicker-header { + background: #738e96; +} + +.admin-color-ocean .ui-datepicker thead { + background: #627c83; +} + +.admin-color-ocean .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +/* Sunrise */ +.admin-color-sunrise .ui-datepicker .ui-widget-header, +.admin-color-sunrise .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} + +.admin-color-sunrise .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} + +.admin-color-sunrise .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +/* Light */ +.admin-color-light .ui-datepicker .ui-widget-header, +.admin-color-light .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} + +.admin-color-light .ui-datepicker thead { + background: #888; +} + +.admin-color-light .ui-datepicker .ui-datepicker-title, +.admin-color-light .ui-datepicker td .ui-state-default, +.admin-color-light .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .ui-datepicker .ui-datepicker-next:before { + color: #555; +} + +.admin-color-light .ui-datepicker td .ui-state-hover { + background: #e5e5e5; +} + +/* bbPress Color Schemes */ + +/* Evergreen */ +.admin-color-bbp-evergreen .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .ui-datepicker .ui-datepicker-header { + background: #56b274; +} + +.admin-color-bbp-evergreen .ui-datepicker thead { + background: #36533f; +} + +.admin-color-bbp-evergreen .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +/* Mint */ +.admin-color-bbp-mint .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} + +.admin-color-bbp-mint .ui-datepicker thead { + background: #4f6d59; +} + +.admin-color-bbp-mint .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} \ No newline at end of file diff --git a/assets/3rd/fontawesome/css/all.min.css b/assets/3rd/fontawesome/css/all.min.css new file mode 100755 index 00000000..1460fac6 --- /dev/null +++ b/assets/3rd/fontawesome/css/all.min.css @@ -0,0 +1,5 @@ +/*! + * FontAwesome Free 5.9.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-bacon:before{content:"\f7e5"}.fa-balance-scale:before{content:"\f24e"}.fa-balance-scale-left:before{content:"\f515"}.fa-balance-scale-right:before{content:"\f516"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-battle-net:before{content:"\f835"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-biking:before{content:"\f84a"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-medical:before{content:"\f7e6"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bootstrap:before{content:"\f836"}.fa-border-all:before{content:"\f84c"}.fa-border-none:before{content:"\f850"}.fa-border-style:before{content:"\f853"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-bread-slice:before{content:"\f7ec"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-cheese:before{content:"\f7ef"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clinic-medical:before{content:"\f7f2"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-medical:before{content:"\f7f5"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-crutch:before{content:"\f7f7"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-egg:before{content:"\f7fb"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-evernote:before{content:"\f839"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fan:before{content:"\f863"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hamburger:before{content:"\f805"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-middle-finger:before{content:"\f806"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hard-hat:before{content:"\f807"}.fa-hashtag:before{content:"\f292"}.fa-hat-wizard:before{content:"\f6e8"}.fa-haykal:before{content:"\f666"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotdog:before{content:"\f80f"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-ice-cream:before{content:"\f810"}.fa-icicles:before{content:"\f7ad"}.fa-icons:before{content:"\f86d"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laptop-medical:before{content:"\f812"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-pager:before{content:"\f815"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-carry:before{content:"\f4ce"}.fa-pepper-hot:before{content:"\f816"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-alt:before{content:"\f879"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-square-alt:before{content:"\f87b"}.fa-phone-volume:before{content:"\f2a0"}.fa-photo-video:before{content:"\f87c"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pizza-slice:before{content:"\f818"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-remove-format:before{content:"\f87d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-down-alt:before{content:"\f881"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-alpha-up-alt:before{content:"\f882"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-down-alt:before{content:"\f884"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-amount-up-alt:before{content:"\f885"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-down-alt:before{content:"\f886"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-numeric-up-alt:before{content:"\f887"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spell-check:before{content:"\f891"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-symfony:before{content:"\f83d"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-trash-restore:before{content:"\f829"}.fa-trash-restore-alt:before{content:"\f82a"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-nurse:before{content:"\f82f"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-voicemail:before{content:"\f897"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-wave-square:before{content:"\f83e"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"FontAwesome 5 Brands";font-style:normal;font-weight:normal;font-display:auto;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"FontAwesome 5 Brands"}@font-face{font-family:"FontAwesome";font-style:normal;font-weight:400;font-display:auto;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-weight:400}@font-face{font-family:"FontAwesome";font-style:normal;font-weight:900;font-display:auto;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"FontAwesome"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.eot b/assets/3rd/fontawesome/webfonts/fa-brands-400.eot new file mode 100755 index 00000000..e79f40f9 Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-brands-400.eot differ diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.svg b/assets/3rd/fontawesome/webfonts/fa-brands-400.svg new file mode 100755 index 00000000..ba0d850b --- /dev/null +++ b/assets/3rd/fontawesome/webfonts/fa-brands-400.svg @@ -0,0 +1,3442 @@ + + + + + +Created by FontForge 20190112 at Tue Jun 4 15:16:44 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.ttf b/assets/3rd/fontawesome/webfonts/fa-brands-400.ttf new file mode 100755 index 00000000..217ffe9e Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-brands-400.ttf differ diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.woff b/assets/3rd/fontawesome/webfonts/fa-brands-400.woff new file mode 100755 index 00000000..a2d80254 Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-brands-400.woff differ diff --git a/assets/3rd/fontawesome/webfonts/fa-brands-400.woff2 b/assets/3rd/fontawesome/webfonts/fa-brands-400.woff2 new file mode 100755 index 00000000..e27b0bfa Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-brands-400.woff2 differ diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.eot b/assets/3rd/fontawesome/webfonts/fa-regular-400.eot new file mode 100755 index 00000000..d62be2fa Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-regular-400.eot differ diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.svg b/assets/3rd/fontawesome/webfonts/fa-regular-400.svg new file mode 100755 index 00000000..751083ee --- /dev/null +++ b/assets/3rd/fontawesome/webfonts/fa-regular-400.svg @@ -0,0 +1,803 @@ + + + + + +Created by FontForge 20190112 at Tue Jun 4 15:16:44 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.ttf b/assets/3rd/fontawesome/webfonts/fa-regular-400.ttf new file mode 100755 index 00000000..eb3cb5ef Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-regular-400.ttf differ diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.woff b/assets/3rd/fontawesome/webfonts/fa-regular-400.woff new file mode 100755 index 00000000..43b1a9ae Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-regular-400.woff differ diff --git a/assets/3rd/fontawesome/webfonts/fa-regular-400.woff2 b/assets/3rd/fontawesome/webfonts/fa-regular-400.woff2 new file mode 100755 index 00000000..b9344a74 Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-regular-400.woff2 differ diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.eot b/assets/3rd/fontawesome/webfonts/fa-solid-900.eot new file mode 100755 index 00000000..c77baa8d Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-solid-900.eot differ diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.svg b/assets/3rd/fontawesome/webfonts/fa-solid-900.svg new file mode 100755 index 00000000..627128b8 --- /dev/null +++ b/assets/3rd/fontawesome/webfonts/fa-solid-900.svg @@ -0,0 +1,4649 @@ + + + + + +Created by FontForge 20190112 at Tue Jun 4 15:16:44 2019 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.ttf b/assets/3rd/fontawesome/webfonts/fa-solid-900.ttf new file mode 100755 index 00000000..c6c3dd4d Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-solid-900.ttf differ diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.woff b/assets/3rd/fontawesome/webfonts/fa-solid-900.woff new file mode 100755 index 00000000..77c17862 Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-solid-900.woff differ diff --git a/assets/3rd/fontawesome/webfonts/fa-solid-900.woff2 b/assets/3rd/fontawesome/webfonts/fa-solid-900.woff2 new file mode 100755 index 00000000..e30fb671 Binary files /dev/null and b/assets/3rd/fontawesome/webfonts/fa-solid-900.woff2 differ diff --git a/assets/3rd/index.html b/assets/3rd/index.html new file mode 100755 index 00000000..e69de29b diff --git a/assets/3rd/magnific-popup/jquery.magnific-popup.min.js b/assets/3rd/magnific-popup/jquery.magnific-popup.min.js new file mode 100755 index 00000000..6ee3a3bd --- /dev/null +++ b/assets/3rd/magnific-popup/jquery.magnific-popup.min.js @@ -0,0 +1,4 @@ +/*! Magnific Popup - v1.1.0 - 2016-02-20 +* http://dimsemenov.com/plugins/magnific-popup/ +* Copyright (c) 2016 Dmitry Semenov; */ +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):window.jQuery||window.Zepto)}(function(a){var b,c,d,e,f,g,h="Close",i="BeforeClose",j="AfterClose",k="BeforeAppend",l="MarkupParse",m="Open",n="Change",o="mfp",p="."+o,q="mfp-ready",r="mfp-removing",s="mfp-prevent-close",t=function(){},u=!!window.jQuery,v=a(window),w=function(a,c){b.ev.on(o+a+p,c)},x=function(b,c,d,e){var f=document.createElement("div");return f.className="mfp-"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},y=function(c,d){b.ev.triggerHandler(o+c,d),b.st.callbacks&&(c=c.charAt(0).toLowerCase()+c.slice(1),b.st.callbacks[c]&&b.st.callbacks[c].apply(b,a.isArray(d)?d:[d]))},z=function(c){return c===g&&b.currTemplate.closeBtn||(b.currTemplate.closeBtn=a(b.st.closeMarkup.replace("%title%",b.st.tClose)),g=c),b.currTemplate.closeBtn},A=function(){a.magnificPopup.instance||(b=new t,b.init(),a.magnificPopup.instance=b)},B=function(){var a=document.createElement("p").style,b=["ms","O","Moz","Webkit"];if(void 0!==a.transition)return!0;for(;b.length;)if(b.pop()+"Transition"in a)return!0;return!1};t.prototype={constructor:t,init:function(){var c=navigator.appVersion;b.isLowIE=b.isIE8=document.all&&!document.addEventListener,b.isAndroid=/android/gi.test(c),b.isIOS=/iphone|ipad|ipod/gi.test(c),b.supportsTransition=B(),b.probablyMobile=b.isAndroid||b.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),d=a(document),b.popupsCache={}},open:function(c){var e;if(c.isObj===!1){b.items=c.items.toArray(),b.index=0;var g,h=c.items;for(e=0;e(a||v.height())},_setFocus:function(){(b.st.focus?b.content.find(b.st.focus).eq(0):b.wrap).focus()},_onFocusIn:function(c){return c.target===b.wrap[0]||a.contains(b.wrap[0],c.target)?void 0:(b._setFocus(),!1)},_parseMarkup:function(b,c,d){var e;d.data&&(c=a.extend(d.data,c)),y(l,[b,c,d]),a.each(c,function(c,d){if(void 0===d||d===!1)return!0;if(e=c.split("_"),e.length>1){var f=b.find(p+"-"+e[0]);if(f.length>0){var g=e[1];"replaceWith"===g?f[0]!==d[0]&&f.replaceWith(d):"img"===g?f.is("img")?f.attr("src",d):f.replaceWith(a("").attr("src",d).attr("class",f.attr("class"))):f.attr(e[1],d)}}else b.find(p+"-"+c).html(d)})},_getScrollbarSize:function(){if(void 0===b.scrollbarSize){var a=document.createElement("div");a.style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(a),b.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return b.scrollbarSize}},a.magnificPopup={instance:null,proto:t.prototype,modules:[],open:function(b,c){return A(),b=b?a.extend(!0,{},b):{},b.isObj=!0,b.index=c||0,this.instance.open(b)},close:function(){return a.magnificPopup.instance&&a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'',tClose:"Close (Esc)",tLoading:"Loading...",autoFocusLast:!0}},a.fn.magnificPopup=function(c){A();var d=a(this);if("string"==typeof c)if("open"===c){var e,f=u?d.data("magnificPopup"):d[0].magnificPopup,g=parseInt(arguments[1],10)||0;f.items?e=f.items[g]:(e=d,f.delegate&&(e=e.find(f.delegate)),e=e.eq(g)),b._openClick({mfpEl:e},d,f)}else b.isOpen&&b[c].apply(b,Array.prototype.slice.call(arguments,1));else c=a.extend(!0,{},c),u?d.data("magnificPopup",c):d[0].magnificPopup=c,b.addGroup(d,c);return d};var C,D,E,F="inline",G=function(){E&&(D.after(E.addClass(C)).detach(),E=null)};a.magnificPopup.registerModule(F,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content not found"},proto:{initInline:function(){b.types.push(F),w(h+"."+F,function(){G()})},getInline:function(c,d){if(G(),c.src){var e=b.st.inline,f=a(c.src);if(f.length){var g=f[0].parentNode;g&&g.tagName&&(D||(C=e.hiddenClass,D=x(C),C="mfp-"+C),E=f.after(D).detach().removeClass(C)),b.updateStatus("ready")}else b.updateStatus("error",e.tNotFound),f=a("
");return c.inlineElement=f,f}return b.updateStatus("ready"),b._parseMarkup(d,{},c),d}}});var H,I="ajax",J=function(){H&&a(document.body).removeClass(H)},K=function(){J(),b.req&&b.req.abort()};a.magnificPopup.registerModule(I,{options:{settings:null,cursor:"mfp-ajax-cur",tError:'The content could not be loaded.'},proto:{initAjax:function(){b.types.push(I),H=b.st.ajax.cursor,w(h+"."+I,K),w("BeforeChange."+I,K)},getAjax:function(c){H&&a(document.body).addClass(H),b.updateStatus("loading");var d=a.extend({url:c.src,success:function(d,e,f){var g={data:d,xhr:f};y("ParseAjax",g),b.appendContent(a(g.data),I),c.finished=!0,J(),b._setFocus(),setTimeout(function(){b.wrap.addClass(q)},16),b.updateStatus("ready"),y("AjaxContentAdded")},error:function(){J(),c.finished=c.loadError=!0,b.updateStatus("error",b.st.ajax.tError.replace("%url%",c.src))}},b.st.ajax.settings);return b.req=a.ajax(d),""}}});var L,M=function(c){if(c.data&&void 0!==c.data.title)return c.data.title;var d=b.st.image.titleSrc;if(d){if(a.isFunction(d))return d.call(b,c);if(c.el)return c.el.attr(d)||""}return""};a.magnificPopup.registerModule("image",{options:{markup:'
',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'The image could not be loaded.'},proto:{initImage:function(){var c=b.st.image,d=".image";b.types.push("image"),w(m+d,function(){"image"===b.currItem.type&&c.cursor&&a(document.body).addClass(c.cursor)}),w(h+d,function(){c.cursor&&a(document.body).removeClass(c.cursor),v.off("resize"+p)}),w("Resize"+d,b.resizeImage),b.isLowIE&&w("AfterChange",b.resizeImage)},resizeImage:function(){var a=b.currItem;if(a&&a.img&&b.st.image.verticalFit){var c=0;b.isLowIE&&(c=parseInt(a.img.css("padding-top"),10)+parseInt(a.img.css("padding-bottom"),10)),a.img.css("max-height",b.wH-c)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,L&&clearInterval(L),a.isCheckingImgSize=!1,y("ImageHasSize",a),a.imgHidden&&(b.content&&b.content.removeClass("mfp-loading"),a.imgHidden=!1))},findImageSize:function(a){var c=0,d=a.img[0],e=function(f){L&&clearInterval(L),L=setInterval(function(){return d.naturalWidth>0?void b._onImageHasSize(a):(c>200&&clearInterval(L),c++,void(3===c?e(10):40===c?e(50):100===c&&e(500)))},f)};e(1)},getImage:function(c,d){var e=0,f=function(){c&&(c.img[0].complete?(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("ready")),c.hasSize=!0,c.loaded=!0,y("ImageLoadComplete")):(e++,200>e?setTimeout(f,100):g()))},g=function(){c&&(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("error",h.tError.replace("%url%",c.src))),c.hasSize=!0,c.loaded=!0,c.loadError=!0)},h=b.st.image,i=d.find(".mfp-img");if(i.length){var j=document.createElement("img");j.className="mfp-img",c.el&&c.el.find("img").length&&(j.alt=c.el.find("img").attr("alt")),c.img=a(j).on("load.mfploader",f).on("error.mfploader",g),j.src=c.src,i.is("img")&&(c.img=c.img.clone()),j=c.img[0],j.naturalWidth>0?c.hasSize=!0:j.width||(c.hasSize=!1)}return b._parseMarkup(d,{title:M(c),img_replaceWith:c.img},c),b.resizeImage(),c.hasSize?(L&&clearInterval(L),c.loadError?(d.addClass("mfp-loading"),b.updateStatus("error",h.tError.replace("%url%",c.src))):(d.removeClass("mfp-loading"),b.updateStatus("ready")),d):(b.updateStatus("loading"),c.loading=!0,c.hasSize||(c.imgHidden=!0,d.addClass("mfp-loading"),b.findImageSize(c)),d)}}});var N,O=function(){return void 0===N&&(N=void 0!==document.createElement("p").style.MozTransform),N};a.magnificPopup.registerModule("zoom",{options:{enabled:!1,easing:"ease-in-out",duration:300,opener:function(a){return a.is("img")?a:a.find("img")}},proto:{initZoom:function(){var a,c=b.st.zoom,d=".zoom";if(c.enabled&&b.supportsTransition){var e,f,g=c.duration,j=function(a){var b=a.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),d="all "+c.duration/1e3+"s "+c.easing,e={position:"fixed",zIndex:9999,left:0,top:0,"-webkit-backface-visibility":"hidden"},f="transition";return e["-webkit-"+f]=e["-moz-"+f]=e["-o-"+f]=e[f]=d,b.css(e),b},k=function(){b.content.css("visibility","visible")};w("BuildControls"+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.content.css("visibility","hidden"),a=b._getItemToZoom(),!a)return void k();f=j(a),f.css(b._getOffset()),b.wrap.append(f),e=setTimeout(function(){f.css(b._getOffset(!0)),e=setTimeout(function(){k(),setTimeout(function(){f.remove(),a=f=null,y("ZoomAnimationEnded")},16)},g)},16)}}),w(i+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.st.removalDelay=g,!a){if(a=b._getItemToZoom(),!a)return;f=j(a)}f.css(b._getOffset(!0)),b.wrap.append(f),b.content.css("visibility","hidden"),setTimeout(function(){f.css(b._getOffset())},16)}}),w(h+d,function(){b._allowZoom()&&(k(),f&&f.remove(),a=null)})}},_allowZoom:function(){return"image"===b.currItem.type},_getItemToZoom:function(){return b.currItem.hasSize?b.currItem.img:!1},_getOffset:function(c){var d;d=c?b.currItem.img:b.st.zoom.opener(b.currItem.el||b.currItem);var e=d.offset(),f=parseInt(d.css("padding-top"),10),g=parseInt(d.css("padding-bottom"),10);e.top-=a(window).scrollTop()-f;var h={width:d.width(),height:(u?d.innerHeight():d[0].offsetHeight)-g-f};return O()?h["-moz-transform"]=h.transform="translate("+e.left+"px,"+e.top+"px)":(h.left=e.left,h.top=e.top),h}}});var P="iframe",Q="//about:blank",R=function(a){if(b.currTemplate[P]){var c=b.currTemplate[P].find("iframe");c.length&&(a||(c[0].src=Q),b.isIE8&&c.css("display",a?"block":"none"))}};a.magnificPopup.registerModule(P,{options:{markup:'
',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){b.types.push(P),w("BeforeChange",function(a,b,c){b!==c&&(b===P?R():c===P&&R(!0))}),w(h+"."+P,function(){R()})},getIframe:function(c,d){var e=c.src,f=b.st.iframe;a.each(f.patterns,function(){return e.indexOf(this.index)>-1?(this.id&&(e="string"==typeof this.id?e.substr(e.lastIndexOf(this.id)+this.id.length,e.length):this.id.call(this,e)),e=this.src.replace("%id%",e),!1):void 0});var g={};return f.srcAction&&(g[f.srcAction]=e),b._parseMarkup(d,g,c),b.updateStatus("ready"),d}}});var S=function(a){var c=b.items.length;return a>c-1?a-c:0>a?c+a:a},T=function(a,b,c){return a.replace(/%curr%/gi,b+1).replace(/%total%/gi,c)};a.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%"},proto:{initGallery:function(){var c=b.st.gallery,e=".mfp-gallery";return b.direction=!0,c&&c.enabled?(f+=" mfp-gallery",w(m+e,function(){c.navigateByImgClick&&b.wrap.on("click"+e,".mfp-img",function(){return b.items.length>1?(b.next(),!1):void 0}),d.on("keydown"+e,function(a){37===a.keyCode?b.prev():39===a.keyCode&&b.next()})}),w("UpdateStatus"+e,function(a,c){c.text&&(c.text=T(c.text,b.currItem.index,b.items.length))}),w(l+e,function(a,d,e,f){var g=b.items.length;e.counter=g>1?T(c.tCounter,f.index,g):""}),w("BuildControls"+e,function(){if(b.items.length>1&&c.arrows&&!b.arrowLeft){var d=c.arrowMarkup,e=b.arrowLeft=a(d.replace(/%title%/gi,c.tPrev).replace(/%dir%/gi,"left")).addClass(s),f=b.arrowRight=a(d.replace(/%title%/gi,c.tNext).replace(/%dir%/gi,"right")).addClass(s);e.click(function(){b.prev()}),f.click(function(){b.next()}),b.container.append(e.add(f))}}),w(n+e,function(){b._preloadTimeout&&clearTimeout(b._preloadTimeout),b._preloadTimeout=setTimeout(function(){b.preloadNearbyImages(),b._preloadTimeout=null},16)}),void w(h+e,function(){d.off(e),b.wrap.off("click"+e),b.arrowRight=b.arrowLeft=null})):!1},next:function(){b.direction=!0,b.index=S(b.index+1),b.updateItemHTML()},prev:function(){b.direction=!1,b.index=S(b.index-1),b.updateItemHTML()},goTo:function(a){b.direction=a>=b.index,b.index=a,b.updateItemHTML()},preloadNearbyImages:function(){var a,c=b.st.gallery.preload,d=Math.min(c[0],b.items.length),e=Math.min(c[1],b.items.length);for(a=1;a<=(b.direction?e:d);a++)b._preloadItem(b.index+a);for(a=1;a<=(b.direction?d:e);a++)b._preloadItem(b.index-a)},_preloadItem:function(c){if(c=S(c),!b.items[c].preloaded){var d=b.items[c];d.parsed||(d=b.parseEl(c)),y("LazyLoad",d),"image"===d.type&&(d.img=a('').on("load.mfploader",function(){d.hasSize=!0}).on("error.mfploader",function(){d.hasSize=!0,d.loadError=!0,y("LazyLoadError",d)}).attr("src",d.src)),d.preloaded=!0}}}});var U="retina";a.magnificPopup.registerModule(U,{options:{replaceSrc:function(a){return a.src.replace(/\.\w+$/,function(a){return"@2x"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var a=b.st.retina,c=a.ratio;c=isNaN(c)?c():c,c>1&&(w("ImageHasSize."+U,function(a,b){b.img.css({"max-width":b.img[0].naturalWidth/c,width:"100%"})}),w("ElementParse."+U,function(b,d){d.src=a.replaceSrc(d,c)}))}}}}),A()}); \ No newline at end of file diff --git a/assets/3rd/select2/css/select2.css b/assets/3rd/select2/css/select2.css new file mode 100755 index 00000000..ce3afd1d --- /dev/null +++ b/assets/3rd/select2/css/select2.css @@ -0,0 +1,484 @@ +.select2-container { + box-sizing: border-box; + display: inline-block; + margin: 0; + position: relative; + vertical-align: middle; } + .select2-container .select2-selection--single { + box-sizing: border-box; + cursor: pointer; + display: block; + height: 28px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--single .select2-selection__rendered { + display: block; + padding-left: 8px; + padding-right: 20px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-selection--single .select2-selection__clear { + position: relative; } + .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { + padding-right: 8px; + padding-left: 20px; } + .select2-container .select2-selection--multiple { + box-sizing: border-box; + cursor: pointer; + display: block; + min-height: 32px; + user-select: none; + -webkit-user-select: none; } + .select2-container .select2-selection--multiple .select2-selection__rendered { + display: inline-block; + overflow: hidden; + padding-left: 8px; + text-overflow: ellipsis; + white-space: nowrap; } + .select2-container .select2-search--inline { + float: left; } + .select2-container .select2-search--inline .select2-search__field { + box-sizing: border-box; + border: none; + font-size: 100%; + margin-top: 5px; + padding: 0; } + .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + +.select2-dropdown { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + box-sizing: border-box; + display: block; + position: absolute; + left: -100000px; + width: 100%; + z-index: 1051; } + +.select2-results { + display: block; } + +.select2-results__options { + list-style: none; + margin: 0; + padding: 0; } + +.select2-results__option { + padding: 6px; + user-select: none; + -webkit-user-select: none; } + .select2-results__option[aria-selected] { + cursor: pointer; } + +.select2-container--open .select2-dropdown { + left: 0; } + +.select2-container--open .select2-dropdown--above { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--open .select2-dropdown--below { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-search--dropdown { + display: block; + padding: 4px; } + .select2-search--dropdown .select2-search__field { + padding: 4px; + width: 100%; + box-sizing: border-box; } + .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { + -webkit-appearance: none; } + .select2-search--dropdown.select2-search--hide { + display: none; } + +.select2-close-mask { + border: 0; + margin: 0; + padding: 0; + display: block; + position: fixed; + left: 0; + top: 0; + min-height: 100%; + min-width: 100%; + height: auto; + width: auto; + opacity: 0; + z-index: 99; + background-color: #fff; + filter: alpha(opacity=0); } + +.select2-hidden-accessible { + border: 0 !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(50%) !important; + clip-path: inset(50%) !important; + height: 1px !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + width: 1px !important; + white-space: nowrap !important; } + +.select2-container--default .select2-selection--single { + background-color: #fff; + border: 1px solid #aaa; + border-radius: 4px; } + .select2-container--default .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--default .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; } + .select2-container--default .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--default .select2-selection--single .select2-selection__arrow { + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; } + .select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { + left: 1px; + right: auto; } + +.select2-container--default.select2-container--disabled .select2-selection--single { + background-color: #eee; + cursor: default; } + .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { + display: none; } + +.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--default .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered { + box-sizing: border-box; + list-style: none; + margin: 0; + padding: 0 5px; + width: 100%; } + .select2-container--default .select2-selection--multiple .select2-selection__rendered li { + list-style: none; } + .select2-container--default .select2-selection--multiple .select2-selection__placeholder { + color: #999; + margin-top: 5px; + float: left; } + .select2-container--default .select2-selection--multiple .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-top: 5px; + margin-right: 10px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { + color: #999; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #333; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { + float: right; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + margin-left: 5px; + margin-right: auto; } + +.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--default.select2-container--focus .select2-selection--multiple { + border: solid black 1px; + outline: 0; } + +.select2-container--default.select2-container--disabled .select2-selection--multiple { + background-color: #eee; + cursor: default; } + +.select2-container--default.select2-container--disabled .select2-selection__choice__remove { + display: none; } + +.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--default .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; } + +.select2-container--default .select2-search--inline .select2-search__field { + background: transparent; + border: none; + outline: 0; + box-shadow: none; + -webkit-appearance: textfield; } + +.select2-container--default .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--default .select2-results__option[role=group] { + padding: 0; } + +.select2-container--default .select2-results__option[aria-disabled=true] { + color: #999; } + +.select2-container--default .select2-results__option[aria-selected=true] { + background-color: #ddd; } + +.select2-container--default .select2-results__option .select2-results__option { + padding-left: 1em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__group { + padding-left: 0; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option { + margin-left: -1em; + padding-left: 2em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -2em; + padding-left: 3em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -3em; + padding-left: 4em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -4em; + padding-left: 5em; } + .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { + margin-left: -5em; + padding-left: 6em; } + +.select2-container--default .select2-results__option--highlighted[aria-selected] { + background-color: #5897fb; + color: white; } + +.select2-container--default .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic .select2-selection--single { + background-color: #f7f7f7; + border: 1px solid #aaa; + border-radius: 4px; + outline: 0; + background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); + background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + .select2-container--classic .select2-selection--single:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--single .select2-selection__rendered { + color: #444; + line-height: 28px; } + .select2-container--classic .select2-selection--single .select2-selection__clear { + cursor: pointer; + float: right; + font-weight: bold; + margin-right: 10px; } + .select2-container--classic .select2-selection--single .select2-selection__placeholder { + color: #999; } + .select2-container--classic .select2-selection--single .select2-selection__arrow { + background-color: #ddd; + border: none; + border-left: 1px solid #aaa; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + height: 26px; + position: absolute; + top: 1px; + right: 1px; + width: 20px; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } + .select2-container--classic .select2-selection--single .select2-selection__arrow b { + border-color: #888 transparent transparent transparent; + border-style: solid; + border-width: 5px 4px 0 4px; + height: 0; + left: 50%; + margin-left: -4px; + margin-top: -2px; + position: absolute; + top: 50%; + width: 0; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { + float: left; } + +.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { + border: none; + border-right: 1px solid #aaa; + border-radius: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + left: 1px; + right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--single { + border: 1px solid #5897fb; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { + background: transparent; + border: none; } + .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { + border-color: transparent transparent #888 transparent; + border-width: 0 4px 5px 4px; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; + background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); + background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); + background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } + +.select2-container--classic .select2-selection--multiple { + background-color: white; + border: 1px solid #aaa; + border-radius: 4px; + cursor: text; + outline: 0; } + .select2-container--classic .select2-selection--multiple:focus { + border: 1px solid #5897fb; } + .select2-container--classic .select2-selection--multiple .select2-selection__rendered { + list-style: none; + margin: 0; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__clear { + display: none; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice { + background-color: #e4e4e4; + border: 1px solid #aaa; + border-radius: 4px; + cursor: default; + float: left; + margin-right: 5px; + margin-top: 5px; + padding: 0 5px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { + color: #888; + cursor: pointer; + display: inline-block; + font-weight: bold; + margin-right: 2px; } + .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { + color: #555; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { + float: right; + margin-left: 5px; + margin-right: auto; } + +.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { + margin-left: 2px; + margin-right: auto; } + +.select2-container--classic.select2-container--open .select2-selection--multiple { + border: 1px solid #5897fb; } + +.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { + border-top: none; + border-top-left-radius: 0; + border-top-right-radius: 0; } + +.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; } + +.select2-container--classic .select2-search--dropdown .select2-search__field { + border: 1px solid #aaa; + outline: 0; } + +.select2-container--classic .select2-search--inline .select2-search__field { + outline: 0; + box-shadow: none; } + +.select2-container--classic .select2-dropdown { + background-color: white; + border: 1px solid transparent; } + +.select2-container--classic .select2-dropdown--above { + border-bottom: none; } + +.select2-container--classic .select2-dropdown--below { + border-top: none; } + +.select2-container--classic .select2-results > .select2-results__options { + max-height: 200px; + overflow-y: auto; } + +.select2-container--classic .select2-results__option[role=group] { + padding: 0; } + +.select2-container--classic .select2-results__option[aria-disabled=true] { + color: grey; } + +.select2-container--classic .select2-results__option--highlighted[aria-selected] { + background-color: #3875d7; + color: white; } + +.select2-container--classic .select2-results__group { + cursor: default; + display: block; + padding: 6px; } + +.select2-container--classic.select2-container--open .select2-dropdown { + border-color: #5897fb; } diff --git a/assets/3rd/select2/css/select2.min.css b/assets/3rd/select2/css/select2.min.css new file mode 100755 index 00000000..60d59904 --- /dev/null +++ b/assets/3rd/select2/css/select2.min.css @@ -0,0 +1 @@ +.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} diff --git a/assets/3rd/select2/js/i18n/af.js b/assets/3rd/select2/js/i18n/af.js new file mode 100755 index 00000000..d835a91e --- /dev/null +++ b/assets/3rd/select2/js/i18n/af.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ar.js b/assets/3rd/select2/js/i18n/ar.js new file mode 100755 index 00000000..d31b67bc --- /dev/null +++ b/assets/3rd/select2/js/i18n/ar.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/az.js b/assets/3rd/select2/js/i18n/az.js new file mode 100755 index 00000000..58471745 --- /dev/null +++ b/assets/3rd/select2/js/i18n/az.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/bg.js b/assets/3rd/select2/js/i18n/bg.js new file mode 100755 index 00000000..09d0ac61 --- /dev/null +++ b/assets/3rd/select2/js/i18n/bg.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/bn.js b/assets/3rd/select2/js/i18n/bn.js new file mode 100755 index 00000000..a224e805 --- /dev/null +++ b/assets/3rd/select2/js/i18n/bn.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/bs.js b/assets/3rd/select2/js/i18n/bs.js new file mode 100755 index 00000000..9d91773b --- /dev/null +++ b/assets/3rd/select2/js/i18n/bs.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ca.js b/assets/3rd/select2/js/i18n/ca.js new file mode 100755 index 00000000..66afe55f --- /dev/null +++ b/assets/3rd/select2/js/i18n/ca.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/cs.js b/assets/3rd/select2/js/i18n/cs.js new file mode 100755 index 00000000..52d7fb05 --- /dev/null +++ b/assets/3rd/select2/js/i18n/cs.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/da.js b/assets/3rd/select2/js/i18n/da.js new file mode 100755 index 00000000..d0234204 --- /dev/null +++ b/assets/3rd/select2/js/i18n/da.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/de.js b/assets/3rd/select2/js/i18n/de.js new file mode 100755 index 00000000..eff40fdc --- /dev/null +++ b/assets/3rd/select2/js/i18n/de.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Eintr";return 1===e.maximum?n+="ag":n+="äge",n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Gegenstände"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/dsb.js b/assets/3rd/select2/js/i18n/dsb.js new file mode 100755 index 00000000..8d6b555d --- /dev/null +++ b/assets/3rd/select2/js/i18n/dsb.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/el.js b/assets/3rd/select2/js/i18n/el.js new file mode 100755 index 00000000..46954e95 --- /dev/null +++ b/assets/3rd/select2/js/i18n/el.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/en.js b/assets/3rd/select2/js/i18n/en.js new file mode 100755 index 00000000..8af09628 --- /dev/null +++ b/assets/3rd/select2/js/i18n/en.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/es.js b/assets/3rd/select2/js/i18n/es.js new file mode 100755 index 00000000..a84b1f39 --- /dev/null +++ b/assets/3rd/select2/js/i18n/es.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Por favor, elimine "+n+" car";return r+=1==n?"ácter":"acteres"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Por favor, introduzca "+n+" car";return r+=1==n?"ácter":"acteres"},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var n="Sólo puede seleccionar "+e.maximum+" elemento";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/et.js b/assets/3rd/select2/js/i18n/et.js new file mode 100755 index 00000000..382ad98c --- /dev/null +++ b/assets/3rd/select2/js/i18n/et.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/eu.js b/assets/3rd/select2/js/i18n/eu.js new file mode 100755 index 00000000..3333f1ab --- /dev/null +++ b/assets/3rd/select2/js/i18n/eu.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/fa.js b/assets/3rd/select2/js/i18n/fa.js new file mode 100755 index 00000000..fcda49e0 --- /dev/null +++ b/assets/3rd/select2/js/i18n/fa.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها می‌توانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/fi.js b/assets/3rd/select2/js/i18n/fi.js new file mode 100755 index 00000000..e84f0add --- /dev/null +++ b/assets/3rd/select2/js/i18n/fi.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/fr.js b/assets/3rd/select2/js/i18n/fr.js new file mode 100755 index 00000000..3d51cdf4 --- /dev/null +++ b/assets/3rd/select2/js/i18n/fr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var n=e.input.length-e.maximum;return"Supprimez "+n+" caractère"+(n>1?"s":"")},inputTooShort:function(e){var n=e.minimum-e.input.length;return"Saisissez au moins "+n+" caractère"+(n>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les articles"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/gl.js b/assets/3rd/select2/js/i18n/gl.js new file mode 100755 index 00000000..bb88dc4a --- /dev/null +++ b/assets/3rd/select2/js/i18n/gl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var n=e.input.length-e.maximum;return 1===n?"Elimine un carácter":"Elimine "+n+" caracteres"},inputTooShort:function(e){var n=e.minimum-e.input.length;return 1===n?"Engada un carácter":"Engada "+n+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return 1===e.maximum?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/he.js b/assets/3rd/select2/js/i18n/he.js new file mode 100755 index 00000000..bf52345f --- /dev/null +++ b/assets/3rd/select2/js/i18n/he.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/hi.js b/assets/3rd/select2/js/i18n/hi.js new file mode 100755 index 00000000..689dc375 --- /dev/null +++ b/assets/3rd/select2/js/i18n/hi.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/hr.js b/assets/3rd/select2/js/i18n/hr.js new file mode 100755 index 00000000..2377ddcd --- /dev/null +++ b/assets/3rd/select2/js/i18n/hr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/hsb.js b/assets/3rd/select2/js/i18n/hsb.js new file mode 100755 index 00000000..3fd5cb79 --- /dev/null +++ b/assets/3rd/select2/js/i18n/hsb.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hsb",[],function(){var n=["znamješko","znamješce","znamješka","znamješkow"],e=["zapisk","zapiskaj","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Prošu zhašej "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Prošu zapodaj znajmjeńša "+a+" "+u(a,n)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(n){return"Móžeš jenož "+n.maximum+" "+u(n.maximum,e)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/hu.js b/assets/3rd/select2/js/i18n/hu.js new file mode 100755 index 00000000..ff0ad75b --- /dev/null +++ b/assets/3rd/select2/js/i18n/hu.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/hy.js b/assets/3rd/select2/js/i18n/hy.js new file mode 100755 index 00000000..b26221d6 --- /dev/null +++ b/assets/3rd/select2/js/i18n/hy.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/id.js b/assets/3rd/select2/js/i18n/id.js new file mode 100755 index 00000000..87f25034 --- /dev/null +++ b/assets/3rd/select2/js/i18n/id.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(n){return"Hapuskan "+(n.input.length-n.maximum)+" huruf"},inputTooShort:function(n){return"Masukkan "+(n.minimum-n.input.length)+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(n){return"Anda hanya dapat memilih "+n.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/is.js b/assets/3rd/select2/js/i18n/is.js new file mode 100755 index 00000000..6df6bb5f --- /dev/null +++ b/assets/3rd/select2/js/i18n/is.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/is",[],function(){return{inputTooLong:function(n){var t=n.input.length-n.maximum,e="Vinsamlegast styttið texta um "+t+" staf";return t<=1?e:e+"i"},inputTooShort:function(n){var t=n.minimum-n.input.length,e="Vinsamlegast skrifið "+t+" staf";return t>1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/it.js b/assets/3rd/select2/js/i18n/it.js new file mode 100755 index 00000000..98cf93a0 --- /dev/null +++ b/assets/3rd/select2/js/i18n/it.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ja.js b/assets/3rd/select2/js/i18n/ja.js new file mode 100755 index 00000000..a0062c76 --- /dev/null +++ b/assets/3rd/select2/js/i18n/ja.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(n){return n.input.length-n.maximum+" 文字を削除してください"},inputTooShort:function(n){return"少なくとも "+(n.minimum-n.input.length)+" 文字を入力してください"},loadingMore:function(){return"読み込み中…"},maximumSelected:function(n){return n.maximum+" 件しか選択できません"},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ka.js b/assets/3rd/select2/js/i18n/ka.js new file mode 100755 index 00000000..5ef45dd4 --- /dev/null +++ b/assets/3rd/select2/js/i18n/ka.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/km.js b/assets/3rd/select2/js/i18n/km.js new file mode 100755 index 00000000..97999667 --- /dev/null +++ b/assets/3rd/select2/js/i18n/km.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(n){return"សូមលុបចេញ "+(n.input.length-n.maximum)+" អក្សរ"},inputTooShort:function(n){return"សូមបញ្ចូល"+(n.minimum-n.input.length)+" អក្សរ រឺ ច្រើនជាងនេះ"},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(n){return"អ្នកអាចជ្រើសរើសបានតែ "+n.maximum+" ជម្រើសប៉ុណ្ណោះ"},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ko.js b/assets/3rd/select2/js/i18n/ko.js new file mode 100755 index 00000000..9f38391f --- /dev/null +++ b/assets/3rd/select2/js/i18n/ko.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(n){return"너무 깁니다. "+(n.input.length-n.maximum)+" 글자 지워주세요."},inputTooShort:function(n){return"너무 짧습니다. "+(n.minimum-n.input.length)+" 글자 더 입력해주세요."},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(n){return"최대 "+n.maximum+"개까지만 선택 가능합니다."},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/lt.js b/assets/3rd/select2/js/i18n/lt.js new file mode 100755 index 00000000..38491f25 --- /dev/null +++ b/assets/3rd/select2/js/i18n/lt.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/lt",[],function(){function n(n,e,i,t){return n%10==1&&(n%100<11||n%100>19)?e:n%10>=2&&n%10<=9&&(n%100<11||n%100>19)?i:t}return{inputTooLong:function(e){var i=e.input.length-e.maximum,t="Pašalinkite "+i+" simbol";return t+=n(i,"į","ius","ių")},inputTooShort:function(e){var i=e.minimum-e.input.length,t="Įrašykite dar "+i+" simbol";return t+=n(i,"į","ius","ių")},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(e){var i="Jūs galite pasirinkti tik "+e.maximum+" element";return i+=n(e.maximum,"ą","us","ų")},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/lv.js b/assets/3rd/select2/js/i18n/lv.js new file mode 100755 index 00000000..95fbb4c9 --- /dev/null +++ b/assets/3rd/select2/js/i18n/lv.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/mk.js b/assets/3rd/select2/js/i18n/mk.js new file mode 100755 index 00000000..143f7908 --- /dev/null +++ b/assets/3rd/select2/js/i18n/mk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ms.js b/assets/3rd/select2/js/i18n/ms.js new file mode 100755 index 00000000..ce346d80 --- /dev/null +++ b/assets/3rd/select2/js/i18n/ms.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/nb.js b/assets/3rd/select2/js/i18n/nb.js new file mode 100755 index 00000000..eb89efdb --- /dev/null +++ b/assets/3rd/select2/js/i18n/nb.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){return"Vennligst fjern "+(e.input.length-e.maximum)+" tegn"},inputTooShort:function(e){return"Vennligst skriv inn "+(e.minimum-e.input.length)+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ne.js b/assets/3rd/select2/js/i18n/ne.js new file mode 100755 index 00000000..4867b586 --- /dev/null +++ b/assets/3rd/select2/js/i18n/ne.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="कृपया "+e+" अक्षर मेटाउनुहोस्।";return 1!=e&&(u+="कृपया "+e+" अक्षरहरु मेटाउनुहोस्।"),u},inputTooShort:function(n){return"कृपया बाँकी रहेका "+(n.minimum-n.input.length)+" वा अरु धेरै अक्षरहरु भर्नुहोस्।"},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(n){var e="तँपाई "+n.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return 1!=n.maximum&&(e="तँपाई "+n.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),e},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/nl.js b/assets/3rd/select2/js/i18n/nl.js new file mode 100755 index 00000000..b3ff265a --- /dev/null +++ b/assets/3rd/select2/js/i18n/nl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){return"Gelieve "+(e.input.length-e.maximum)+" karakters te verwijderen"},inputTooShort:function(e){return"Gelieve "+(e.minimum-e.input.length)+" of meer karakters in te voeren"},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var n=1==e.maximum?"kan":"kunnen",r="Er "+n+" maar "+e.maximum+" item";return 1!=e.maximum&&(r+="s"),r+=" worden geselecteerd"},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/pl.js b/assets/3rd/select2/js/i18n/pl.js new file mode 100755 index 00000000..2008e2e1 --- /dev/null +++ b/assets/3rd/select2/js/i18n/pl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/pl",[],function(){var n=["znak","znaki","znaków"],e=["element","elementy","elementów"],r=function(n,e){return 1===n?e[0]:n>1&&n<=4?e[1]:n>=5?e[2]:void 0};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Usuń "+t+" "+r(t,n)},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Podaj przynajmniej "+t+" "+r(t,n)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(n){return"Możesz zaznaczyć tylko "+n.maximum+" "+r(n.maximum,e)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ps.js b/assets/3rd/select2/js/i18n/ps.js new file mode 100755 index 00000000..9bc16ec6 --- /dev/null +++ b/assets/3rd/select2/js/i18n/ps.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/pt-BR.js b/assets/3rd/select2/js/i18n/pt-BR.js new file mode 100755 index 00000000..c64c7aa4 --- /dev/null +++ b/assets/3rd/select2/js/i18n/pt-BR.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/pt.js b/assets/3rd/select2/js/i18n/pt.js new file mode 100755 index 00000000..6ca5e6b1 --- /dev/null +++ b/assets/3rd/select2/js/i18n/pt.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ro.js b/assets/3rd/select2/js/i18n/ro.js new file mode 100755 index 00000000..3befe800 --- /dev/null +++ b/assets/3rd/select2/js/i18n/ro.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return 1!==t&&(n+="e"),n},inputTooShort:function(e){return"Vă rugăm să introduceți "+(e.minimum-e.input.length)+" sau mai multe caractere"},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",1!==e.maximum&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/ru.js b/assets/3rd/select2/js/i18n/ru.js new file mode 100755 index 00000000..8102a321 --- /dev/null +++ b/assets/3rd/select2/js/i18n/ru.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ru",[],function(){function n(n,e,r,u){return n%10<5&&n%10>0&&n%100<5||n%100>20?n%10>1?r:e:u}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Пожалуйста, введите на "+r+" символ";return u+=n(r,"","a","ов"),u+=" меньше"},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Пожалуйста, введите ещё хотя бы "+r+" символ";return u+=n(r,"","a","ов")},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(e){var r="Вы можете выбрать не более "+e.maximum+" элемент";return r+=n(e.maximum,"","a","ов")},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/sk.js b/assets/3rd/select2/js/i18n/sk.js new file mode 100755 index 00000000..19465bc7 --- /dev/null +++ b/assets/3rd/select2/js/i18n/sk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadajte o jeden znak menej":t>=2&&t<=4?"Prosím, zadajte o "+e[t](!0)+" znaky menej":"Prosím, zadajte o "+t+" znakov menej"},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadajte ešte jeden znak":t<=4?"Prosím, zadajte ešte ďalšie "+e[t](!0)+" znaky":"Prosím, zadajte ešte ďalších "+t+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(n){return 1==n.maximum?"Môžete zvoliť len jednu položku":n.maximum>=2&&n.maximum<=4?"Môžete zvoliť najviac "+e[n.maximum](!1)+" položky":"Môžete zvoliť najviac "+n.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/sl.js b/assets/3rd/select2/js/i18n/sl.js new file mode 100755 index 00000000..06c291e5 --- /dev/null +++ b/assets/3rd/select2/js/i18n/sl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Prosim zbrišite "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Prosim vpišite še "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var n="Označite lahko največ "+e.maximum+" predmet";return 2==e.maximum?n+="a":1!=e.maximum&&(n+="e"),n},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/sq.js b/assets/3rd/select2/js/i18n/sq.js new file mode 100755 index 00000000..f4cc7932 --- /dev/null +++ b/assets/3rd/select2/js/i18n/sq.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/sr-Cyrl.js b/assets/3rd/select2/js/i18n/sr-Cyrl.js new file mode 100755 index 00000000..124a5b20 --- /dev/null +++ b/assets/3rd/select2/js/i18n/sr-Cyrl.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr-Cyrl",[],function(){function n(n,e,r,u){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:u}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Обришите "+r+" симбол";return u+=n(r,"","а","а")},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Укуцајте бар још "+r+" симбол";return u+=n(r,"","а","а")},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(e){var r="Можете изабрати само "+e.maximum+" ставк";return r+=n(e.maximum,"у","е","и")},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/sr.js b/assets/3rd/select2/js/i18n/sr.js new file mode 100755 index 00000000..b078face --- /dev/null +++ b/assets/3rd/select2/js/i18n/sr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr",[],function(){function n(n,e,r,t){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(e){var r=e.input.length-e.maximum,t="Obrišite "+r+" simbol";return t+=n(r,"","a","a")},inputTooShort:function(e){var r=e.minimum-e.input.length,t="Ukucajte bar još "+r+" simbol";return t+=n(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(e){var r="Možete izabrati samo "+e.maximum+" stavk";return r+=n(e.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/sv.js b/assets/3rd/select2/js/i18n/sv.js new file mode 100755 index 00000000..3995f65b --- /dev/null +++ b/assets/3rd/select2/js/i18n/sv.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(n){return"Vänligen sudda ut "+(n.input.length-n.maximum)+" tecken"},inputTooShort:function(n){return"Vänligen skriv in "+(n.minimum-n.input.length)+" eller fler tecken"},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(n){return"Du kan max välja "+n.maximum+" element"},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"},removeAllItems:function(){return"Ta bort alla objekt"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/th.js b/assets/3rd/select2/js/i18n/th.js new file mode 100755 index 00000000..2367bfe7 --- /dev/null +++ b/assets/3rd/select2/js/i18n/th.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(n){return"โปรดลบออก "+(n.input.length-n.maximum)+" ตัวอักษร"},inputTooShort:function(n){return"โปรดพิมพ์เพิ่มอีก "+(n.minimum-n.input.length)+" ตัวอักษร"},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(n){return"คุณสามารถเลือกได้ไม่เกิน "+n.maximum+" รายการ"},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"},removeAllItems:function(){return"ลบรายการทั้งหมด"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/tk.js b/assets/3rd/select2/js/i18n/tk.js new file mode 100755 index 00000000..b5a90334 --- /dev/null +++ b/assets/3rd/select2/js/i18n/tk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/tk",[],function(){return{errorLoading:function(){return"Netije ýüklenmedi."},inputTooLong:function(e){return e.input.length-e.maximum+" harp bozuň."},inputTooShort:function(e){return"Ýene-de iň az "+(e.minimum-e.input.length)+" harp ýazyň."},loadingMore:function(){return"Köpräk netije görkezilýär…"},maximumSelected:function(e){return"Diňe "+e.maximum+" sanysyny saýlaň."},noResults:function(){return"Netije tapylmady."},searching:function(){return"Gözlenýär…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/tr.js b/assets/3rd/select2/js/i18n/tr.js new file mode 100755 index 00000000..b02b3728 --- /dev/null +++ b/assets/3rd/select2/js/i18n/tr.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(n){return n.input.length-n.maximum+" karakter daha girmelisiniz"},inputTooShort:function(n){return"En az "+(n.minimum-n.input.length)+" karakter daha girmelisiniz"},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(n){return"Sadece "+n.maximum+" seçim yapabilirsiniz"},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"},removeAllItems:function(){return"Tüm öğeleri kaldır"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/uk.js b/assets/3rd/select2/js/i18n/uk.js new file mode 100755 index 00000000..40b46b47 --- /dev/null +++ b/assets/3rd/select2/js/i18n/uk.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/uk",[],function(){function n(n,e,u,r){return n%100>10&&n%100<15?r:n%10==1?e:n%10>1&&n%10<5?u:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(e){return"Будь ласка, видаліть "+(e.input.length-e.maximum)+" "+n(e.maximum,"літеру","літери","літер")},inputTooShort:function(n){return"Будь ласка, введіть "+(n.minimum-n.input.length)+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(e){return"Ви можете вибрати лише "+e.maximum+" "+n(e.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"},removeAllItems:function(){return"Видалити всі елементи"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/vi.js b/assets/3rd/select2/js/i18n/vi.js new file mode 100755 index 00000000..cc58c15e --- /dev/null +++ b/assets/3rd/select2/js/i18n/vi.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/vi",[],function(){return{inputTooLong:function(n){return"Vui lòng xóa bớt "+(n.input.length-n.maximum)+" ký tự"},inputTooShort:function(n){return"Vui lòng nhập thêm từ "+(n.minimum-n.input.length)+" ký tự trở lên"},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(n){return"Chỉ có thể chọn được "+n.maximum+" lựa chọn"},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"},removeAllItems:function(){return"Xóa tất cả các mục"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/zh-CN.js b/assets/3rd/select2/js/i18n/zh-CN.js new file mode 100755 index 00000000..3acd4cdb --- /dev/null +++ b/assets/3rd/select2/js/i18n/zh-CN.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(n){return"请删除"+(n.input.length-n.maximum)+"个字符"},inputTooShort:function(n){return"请再输入至少"+(n.minimum-n.input.length)+"个字符"},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(n){return"最多只能选择"+n.maximum+"个项目"},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/i18n/zh-TW.js b/assets/3rd/select2/js/i18n/zh-TW.js new file mode 100755 index 00000000..cb43386b --- /dev/null +++ b/assets/3rd/select2/js/i18n/zh-TW.js @@ -0,0 +1,3 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ + +!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(n){return"請刪掉"+(n.input.length-n.maximum)+"個字元"},inputTooShort:function(n){return"請再輸入"+(n.minimum-n.input.length)+"個字元"},loadingMore:function(){return"載入中…"},maximumSelected:function(n){return"你只能選擇最多"+n.maximum+"項"},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"},removeAllItems:function(){return"刪除所有項目"}}}),n.define,n.require}(); \ No newline at end of file diff --git a/assets/3rd/select2/js/select2.full.js b/assets/3rd/select2/js/select2.full.js new file mode 100755 index 00000000..f3a20b9f --- /dev/null +++ b/assets/3rd/select2/js/select2.full.js @@ -0,0 +1,6597 @@ +/*! + * Select2 4.0.7 + * https://select2.github.io + * + * Released under the MIT license + * https://github.com/select2/select2/blob/master/LICENSE.md + */ +;(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = function (root, jQuery) { + if (jQuery === undefined) { + // require('jQuery') returns a factory that requires window to + // build a jQuery instance, we normalize how we use modules + // that require this pattern but the window provided is a noop + // if it's defined (how jquery works) + if (typeof window !== 'undefined') { + jQuery = require('jquery'); + } + else { + jQuery = require('jquery')(root); + } + } + factory(jQuery); + return jQuery; + }; + } else { + // Browser globals + factory(jQuery); + } +} (function (jQuery) { + // This is needed so we can catch the AMD loader configuration and use it + // The inner file should be wrapped (by `banner.start.js`) in a function that + // returns the AMD loader references. + var S2 =(function () { + // Restore the Select2 AMD loader so it can be used + // Needed mostly in the language files, where the loader is not inserted + if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) { + var S2 = jQuery.fn.select2.amd; + } +var S2;(function () { if (!S2 || !S2.requirejs) { +if (!S2) { S2 = {}; } else { require = S2; } +/** + * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. + * Released under MIT license, http://github.com/requirejs/almond/LICENSE + */ +//Going sloppy to avoid 'use strict' string cost, but strict practices should +//be followed. +/*global setTimeout: false */ + +var requirejs, require, define; +(function (undef) { + var main, req, makeMap, handlers, + defined = {}, + waiting = {}, + config = {}, + defining = {}, + hasOwn = Object.prototype.hasOwnProperty, + aps = [].slice, + jsSuffixRegExp = /\.js$/; + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @returns {String} normalized name + */ + function normalize(name, baseName) { + var nameParts, nameSegment, mapValue, foundMap, lastIndex, + foundI, foundStarMap, starI, i, j, part, normalizedBaseParts, + baseParts = baseName && baseName.split("/"), + map = config.map, + starMap = (map && map['*']) || {}; + + //Adjust any relative paths. + if (name) { + name = name.split('/'); + lastIndex = name.length - 1; + + // If wanting node ID compatibility, strip .js from end + // of IDs. Have to do this here, and not in nameToUrl + // because node allows either .js or non .js to map + // to same file. + if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { + name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); + } + + // Starts with a '.' so need the baseName + if (name[0].charAt(0) === '.' && baseParts) { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + name = normalizedBaseParts.concat(name); + } + + //start trimDots + for (i = 0; i < name.length; i++) { + part = name[i]; + if (part === '.') { + name.splice(i, 1); + i -= 1; + } else if (part === '..') { + // If at the start, or previous value is still .., + // keep them so that when converted to a path it may + // still work when converted to a path, even though + // as an ID it is less than ideal. In larger point + // releases, may be better to just kick out an error. + if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') { + continue; + } else if (i > 0) { + name.splice(i - 1, 2); + i -= 2; + } + } + } + //end trimDots + + name = name.join('/'); + } + + //Apply map config if available. + if ((baseParts || starMap) && map) { + nameParts = name.split('/'); + + for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join("/"); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = map[baseParts.slice(0, j).join('/')]; + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = mapValue[nameSegment]; + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break; + } + } + } + } + + if (foundMap) { + break; + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && starMap[nameSegment]) { + foundStarMap = starMap[nameSegment]; + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + return name; + } + + function makeRequire(relName, forceSync) { + return function () { + //A version of a require function that passes a moduleName + //value for items that may need to + //look up paths relative to the moduleName + var args = aps.call(arguments, 0); + + //If first arg is not require('string'), and there is only + //one arg, it is the array form without a callback. Insert + //a null so that the following concat is correct. + if (typeof args[0] !== 'string' && args.length === 1) { + args.push(null); + } + return req.apply(undef, args.concat([relName, forceSync])); + }; + } + + function makeNormalize(relName) { + return function (name) { + return normalize(name, relName); + }; + } + + function makeLoad(depName) { + return function (value) { + defined[depName] = value; + }; + } + + function callDep(name) { + if (hasProp(waiting, name)) { + var args = waiting[name]; + delete waiting[name]; + defining[name] = true; + main.apply(undef, args); + } + + if (!hasProp(defined, name) && !hasProp(defining, name)) { + throw new Error('No ' + name); + } + return defined[name]; + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + //Creates a parts array for a relName where first part is plugin ID, + //second part is resource ID. Assumes relName has already been normalized. + function makeRelParts(relName) { + return relName ? splitPrefix(relName) : []; + } + + /** + * Makes a name map, normalizing the name, and using a plugin + * for normalization if necessary. Grabs a ref to plugin + * too, as an optimization. + */ + makeMap = function (name, relParts) { + var plugin, + parts = splitPrefix(name), + prefix = parts[0], + relResourceName = relParts[1]; + + name = parts[1]; + + if (prefix) { + prefix = normalize(prefix, relResourceName); + plugin = callDep(prefix); + } + + //Normalize according + if (prefix) { + if (plugin && plugin.normalize) { + name = plugin.normalize(name, makeNormalize(relResourceName)); + } else { + name = normalize(name, relResourceName); + } + } else { + name = normalize(name, relResourceName); + parts = splitPrefix(name); + prefix = parts[0]; + name = parts[1]; + if (prefix) { + plugin = callDep(prefix); + } + } + + //Using ridiculous property names for space reasons + return { + f: prefix ? prefix + '!' + name : name, //fullName + n: name, + pr: prefix, + p: plugin + }; + }; + + function makeConfig(name) { + return function () { + return (config && config.config && config.config[name]) || {}; + }; + } + + handlers = { + require: function (name) { + return makeRequire(name); + }, + exports: function (name) { + var e = defined[name]; + if (typeof e !== 'undefined') { + return e; + } else { + return (defined[name] = {}); + } + }, + module: function (name) { + return { + id: name, + uri: '', + exports: defined[name], + config: makeConfig(name) + }; + } + }; + + main = function (name, deps, callback, relName) { + var cjsModule, depName, ret, map, i, relParts, + args = [], + callbackType = typeof callback, + usingExports; + + //Use name if no relName + relName = relName || name; + relParts = makeRelParts(relName); + + //Call the callback to define the module, if necessary. + if (callbackType === 'undefined' || callbackType === 'function') { + //Pull out the defined dependencies and pass the ordered + //values to the callback. + //Default to [require, exports, module] if no deps + deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; + for (i = 0; i < deps.length; i += 1) { + map = makeMap(deps[i], relParts); + depName = map.f; + + //Fast path CommonJS standard dependencies. + if (depName === "require") { + args[i] = handlers.require(name); + } else if (depName === "exports") { + //CommonJS module spec 1.1 + args[i] = handlers.exports(name); + usingExports = true; + } else if (depName === "module") { + //CommonJS module spec 1.1 + cjsModule = args[i] = handlers.module(name); + } else if (hasProp(defined, depName) || + hasProp(waiting, depName) || + hasProp(defining, depName)) { + args[i] = callDep(depName); + } else if (map.p) { + map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); + args[i] = defined[depName]; + } else { + throw new Error(name + ' missing ' + depName); + } + } + + ret = callback ? callback.apply(defined[name], args) : undefined; + + if (name) { + //If setting exports via "module" is in play, + //favor that over return value and exports. After that, + //favor a non-undefined return value over exports use. + if (cjsModule && cjsModule.exports !== undef && + cjsModule.exports !== defined[name]) { + defined[name] = cjsModule.exports; + } else if (ret !== undef || !usingExports) { + //Use the return value from the function. + defined[name] = ret; + } + } + } else if (name) { + //May just be an object definition for the module. Only + //worry about defining if have a module name. + defined[name] = callback; + } + }; + + requirejs = require = req = function (deps, callback, relName, forceSync, alt) { + if (typeof deps === "string") { + if (handlers[deps]) { + //callback in this case is really relName + return handlers[deps](callback); + } + //Just return the module wanted. In this scenario, the + //deps arg is the module name, and second arg (if passed) + //is just the relName. + //Normalize module name, if it contains . or .. + return callDep(makeMap(deps, makeRelParts(callback)).f); + } else if (!deps.splice) { + //deps is a config object, not an array. + config = deps; + if (config.deps) { + req(config.deps, config.callback); + } + if (!callback) { + return; + } + + if (callback.splice) { + //callback is an array, which means it is a dependency list. + //Adjust args if there are dependencies + deps = callback; + callback = relName; + relName = null; + } else { + deps = undef; + } + } + + //Support require(['a']) + callback = callback || function () {}; + + //If relName is a function, it is an errback handler, + //so remove it. + if (typeof relName === 'function') { + relName = forceSync; + forceSync = alt; + } + + //Simulate async callback; + if (forceSync) { + main(undef, deps, callback, relName); + } else { + //Using a non-zero value because of concern for what old browsers + //do, and latest browsers "upgrade" to 4 if lower value is used: + //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: + //If want a value immediately, use require('id') instead -- something + //that works in almond on the global level, but not guaranteed and + //unlikely to work in other AMD implementations. + setTimeout(function () { + main(undef, deps, callback, relName); + }, 4); + } + + return req; + }; + + /** + * Just drops the config on the floor, but returns req in case + * the config return value is used. + */ + req.config = function (cfg) { + return req(cfg); + }; + + /** + * Expose module registry for debugging and tooling + */ + requirejs._defined = defined; + + define = function (name, deps, callback) { + if (typeof name !== 'string') { + throw new Error('See almond README: incorrect module build, no module name'); + } + + //This module may not have dependencies + if (!deps.splice) { + //deps is not an array, so probably means + //an object literal or factory function for + //the value. Adjust args. + callback = deps; + deps = []; + } + + if (!hasProp(defined, name) && !hasProp(waiting, name)) { + waiting[name] = [name, deps, callback]; + } + }; + + define.amd = { + jQuery: true + }; +}()); + +S2.requirejs = requirejs;S2.require = require;S2.define = define; +} +}()); +S2.define("almond", function(){}); + +/* global jQuery:false, $:false */ +S2.define('jquery',[],function () { + var _$ = jQuery || $; + + if (_$ == null && console && console.error) { + console.error( + 'Select2: An instance of jQuery or a jQuery-compatible library was not ' + + 'found. Make sure that you are including jQuery before Select2 on your ' + + 'web page.' + ); + } + + return _$; +}); + +S2.define('select2/utils',[ + 'jquery' +], function ($) { + var Utils = {}; + + Utils.Extend = function (ChildClass, SuperClass) { + var __hasProp = {}.hasOwnProperty; + + function BaseConstructor () { + this.constructor = ChildClass; + } + + for (var key in SuperClass) { + if (__hasProp.call(SuperClass, key)) { + ChildClass[key] = SuperClass[key]; + } + } + + BaseConstructor.prototype = SuperClass.prototype; + ChildClass.prototype = new BaseConstructor(); + ChildClass.__super__ = SuperClass.prototype; + + return ChildClass; + }; + + function getMethods (theClass) { + var proto = theClass.prototype; + + var methods = []; + + for (var methodName in proto) { + var m = proto[methodName]; + + if (typeof m !== 'function') { + continue; + } + + if (methodName === 'constructor') { + continue; + } + + methods.push(methodName); + } + + return methods; + } + + Utils.Decorate = function (SuperClass, DecoratorClass) { + var decoratedMethods = getMethods(DecoratorClass); + var superMethods = getMethods(SuperClass); + + function DecoratedClass () { + var unshift = Array.prototype.unshift; + + var argCount = DecoratorClass.prototype.constructor.length; + + var calledConstructor = SuperClass.prototype.constructor; + + if (argCount > 0) { + unshift.call(arguments, SuperClass.prototype.constructor); + + calledConstructor = DecoratorClass.prototype.constructor; + } + + calledConstructor.apply(this, arguments); + } + + DecoratorClass.displayName = SuperClass.displayName; + + function ctr () { + this.constructor = DecoratedClass; + } + + DecoratedClass.prototype = new ctr(); + + for (var m = 0; m < superMethods.length; m++) { + var superMethod = superMethods[m]; + + DecoratedClass.prototype[superMethod] = + SuperClass.prototype[superMethod]; + } + + var calledMethod = function (methodName) { + // Stub out the original method if it's not decorating an actual method + var originalMethod = function () {}; + + if (methodName in DecoratedClass.prototype) { + originalMethod = DecoratedClass.prototype[methodName]; + } + + var decoratedMethod = DecoratorClass.prototype[methodName]; + + return function () { + var unshift = Array.prototype.unshift; + + unshift.call(arguments, originalMethod); + + return decoratedMethod.apply(this, arguments); + }; + }; + + for (var d = 0; d < decoratedMethods.length; d++) { + var decoratedMethod = decoratedMethods[d]; + + DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod); + } + + return DecoratedClass; + }; + + var Observable = function () { + this.listeners = {}; + }; + + Observable.prototype.on = function (event, callback) { + this.listeners = this.listeners || {}; + + if (event in this.listeners) { + this.listeners[event].push(callback); + } else { + this.listeners[event] = [callback]; + } + }; + + Observable.prototype.trigger = function (event) { + var slice = Array.prototype.slice; + var params = slice.call(arguments, 1); + + this.listeners = this.listeners || {}; + + // Params should always come in as an array + if (params == null) { + params = []; + } + + // If there are no arguments to the event, use a temporary object + if (params.length === 0) { + params.push({}); + } + + // Set the `_type` of the first object to the event + params[0]._type = event; + + if (event in this.listeners) { + this.invoke(this.listeners[event], slice.call(arguments, 1)); + } + + if ('*' in this.listeners) { + this.invoke(this.listeners['*'], arguments); + } + }; + + Observable.prototype.invoke = function (listeners, params) { + for (var i = 0, len = listeners.length; i < len; i++) { + listeners[i].apply(this, params); + } + }; + + Utils.Observable = Observable; + + Utils.generateChars = function (length) { + var chars = ''; + + for (var i = 0; i < length; i++) { + var randomChar = Math.floor(Math.random() * 36); + chars += randomChar.toString(36); + } + + return chars; + }; + + Utils.bind = function (func, context) { + return function () { + func.apply(context, arguments); + }; + }; + + Utils._convertData = function (data) { + for (var originalKey in data) { + var keys = originalKey.split('-'); + + var dataLevel = data; + + if (keys.length === 1) { + continue; + } + + for (var k = 0; k < keys.length; k++) { + var key = keys[k]; + + // Lowercase the first letter + // By default, dash-separated becomes camelCase + key = key.substring(0, 1).toLowerCase() + key.substring(1); + + if (!(key in dataLevel)) { + dataLevel[key] = {}; + } + + if (k == keys.length - 1) { + dataLevel[key] = data[originalKey]; + } + + dataLevel = dataLevel[key]; + } + + delete data[originalKey]; + } + + return data; + }; + + Utils.hasScroll = function (index, el) { + // Adapted from the function created by @ShadowScripter + // and adapted by @BillBarry on the Stack Exchange Code Review website. + // The original code can be found at + // http://codereview.stackexchange.com/q/13338 + // and was designed to be used with the Sizzle selector engine. + + var $el = $(el); + var overflowX = el.style.overflowX; + var overflowY = el.style.overflowY; + + //Check both x and y declarations + if (overflowX === overflowY && + (overflowY === 'hidden' || overflowY === 'visible')) { + return false; + } + + if (overflowX === 'scroll' || overflowY === 'scroll') { + return true; + } + + return ($el.innerHeight() < el.scrollHeight || + $el.innerWidth() < el.scrollWidth); + }; + + Utils.escapeMarkup = function (markup) { + var replaceMap = { + '\\': '\', + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''', + '/': '/' + }; + + // Do not try to escape the markup if it's not a string + if (typeof markup !== 'string') { + return markup; + } + + return String(markup).replace(/[&<>"'\/\\]/g, function (match) { + return replaceMap[match]; + }); + }; + + // Append an array of jQuery nodes to a given element. + Utils.appendMany = function ($element, $nodes) { + // jQuery 1.7.x does not support $.fn.append() with an array + // Fall back to a jQuery object collection using $.fn.add() + if ($.fn.jquery.substr(0, 3) === '1.7') { + var $jqNodes = $(); + + $.map($nodes, function (node) { + $jqNodes = $jqNodes.add(node); + }); + + $nodes = $jqNodes; + } + + $element.append($nodes); + }; + + // Cache objects in Utils.__cache instead of $.data (see #4346) + Utils.__cache = {}; + + var id = 0; + Utils.GetUniqueElementId = function (element) { + // Get a unique element Id. If element has no id, + // creates a new unique number, stores it in the id + // attribute and returns the new id. + // If an id already exists, it simply returns it. + + var select2Id = element.getAttribute('data-select2-id'); + if (select2Id == null) { + // If element has id, use it. + if (element.id) { + select2Id = element.id; + element.setAttribute('data-select2-id', select2Id); + } else { + element.setAttribute('data-select2-id', ++id); + select2Id = id.toString(); + } + } + return select2Id; + }; + + Utils.StoreData = function (element, name, value) { + // Stores an item in the cache for a specified element. + // name is the cache key. + var id = Utils.GetUniqueElementId(element); + if (!Utils.__cache[id]) { + Utils.__cache[id] = {}; + } + + Utils.__cache[id][name] = value; + }; + + Utils.GetData = function (element, name) { + // Retrieves a value from the cache by its key (name) + // name is optional. If no name specified, return + // all cache items for the specified element. + // and for a specified element. + var id = Utils.GetUniqueElementId(element); + if (name) { + if (Utils.__cache[id]) { + if (Utils.__cache[id][name] != null) { + return Utils.__cache[id][name]; + } + return $(element).data(name); // Fallback to HTML5 data attribs. + } + return $(element).data(name); // Fallback to HTML5 data attribs. + } else { + return Utils.__cache[id]; + } + }; + + Utils.RemoveData = function (element) { + // Removes all cached items for a specified element. + var id = Utils.GetUniqueElementId(element); + if (Utils.__cache[id] != null) { + delete Utils.__cache[id]; + } + }; + + return Utils; +}); + +S2.define('select2/results',[ + 'jquery', + './utils' +], function ($, Utils) { + function Results ($element, options, dataAdapter) { + this.$element = $element; + this.data = dataAdapter; + this.options = options; + + Results.__super__.constructor.call(this); + } + + Utils.Extend(Results, Utils.Observable); + + Results.prototype.render = function () { + var $results = $( + '
    ' + ); + + if (this.options.get('multiple')) { + $results.attr('aria-multiselectable', 'true'); + } + + this.$results = $results; + + return $results; + }; + + Results.prototype.clear = function () { + this.$results.empty(); + }; + + Results.prototype.displayMessage = function (params) { + var escapeMarkup = this.options.get('escapeMarkup'); + + this.clear(); + this.hideLoading(); + + var $message = $( + '
  • ' + ); + + var message = this.options.get('translations').get(params.message); + + $message.append( + escapeMarkup( + message(params.args) + ) + ); + + $message[0].className += ' select2-results__message'; + + this.$results.append($message); + }; + + Results.prototype.hideMessages = function () { + this.$results.find('.select2-results__message').remove(); + }; + + Results.prototype.append = function (data) { + this.hideLoading(); + + var $options = []; + + if (data.results == null || data.results.length === 0) { + if (this.$results.children().length === 0) { + this.trigger('results:message', { + message: 'noResults' + }); + } + + return; + } + + data.results = this.sort(data.results); + + for (var d = 0; d < data.results.length; d++) { + var item = data.results[d]; + + var $option = this.option(item); + + $options.push($option); + } + + this.$results.append($options); + }; + + Results.prototype.position = function ($results, $dropdown) { + var $resultsContainer = $dropdown.find('.select2-results'); + $resultsContainer.append($results); + }; + + Results.prototype.sort = function (data) { + var sorter = this.options.get('sorter'); + + return sorter(data); + }; + + Results.prototype.highlightFirstItem = function () { + var $options = this.$results + .find('.select2-results__option[aria-selected]'); + + var $selected = $options.filter('[aria-selected=true]'); + + // Check if there are any selected options + if ($selected.length > 0) { + // If there are selected options, highlight the first + $selected.first().trigger('mouseenter'); + } else { + // If there are no selected options, highlight the first option + // in the dropdown + $options.first().trigger('mouseenter'); + } + + this.ensureHighlightVisible(); + }; + + Results.prototype.setClasses = function () { + var self = this; + + this.data.current(function (selected) { + var selectedIds = $.map(selected, function (s) { + return s.id.toString(); + }); + + var $options = self.$results + .find('.select2-results__option[aria-selected]'); + + $options.each(function () { + var $option = $(this); + + var item = Utils.GetData(this, 'data'); + + // id needs to be converted to a string when comparing + var id = '' + item.id; + + if ((item.element != null && item.element.selected) || + (item.element == null && $.inArray(id, selectedIds) > -1)) { + $option.attr('aria-selected', 'true'); + } else { + $option.attr('aria-selected', 'false'); + } + }); + + }); + }; + + Results.prototype.showLoading = function (params) { + this.hideLoading(); + + var loadingMore = this.options.get('translations').get('searching'); + + var loading = { + disabled: true, + loading: true, + text: loadingMore(params) + }; + var $loading = this.option(loading); + $loading.className += ' loading-results'; + + this.$results.prepend($loading); + }; + + Results.prototype.hideLoading = function () { + this.$results.find('.loading-results').remove(); + }; + + Results.prototype.option = function (data) { + var option = document.createElement('li'); + option.className = 'select2-results__option'; + + var attrs = { + 'role': 'treeitem', + 'aria-selected': 'false' + }; + + if (data.disabled) { + delete attrs['aria-selected']; + attrs['aria-disabled'] = 'true'; + } + + if (data.id == null) { + delete attrs['aria-selected']; + } + + if (data._resultId != null) { + option.id = data._resultId; + } + + if (data.title) { + option.title = data.title; + } + + if (data.children) { + attrs.role = 'group'; + attrs['aria-label'] = data.text; + delete attrs['aria-selected']; + } + + for (var attr in attrs) { + var val = attrs[attr]; + + option.setAttribute(attr, val); + } + + if (data.children) { + var $option = $(option); + + var label = document.createElement('strong'); + label.className = 'select2-results__group'; + + var $label = $(label); + this.template(data, label); + + var $children = []; + + for (var c = 0; c < data.children.length; c++) { + var child = data.children[c]; + + var $child = this.option(child); + + $children.push($child); + } + + var $childrenContainer = $('
      ', { + 'class': 'select2-results__options select2-results__options--nested' + }); + + $childrenContainer.append($children); + + $option.append(label); + $option.append($childrenContainer); + } else { + this.template(data, option); + } + + Utils.StoreData(option, 'data', data); + + return option; + }; + + Results.prototype.bind = function (container, $container) { + var self = this; + + var id = container.id + '-results'; + + this.$results.attr('id', id); + + container.on('results:all', function (params) { + self.clear(); + self.append(params.data); + + if (container.isOpen()) { + self.setClasses(); + self.highlightFirstItem(); + } + }); + + container.on('results:append', function (params) { + self.append(params.data); + + if (container.isOpen()) { + self.setClasses(); + } + }); + + container.on('query', function (params) { + self.hideMessages(); + self.showLoading(params); + }); + + container.on('select', function () { + if (!container.isOpen()) { + return; + } + + self.setClasses(); + + if (self.options.get('scrollAfterSelect')) { + self.highlightFirstItem(); + } + }); + + container.on('unselect', function () { + if (!container.isOpen()) { + return; + } + + self.setClasses(); + + if (self.options.get('scrollAfterSelect')) { + self.highlightFirstItem(); + } + }); + + container.on('open', function () { + // When the dropdown is open, aria-expended="true" + self.$results.attr('aria-expanded', 'true'); + self.$results.attr('aria-hidden', 'false'); + + self.setClasses(); + self.ensureHighlightVisible(); + }); + + container.on('close', function () { + // When the dropdown is closed, aria-expended="false" + self.$results.attr('aria-expanded', 'false'); + self.$results.attr('aria-hidden', 'true'); + self.$results.removeAttr('aria-activedescendant'); + }); + + container.on('results:toggle', function () { + var $highlighted = self.getHighlightedResults(); + + if ($highlighted.length === 0) { + return; + } + + $highlighted.trigger('mouseup'); + }); + + container.on('results:select', function () { + var $highlighted = self.getHighlightedResults(); + + if ($highlighted.length === 0) { + return; + } + + var data = Utils.GetData($highlighted[0], 'data'); + + if ($highlighted.attr('aria-selected') == 'true') { + self.trigger('close', {}); + } else { + self.trigger('select', { + data: data + }); + } + }); + + container.on('results:previous', function () { + var $highlighted = self.getHighlightedResults(); + + var $options = self.$results.find('[aria-selected]'); + + var currentIndex = $options.index($highlighted); + + // If we are already at the top, don't move further + // If no options, currentIndex will be -1 + if (currentIndex <= 0) { + return; + } + + var nextIndex = currentIndex - 1; + + // If none are highlighted, highlight the first + if ($highlighted.length === 0) { + nextIndex = 0; + } + + var $next = $options.eq(nextIndex); + + $next.trigger('mouseenter'); + + var currentOffset = self.$results.offset().top; + var nextTop = $next.offset().top; + var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset); + + if (nextIndex === 0) { + self.$results.scrollTop(0); + } else if (nextTop - currentOffset < 0) { + self.$results.scrollTop(nextOffset); + } + }); + + container.on('results:next', function () { + var $highlighted = self.getHighlightedResults(); + + var $options = self.$results.find('[aria-selected]'); + + var currentIndex = $options.index($highlighted); + + var nextIndex = currentIndex + 1; + + // If we are at the last option, stay there + if (nextIndex >= $options.length) { + return; + } + + var $next = $options.eq(nextIndex); + + $next.trigger('mouseenter'); + + var currentOffset = self.$results.offset().top + + self.$results.outerHeight(false); + var nextBottom = $next.offset().top + $next.outerHeight(false); + var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset; + + if (nextIndex === 0) { + self.$results.scrollTop(0); + } else if (nextBottom > currentOffset) { + self.$results.scrollTop(nextOffset); + } + }); + + container.on('results:focus', function (params) { + params.element.addClass('select2-results__option--highlighted'); + }); + + container.on('results:message', function (params) { + self.displayMessage(params); + }); + + if ($.fn.mousewheel) { + this.$results.on('mousewheel', function (e) { + var top = self.$results.scrollTop(); + + var bottom = self.$results.get(0).scrollHeight - top + e.deltaY; + + var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0; + var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height(); + + if (isAtTop) { + self.$results.scrollTop(0); + + e.preventDefault(); + e.stopPropagation(); + } else if (isAtBottom) { + self.$results.scrollTop( + self.$results.get(0).scrollHeight - self.$results.height() + ); + + e.preventDefault(); + e.stopPropagation(); + } + }); + } + + this.$results.on('mouseup', '.select2-results__option[aria-selected]', + function (evt) { + var $this = $(this); + + var data = Utils.GetData(this, 'data'); + + if ($this.attr('aria-selected') === 'true') { + if (self.options.get('multiple')) { + self.trigger('unselect', { + originalEvent: evt, + data: data + }); + } else { + self.trigger('close', {}); + } + + return; + } + + self.trigger('select', { + originalEvent: evt, + data: data + }); + }); + + this.$results.on('mouseenter', '.select2-results__option[aria-selected]', + function (evt) { + var data = Utils.GetData(this, 'data'); + + self.getHighlightedResults() + .removeClass('select2-results__option--highlighted'); + + self.trigger('results:focus', { + data: data, + element: $(this) + }); + }); + }; + + Results.prototype.getHighlightedResults = function () { + var $highlighted = this.$results + .find('.select2-results__option--highlighted'); + + return $highlighted; + }; + + Results.prototype.destroy = function () { + this.$results.remove(); + }; + + Results.prototype.ensureHighlightVisible = function () { + var $highlighted = this.getHighlightedResults(); + + if ($highlighted.length === 0) { + return; + } + + var $options = this.$results.find('[aria-selected]'); + + var currentIndex = $options.index($highlighted); + + var currentOffset = this.$results.offset().top; + var nextTop = $highlighted.offset().top; + var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset); + + var offsetDelta = nextTop - currentOffset; + nextOffset -= $highlighted.outerHeight(false) * 2; + + if (currentIndex <= 2) { + this.$results.scrollTop(0); + } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) { + this.$results.scrollTop(nextOffset); + } + }; + + Results.prototype.template = function (result, container) { + var template = this.options.get('templateResult'); + var escapeMarkup = this.options.get('escapeMarkup'); + + var content = template(result, container); + + if (content == null) { + container.style.display = 'none'; + } else if (typeof content === 'string') { + container.innerHTML = escapeMarkup(content); + } else { + $(container).append(content); + } + }; + + return Results; +}); + +S2.define('select2/keys',[ + +], function () { + var KEYS = { + BACKSPACE: 8, + TAB: 9, + ENTER: 13, + SHIFT: 16, + CTRL: 17, + ALT: 18, + ESC: 27, + SPACE: 32, + PAGE_UP: 33, + PAGE_DOWN: 34, + END: 35, + HOME: 36, + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + DELETE: 46 + }; + + return KEYS; +}); + +S2.define('select2/selection/base',[ + 'jquery', + '../utils', + '../keys' +], function ($, Utils, KEYS) { + function BaseSelection ($element, options) { + this.$element = $element; + this.options = options; + + BaseSelection.__super__.constructor.call(this); + } + + Utils.Extend(BaseSelection, Utils.Observable); + + BaseSelection.prototype.render = function () { + var $selection = $( + '' + ); + + this._tabindex = 0; + + if (Utils.GetData(this.$element[0], 'old-tabindex') != null) { + this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex'); + } else if (this.$element.attr('tabindex') != null) { + this._tabindex = this.$element.attr('tabindex'); + } + + $selection.attr('title', this.$element.attr('title')); + $selection.attr('tabindex', this._tabindex); + + this.$selection = $selection; + + return $selection; + }; + + BaseSelection.prototype.bind = function (container, $container) { + var self = this; + + var id = container.id + '-container'; + var resultsId = container.id + '-results'; + + this.container = container; + + this.$selection.on('focus', function (evt) { + self.trigger('focus', evt); + }); + + this.$selection.on('blur', function (evt) { + self._handleBlur(evt); + }); + + this.$selection.on('keydown', function (evt) { + self.trigger('keypress', evt); + + if (evt.which === KEYS.SPACE) { + evt.preventDefault(); + } + }); + + container.on('results:focus', function (params) { + self.$selection.attr('aria-activedescendant', params.data._resultId); + }); + + container.on('selection:update', function (params) { + self.update(params.data); + }); + + container.on('open', function () { + // When the dropdown is open, aria-expanded="true" + self.$selection.attr('aria-expanded', 'true'); + self.$selection.attr('aria-owns', resultsId); + + self._attachCloseHandler(container); + }); + + container.on('close', function () { + // When the dropdown is closed, aria-expanded="false" + self.$selection.attr('aria-expanded', 'false'); + self.$selection.removeAttr('aria-activedescendant'); + self.$selection.removeAttr('aria-owns'); + + window.setTimeout(function () { + self.$selection.focus(); + }, 0); + + self._detachCloseHandler(container); + }); + + container.on('enable', function () { + self.$selection.attr('tabindex', self._tabindex); + }); + + container.on('disable', function () { + self.$selection.attr('tabindex', '-1'); + }); + }; + + BaseSelection.prototype._handleBlur = function (evt) { + var self = this; + + // This needs to be delayed as the active element is the body when the tab + // key is pressed, possibly along with others. + window.setTimeout(function () { + // Don't trigger `blur` if the focus is still in the selection + if ( + (document.activeElement == self.$selection[0]) || + ($.contains(self.$selection[0], document.activeElement)) + ) { + return; + } + + self.trigger('blur', evt); + }, 1); + }; + + BaseSelection.prototype._attachCloseHandler = function (container) { + var self = this; + + $(document.body).on('mousedown.select2.' + container.id, function (e) { + var $target = $(e.target); + + var $select = $target.closest('.select2'); + + var $all = $('.select2.select2-container--open'); + + $all.each(function () { + var $this = $(this); + + if (this == $select[0]) { + return; + } + + var $element = Utils.GetData(this, 'element'); + + $element.select2('close'); + }); + }); + }; + + BaseSelection.prototype._detachCloseHandler = function (container) { + $(document.body).off('mousedown.select2.' + container.id); + }; + + BaseSelection.prototype.position = function ($selection, $container) { + var $selectionContainer = $container.find('.selection'); + $selectionContainer.append($selection); + }; + + BaseSelection.prototype.destroy = function () { + this._detachCloseHandler(this.container); + }; + + BaseSelection.prototype.update = function (data) { + throw new Error('The `update` method must be defined in child classes.'); + }; + + return BaseSelection; +}); + +S2.define('select2/selection/single',[ + 'jquery', + './base', + '../utils', + '../keys' +], function ($, BaseSelection, Utils, KEYS) { + function SingleSelection () { + SingleSelection.__super__.constructor.apply(this, arguments); + } + + Utils.Extend(SingleSelection, BaseSelection); + + SingleSelection.prototype.render = function () { + var $selection = SingleSelection.__super__.render.call(this); + + $selection.addClass('select2-selection--single'); + + $selection.html( + '' + + '' + + '' + + '' + ); + + return $selection; + }; + + SingleSelection.prototype.bind = function (container, $container) { + var self = this; + + SingleSelection.__super__.bind.apply(this, arguments); + + var id = container.id + '-container'; + + this.$selection.find('.select2-selection__rendered') + .attr('id', id) + .attr('role', 'textbox') + .attr('aria-readonly', 'true'); + this.$selection.attr('aria-labelledby', id); + + this.$selection.on('mousedown', function (evt) { + // Only respond to left clicks + if (evt.which !== 1) { + return; + } + + self.trigger('toggle', { + originalEvent: evt + }); + }); + + this.$selection.on('focus', function (evt) { + // User focuses on the container + }); + + this.$selection.on('blur', function (evt) { + // User exits the container + }); + + container.on('focus', function (evt) { + if (!container.isOpen()) { + self.$selection.focus(); + } + }); + }; + + SingleSelection.prototype.clear = function () { + var $rendered = this.$selection.find('.select2-selection__rendered'); + $rendered.empty(); + $rendered.removeAttr('title'); // clear tooltip on empty + }; + + SingleSelection.prototype.display = function (data, container) { + var template = this.options.get('templateSelection'); + var escapeMarkup = this.options.get('escapeMarkup'); + + return escapeMarkup(template(data, container)); + }; + + SingleSelection.prototype.selectionContainer = function () { + return $(''); + }; + + SingleSelection.prototype.update = function (data) { + if (data.length === 0) { + this.clear(); + return; + } + + var selection = data[0]; + + var $rendered = this.$selection.find('.select2-selection__rendered'); + var formatted = this.display(selection, $rendered); + + $rendered.empty().append(formatted); + $rendered.attr('title', selection.title || selection.text); + }; + + return SingleSelection; +}); + +S2.define('select2/selection/multiple',[ + 'jquery', + './base', + '../utils' +], function ($, BaseSelection, Utils) { + function MultipleSelection ($element, options) { + MultipleSelection.__super__.constructor.apply(this, arguments); + } + + Utils.Extend(MultipleSelection, BaseSelection); + + MultipleSelection.prototype.render = function () { + var $selection = MultipleSelection.__super__.render.call(this); + + $selection.addClass('select2-selection--multiple'); + + $selection.html( + '
        ' + ); + + return $selection; + }; + + MultipleSelection.prototype.bind = function (container, $container) { + var self = this; + + MultipleSelection.__super__.bind.apply(this, arguments); + + this.$selection.on('click', function (evt) { + self.trigger('toggle', { + originalEvent: evt + }); + }); + + this.$selection.on( + 'click', + '.select2-selection__choice__remove', + function (evt) { + // Ignore the event if it is disabled + if (self.options.get('disabled')) { + return; + } + + var $remove = $(this); + var $selection = $remove.parent(); + + var data = Utils.GetData($selection[0], 'data'); + + self.trigger('unselect', { + originalEvent: evt, + data: data + }); + } + ); + }; + + MultipleSelection.prototype.clear = function () { + var $rendered = this.$selection.find('.select2-selection__rendered'); + $rendered.empty(); + $rendered.removeAttr('title'); + }; + + MultipleSelection.prototype.display = function (data, container) { + var template = this.options.get('templateSelection'); + var escapeMarkup = this.options.get('escapeMarkup'); + + return escapeMarkup(template(data, container)); + }; + + MultipleSelection.prototype.selectionContainer = function () { + var $container = $( + '
      • ' + + '' + + '×' + + '' + + '
      • ' + ); + + return $container; + }; + + MultipleSelection.prototype.update = function (data) { + this.clear(); + + if (data.length === 0) { + return; + } + + var $selections = []; + + for (var d = 0; d < data.length; d++) { + var selection = data[d]; + + var $selection = this.selectionContainer(); + var formatted = this.display(selection, $selection); + + $selection.append(formatted); + $selection.attr('title', selection.title || selection.text); + + Utils.StoreData($selection[0], 'data', selection); + + $selections.push($selection); + } + + var $rendered = this.$selection.find('.select2-selection__rendered'); + + Utils.appendMany($rendered, $selections); + }; + + return MultipleSelection; +}); + +S2.define('select2/selection/placeholder',[ + '../utils' +], function (Utils) { + function Placeholder (decorated, $element, options) { + this.placeholder = this.normalizePlaceholder(options.get('placeholder')); + + decorated.call(this, $element, options); + } + + Placeholder.prototype.normalizePlaceholder = function (_, placeholder) { + if (typeof placeholder === 'string') { + placeholder = { + id: '', + text: placeholder + }; + } + + return placeholder; + }; + + Placeholder.prototype.createPlaceholder = function (decorated, placeholder) { + var $placeholder = this.selectionContainer(); + + $placeholder.html(this.display(placeholder)); + $placeholder.addClass('select2-selection__placeholder') + .removeClass('select2-selection__choice'); + + return $placeholder; + }; + + Placeholder.prototype.update = function (decorated, data) { + var singlePlaceholder = ( + data.length == 1 && data[0].id != this.placeholder.id + ); + var multipleSelections = data.length > 1; + + if (multipleSelections || singlePlaceholder) { + return decorated.call(this, data); + } + + this.clear(); + + var $placeholder = this.createPlaceholder(this.placeholder); + + this.$selection.find('.select2-selection__rendered').append($placeholder); + }; + + return Placeholder; +}); + +S2.define('select2/selection/allowClear',[ + 'jquery', + '../keys', + '../utils' +], function ($, KEYS, Utils) { + function AllowClear () { } + + AllowClear.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + if (this.placeholder == null) { + if (this.options.get('debug') && window.console && console.error) { + console.error( + 'Select2: The `allowClear` option should be used in combination ' + + 'with the `placeholder` option.' + ); + } + } + + this.$selection.on('mousedown', '.select2-selection__clear', + function (evt) { + self._handleClear(evt); + }); + + container.on('keypress', function (evt) { + self._handleKeyboardClear(evt, container); + }); + }; + + AllowClear.prototype._handleClear = function (_, evt) { + // Ignore the event if it is disabled + if (this.options.get('disabled')) { + return; + } + + var $clear = this.$selection.find('.select2-selection__clear'); + + // Ignore the event if nothing has been selected + if ($clear.length === 0) { + return; + } + + evt.stopPropagation(); + + var data = Utils.GetData($clear[0], 'data'); + + var previousVal = this.$element.val(); + this.$element.val(this.placeholder.id); + + var unselectData = { + data: data + }; + this.trigger('clear', unselectData); + if (unselectData.prevented) { + this.$element.val(previousVal); + return; + } + + for (var d = 0; d < data.length; d++) { + unselectData = { + data: data[d] + }; + + // Trigger the `unselect` event, so people can prevent it from being + // cleared. + this.trigger('unselect', unselectData); + + // If the event was prevented, don't clear it out. + if (unselectData.prevented) { + this.$element.val(previousVal); + return; + } + } + + this.$element.trigger('change'); + + this.trigger('toggle', {}); + }; + + AllowClear.prototype._handleKeyboardClear = function (_, evt, container) { + if (container.isOpen()) { + return; + } + + if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) { + this._handleClear(evt); + } + }; + + AllowClear.prototype.update = function (decorated, data) { + decorated.call(this, data); + + if (this.$selection.find('.select2-selection__placeholder').length > 0 || + data.length === 0) { + return; + } + + var removeAll = this.options.get('translations').get('removeAllItems'); + + var $remove = $( + '' + + '×' + + '' + ); + Utils.StoreData($remove[0], 'data', data); + + this.$selection.find('.select2-selection__rendered').prepend($remove); + }; + + return AllowClear; +}); + +S2.define('select2/selection/search',[ + 'jquery', + '../utils', + '../keys' +], function ($, Utils, KEYS) { + function Search (decorated, $element, options) { + decorated.call(this, $element, options); + } + + Search.prototype.render = function (decorated) { + var $search = $( + '' + ); + + this.$searchContainer = $search; + this.$search = $search.find('input'); + + var $rendered = decorated.call(this); + + this._transferTabIndex(); + + return $rendered; + }; + + Search.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('open', function () { + self.$search.trigger('focus'); + }); + + container.on('close', function () { + self.$search.val(''); + self.$search.removeAttr('aria-activedescendant'); + self.$search.trigger('focus'); + }); + + container.on('enable', function () { + self.$search.prop('disabled', false); + + self._transferTabIndex(); + }); + + container.on('disable', function () { + self.$search.prop('disabled', true); + }); + + container.on('focus', function (evt) { + self.$search.trigger('focus'); + }); + + container.on('results:focus', function (params) { + self.$search.attr('aria-activedescendant', params.id); + }); + + this.$selection.on('focusin', '.select2-search--inline', function (evt) { + self.trigger('focus', evt); + }); + + this.$selection.on('focusout', '.select2-search--inline', function (evt) { + self._handleBlur(evt); + }); + + this.$selection.on('keydown', '.select2-search--inline', function (evt) { + evt.stopPropagation(); + + self.trigger('keypress', evt); + + self._keyUpPrevented = evt.isDefaultPrevented(); + + var key = evt.which; + + if (key === KEYS.BACKSPACE && self.$search.val() === '') { + var $previousChoice = self.$searchContainer + .prev('.select2-selection__choice'); + + if ($previousChoice.length > 0) { + var item = Utils.GetData($previousChoice[0], 'data'); + + self.searchRemoveChoice(item); + + evt.preventDefault(); + } + } + }); + + // Try to detect the IE version should the `documentMode` property that + // is stored on the document. This is only implemented in IE and is + // slightly cleaner than doing a user agent check. + // This property is not available in Edge, but Edge also doesn't have + // this bug. + var msie = document.documentMode; + var disableInputEvents = msie && msie <= 11; + + // Workaround for browsers which do not support the `input` event + // This will prevent double-triggering of events for browsers which support + // both the `keyup` and `input` events. + this.$selection.on( + 'input.searchcheck', + '.select2-search--inline', + function (evt) { + // IE will trigger the `input` event when a placeholder is used on a + // search box. To get around this issue, we are forced to ignore all + // `input` events in IE and keep using `keyup`. + if (disableInputEvents) { + self.$selection.off('input.search input.searchcheck'); + return; + } + + // Unbind the duplicated `keyup` event + self.$selection.off('keyup.search'); + } + ); + + this.$selection.on( + 'keyup.search input.search', + '.select2-search--inline', + function (evt) { + // IE will trigger the `input` event when a placeholder is used on a + // search box. To get around this issue, we are forced to ignore all + // `input` events in IE and keep using `keyup`. + if (disableInputEvents && evt.type === 'input') { + self.$selection.off('input.search input.searchcheck'); + return; + } + + var key = evt.which; + + // We can freely ignore events from modifier keys + if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) { + return; + } + + // Tabbing will be handled during the `keydown` phase + if (key == KEYS.TAB) { + return; + } + + self.handleSearch(evt); + } + ); + }; + + /** + * This method will transfer the tabindex attribute from the rendered + * selection to the search box. This allows for the search box to be used as + * the primary focus instead of the selection container. + * + * @private + */ + Search.prototype._transferTabIndex = function (decorated) { + this.$search.attr('tabindex', this.$selection.attr('tabindex')); + this.$selection.attr('tabindex', '-1'); + }; + + Search.prototype.createPlaceholder = function (decorated, placeholder) { + this.$search.attr('placeholder', placeholder.text); + }; + + Search.prototype.update = function (decorated, data) { + var searchHadFocus = this.$search[0] == document.activeElement; + + this.$search.attr('placeholder', ''); + + decorated.call(this, data); + + this.$selection.find('.select2-selection__rendered') + .append(this.$searchContainer); + + this.resizeSearch(); + if (searchHadFocus) { + var isTagInput = this.$element.find('[data-select2-tag]').length; + if (isTagInput) { + // fix IE11 bug where tag input lost focus + this.$element.focus(); + } else { + this.$search.focus(); + } + } + }; + + Search.prototype.handleSearch = function () { + this.resizeSearch(); + + if (!this._keyUpPrevented) { + var input = this.$search.val(); + + this.trigger('query', { + term: input + }); + } + + this._keyUpPrevented = false; + }; + + Search.prototype.searchRemoveChoice = function (decorated, item) { + this.trigger('unselect', { + data: item + }); + + this.$search.val(item.text); + this.handleSearch(); + }; + + Search.prototype.resizeSearch = function () { + this.$search.css('width', '25px'); + + var width = ''; + + if (this.$search.attr('placeholder') !== '') { + width = this.$selection.find('.select2-selection__rendered').innerWidth(); + } else { + var minimumWidth = this.$search.val().length + 1; + + width = (minimumWidth * 0.75) + 'em'; + } + + this.$search.css('width', width); + }; + + return Search; +}); + +S2.define('select2/selection/eventRelay',[ + 'jquery' +], function ($) { + function EventRelay () { } + + EventRelay.prototype.bind = function (decorated, container, $container) { + var self = this; + var relayEvents = [ + 'open', 'opening', + 'close', 'closing', + 'select', 'selecting', + 'unselect', 'unselecting', + 'clear', 'clearing' + ]; + + var preventableEvents = [ + 'opening', 'closing', 'selecting', 'unselecting', 'clearing' + ]; + + decorated.call(this, container, $container); + + container.on('*', function (name, params) { + // Ignore events that should not be relayed + if ($.inArray(name, relayEvents) === -1) { + return; + } + + // The parameters should always be an object + params = params || {}; + + // Generate the jQuery event for the Select2 event + var evt = $.Event('select2:' + name, { + params: params + }); + + self.$element.trigger(evt); + + // Only handle preventable events if it was one + if ($.inArray(name, preventableEvents) === -1) { + return; + } + + params.prevented = evt.isDefaultPrevented(); + }); + }; + + return EventRelay; +}); + +S2.define('select2/translation',[ + 'jquery', + 'require' +], function ($, require) { + function Translation (dict) { + this.dict = dict || {}; + } + + Translation.prototype.all = function () { + return this.dict; + }; + + Translation.prototype.get = function (key) { + return this.dict[key]; + }; + + Translation.prototype.extend = function (translation) { + this.dict = $.extend({}, translation.all(), this.dict); + }; + + // Static functions + + Translation._cache = {}; + + Translation.loadPath = function (path) { + if (!(path in Translation._cache)) { + var translations = require(path); + + Translation._cache[path] = translations; + } + + return new Translation(Translation._cache[path]); + }; + + return Translation; +}); + +S2.define('select2/diacritics',[ + +], function () { + var diacritics = { + '\u24B6': 'A', + '\uFF21': 'A', + '\u00C0': 'A', + '\u00C1': 'A', + '\u00C2': 'A', + '\u1EA6': 'A', + '\u1EA4': 'A', + '\u1EAA': 'A', + '\u1EA8': 'A', + '\u00C3': 'A', + '\u0100': 'A', + '\u0102': 'A', + '\u1EB0': 'A', + '\u1EAE': 'A', + '\u1EB4': 'A', + '\u1EB2': 'A', + '\u0226': 'A', + '\u01E0': 'A', + '\u00C4': 'A', + '\u01DE': 'A', + '\u1EA2': 'A', + '\u00C5': 'A', + '\u01FA': 'A', + '\u01CD': 'A', + '\u0200': 'A', + '\u0202': 'A', + '\u1EA0': 'A', + '\u1EAC': 'A', + '\u1EB6': 'A', + '\u1E00': 'A', + '\u0104': 'A', + '\u023A': 'A', + '\u2C6F': 'A', + '\uA732': 'AA', + '\u00C6': 'AE', + '\u01FC': 'AE', + '\u01E2': 'AE', + '\uA734': 'AO', + '\uA736': 'AU', + '\uA738': 'AV', + '\uA73A': 'AV', + '\uA73C': 'AY', + '\u24B7': 'B', + '\uFF22': 'B', + '\u1E02': 'B', + '\u1E04': 'B', + '\u1E06': 'B', + '\u0243': 'B', + '\u0182': 'B', + '\u0181': 'B', + '\u24B8': 'C', + '\uFF23': 'C', + '\u0106': 'C', + '\u0108': 'C', + '\u010A': 'C', + '\u010C': 'C', + '\u00C7': 'C', + '\u1E08': 'C', + '\u0187': 'C', + '\u023B': 'C', + '\uA73E': 'C', + '\u24B9': 'D', + '\uFF24': 'D', + '\u1E0A': 'D', + '\u010E': 'D', + '\u1E0C': 'D', + '\u1E10': 'D', + '\u1E12': 'D', + '\u1E0E': 'D', + '\u0110': 'D', + '\u018B': 'D', + '\u018A': 'D', + '\u0189': 'D', + '\uA779': 'D', + '\u01F1': 'DZ', + '\u01C4': 'DZ', + '\u01F2': 'Dz', + '\u01C5': 'Dz', + '\u24BA': 'E', + '\uFF25': 'E', + '\u00C8': 'E', + '\u00C9': 'E', + '\u00CA': 'E', + '\u1EC0': 'E', + '\u1EBE': 'E', + '\u1EC4': 'E', + '\u1EC2': 'E', + '\u1EBC': 'E', + '\u0112': 'E', + '\u1E14': 'E', + '\u1E16': 'E', + '\u0114': 'E', + '\u0116': 'E', + '\u00CB': 'E', + '\u1EBA': 'E', + '\u011A': 'E', + '\u0204': 'E', + '\u0206': 'E', + '\u1EB8': 'E', + '\u1EC6': 'E', + '\u0228': 'E', + '\u1E1C': 'E', + '\u0118': 'E', + '\u1E18': 'E', + '\u1E1A': 'E', + '\u0190': 'E', + '\u018E': 'E', + '\u24BB': 'F', + '\uFF26': 'F', + '\u1E1E': 'F', + '\u0191': 'F', + '\uA77B': 'F', + '\u24BC': 'G', + '\uFF27': 'G', + '\u01F4': 'G', + '\u011C': 'G', + '\u1E20': 'G', + '\u011E': 'G', + '\u0120': 'G', + '\u01E6': 'G', + '\u0122': 'G', + '\u01E4': 'G', + '\u0193': 'G', + '\uA7A0': 'G', + '\uA77D': 'G', + '\uA77E': 'G', + '\u24BD': 'H', + '\uFF28': 'H', + '\u0124': 'H', + '\u1E22': 'H', + '\u1E26': 'H', + '\u021E': 'H', + '\u1E24': 'H', + '\u1E28': 'H', + '\u1E2A': 'H', + '\u0126': 'H', + '\u2C67': 'H', + '\u2C75': 'H', + '\uA78D': 'H', + '\u24BE': 'I', + '\uFF29': 'I', + '\u00CC': 'I', + '\u00CD': 'I', + '\u00CE': 'I', + '\u0128': 'I', + '\u012A': 'I', + '\u012C': 'I', + '\u0130': 'I', + '\u00CF': 'I', + '\u1E2E': 'I', + '\u1EC8': 'I', + '\u01CF': 'I', + '\u0208': 'I', + '\u020A': 'I', + '\u1ECA': 'I', + '\u012E': 'I', + '\u1E2C': 'I', + '\u0197': 'I', + '\u24BF': 'J', + '\uFF2A': 'J', + '\u0134': 'J', + '\u0248': 'J', + '\u24C0': 'K', + '\uFF2B': 'K', + '\u1E30': 'K', + '\u01E8': 'K', + '\u1E32': 'K', + '\u0136': 'K', + '\u1E34': 'K', + '\u0198': 'K', + '\u2C69': 'K', + '\uA740': 'K', + '\uA742': 'K', + '\uA744': 'K', + '\uA7A2': 'K', + '\u24C1': 'L', + '\uFF2C': 'L', + '\u013F': 'L', + '\u0139': 'L', + '\u013D': 'L', + '\u1E36': 'L', + '\u1E38': 'L', + '\u013B': 'L', + '\u1E3C': 'L', + '\u1E3A': 'L', + '\u0141': 'L', + '\u023D': 'L', + '\u2C62': 'L', + '\u2C60': 'L', + '\uA748': 'L', + '\uA746': 'L', + '\uA780': 'L', + '\u01C7': 'LJ', + '\u01C8': 'Lj', + '\u24C2': 'M', + '\uFF2D': 'M', + '\u1E3E': 'M', + '\u1E40': 'M', + '\u1E42': 'M', + '\u2C6E': 'M', + '\u019C': 'M', + '\u24C3': 'N', + '\uFF2E': 'N', + '\u01F8': 'N', + '\u0143': 'N', + '\u00D1': 'N', + '\u1E44': 'N', + '\u0147': 'N', + '\u1E46': 'N', + '\u0145': 'N', + '\u1E4A': 'N', + '\u1E48': 'N', + '\u0220': 'N', + '\u019D': 'N', + '\uA790': 'N', + '\uA7A4': 'N', + '\u01CA': 'NJ', + '\u01CB': 'Nj', + '\u24C4': 'O', + '\uFF2F': 'O', + '\u00D2': 'O', + '\u00D3': 'O', + '\u00D4': 'O', + '\u1ED2': 'O', + '\u1ED0': 'O', + '\u1ED6': 'O', + '\u1ED4': 'O', + '\u00D5': 'O', + '\u1E4C': 'O', + '\u022C': 'O', + '\u1E4E': 'O', + '\u014C': 'O', + '\u1E50': 'O', + '\u1E52': 'O', + '\u014E': 'O', + '\u022E': 'O', + '\u0230': 'O', + '\u00D6': 'O', + '\u022A': 'O', + '\u1ECE': 'O', + '\u0150': 'O', + '\u01D1': 'O', + '\u020C': 'O', + '\u020E': 'O', + '\u01A0': 'O', + '\u1EDC': 'O', + '\u1EDA': 'O', + '\u1EE0': 'O', + '\u1EDE': 'O', + '\u1EE2': 'O', + '\u1ECC': 'O', + '\u1ED8': 'O', + '\u01EA': 'O', + '\u01EC': 'O', + '\u00D8': 'O', + '\u01FE': 'O', + '\u0186': 'O', + '\u019F': 'O', + '\uA74A': 'O', + '\uA74C': 'O', + '\u0152': 'OE', + '\u01A2': 'OI', + '\uA74E': 'OO', + '\u0222': 'OU', + '\u24C5': 'P', + '\uFF30': 'P', + '\u1E54': 'P', + '\u1E56': 'P', + '\u01A4': 'P', + '\u2C63': 'P', + '\uA750': 'P', + '\uA752': 'P', + '\uA754': 'P', + '\u24C6': 'Q', + '\uFF31': 'Q', + '\uA756': 'Q', + '\uA758': 'Q', + '\u024A': 'Q', + '\u24C7': 'R', + '\uFF32': 'R', + '\u0154': 'R', + '\u1E58': 'R', + '\u0158': 'R', + '\u0210': 'R', + '\u0212': 'R', + '\u1E5A': 'R', + '\u1E5C': 'R', + '\u0156': 'R', + '\u1E5E': 'R', + '\u024C': 'R', + '\u2C64': 'R', + '\uA75A': 'R', + '\uA7A6': 'R', + '\uA782': 'R', + '\u24C8': 'S', + '\uFF33': 'S', + '\u1E9E': 'S', + '\u015A': 'S', + '\u1E64': 'S', + '\u015C': 'S', + '\u1E60': 'S', + '\u0160': 'S', + '\u1E66': 'S', + '\u1E62': 'S', + '\u1E68': 'S', + '\u0218': 'S', + '\u015E': 'S', + '\u2C7E': 'S', + '\uA7A8': 'S', + '\uA784': 'S', + '\u24C9': 'T', + '\uFF34': 'T', + '\u1E6A': 'T', + '\u0164': 'T', + '\u1E6C': 'T', + '\u021A': 'T', + '\u0162': 'T', + '\u1E70': 'T', + '\u1E6E': 'T', + '\u0166': 'T', + '\u01AC': 'T', + '\u01AE': 'T', + '\u023E': 'T', + '\uA786': 'T', + '\uA728': 'TZ', + '\u24CA': 'U', + '\uFF35': 'U', + '\u00D9': 'U', + '\u00DA': 'U', + '\u00DB': 'U', + '\u0168': 'U', + '\u1E78': 'U', + '\u016A': 'U', + '\u1E7A': 'U', + '\u016C': 'U', + '\u00DC': 'U', + '\u01DB': 'U', + '\u01D7': 'U', + '\u01D5': 'U', + '\u01D9': 'U', + '\u1EE6': 'U', + '\u016E': 'U', + '\u0170': 'U', + '\u01D3': 'U', + '\u0214': 'U', + '\u0216': 'U', + '\u01AF': 'U', + '\u1EEA': 'U', + '\u1EE8': 'U', + '\u1EEE': 'U', + '\u1EEC': 'U', + '\u1EF0': 'U', + '\u1EE4': 'U', + '\u1E72': 'U', + '\u0172': 'U', + '\u1E76': 'U', + '\u1E74': 'U', + '\u0244': 'U', + '\u24CB': 'V', + '\uFF36': 'V', + '\u1E7C': 'V', + '\u1E7E': 'V', + '\u01B2': 'V', + '\uA75E': 'V', + '\u0245': 'V', + '\uA760': 'VY', + '\u24CC': 'W', + '\uFF37': 'W', + '\u1E80': 'W', + '\u1E82': 'W', + '\u0174': 'W', + '\u1E86': 'W', + '\u1E84': 'W', + '\u1E88': 'W', + '\u2C72': 'W', + '\u24CD': 'X', + '\uFF38': 'X', + '\u1E8A': 'X', + '\u1E8C': 'X', + '\u24CE': 'Y', + '\uFF39': 'Y', + '\u1EF2': 'Y', + '\u00DD': 'Y', + '\u0176': 'Y', + '\u1EF8': 'Y', + '\u0232': 'Y', + '\u1E8E': 'Y', + '\u0178': 'Y', + '\u1EF6': 'Y', + '\u1EF4': 'Y', + '\u01B3': 'Y', + '\u024E': 'Y', + '\u1EFE': 'Y', + '\u24CF': 'Z', + '\uFF3A': 'Z', + '\u0179': 'Z', + '\u1E90': 'Z', + '\u017B': 'Z', + '\u017D': 'Z', + '\u1E92': 'Z', + '\u1E94': 'Z', + '\u01B5': 'Z', + '\u0224': 'Z', + '\u2C7F': 'Z', + '\u2C6B': 'Z', + '\uA762': 'Z', + '\u24D0': 'a', + '\uFF41': 'a', + '\u1E9A': 'a', + '\u00E0': 'a', + '\u00E1': 'a', + '\u00E2': 'a', + '\u1EA7': 'a', + '\u1EA5': 'a', + '\u1EAB': 'a', + '\u1EA9': 'a', + '\u00E3': 'a', + '\u0101': 'a', + '\u0103': 'a', + '\u1EB1': 'a', + '\u1EAF': 'a', + '\u1EB5': 'a', + '\u1EB3': 'a', + '\u0227': 'a', + '\u01E1': 'a', + '\u00E4': 'a', + '\u01DF': 'a', + '\u1EA3': 'a', + '\u00E5': 'a', + '\u01FB': 'a', + '\u01CE': 'a', + '\u0201': 'a', + '\u0203': 'a', + '\u1EA1': 'a', + '\u1EAD': 'a', + '\u1EB7': 'a', + '\u1E01': 'a', + '\u0105': 'a', + '\u2C65': 'a', + '\u0250': 'a', + '\uA733': 'aa', + '\u00E6': 'ae', + '\u01FD': 'ae', + '\u01E3': 'ae', + '\uA735': 'ao', + '\uA737': 'au', + '\uA739': 'av', + '\uA73B': 'av', + '\uA73D': 'ay', + '\u24D1': 'b', + '\uFF42': 'b', + '\u1E03': 'b', + '\u1E05': 'b', + '\u1E07': 'b', + '\u0180': 'b', + '\u0183': 'b', + '\u0253': 'b', + '\u24D2': 'c', + '\uFF43': 'c', + '\u0107': 'c', + '\u0109': 'c', + '\u010B': 'c', + '\u010D': 'c', + '\u00E7': 'c', + '\u1E09': 'c', + '\u0188': 'c', + '\u023C': 'c', + '\uA73F': 'c', + '\u2184': 'c', + '\u24D3': 'd', + '\uFF44': 'd', + '\u1E0B': 'd', + '\u010F': 'd', + '\u1E0D': 'd', + '\u1E11': 'd', + '\u1E13': 'd', + '\u1E0F': 'd', + '\u0111': 'd', + '\u018C': 'd', + '\u0256': 'd', + '\u0257': 'd', + '\uA77A': 'd', + '\u01F3': 'dz', + '\u01C6': 'dz', + '\u24D4': 'e', + '\uFF45': 'e', + '\u00E8': 'e', + '\u00E9': 'e', + '\u00EA': 'e', + '\u1EC1': 'e', + '\u1EBF': 'e', + '\u1EC5': 'e', + '\u1EC3': 'e', + '\u1EBD': 'e', + '\u0113': 'e', + '\u1E15': 'e', + '\u1E17': 'e', + '\u0115': 'e', + '\u0117': 'e', + '\u00EB': 'e', + '\u1EBB': 'e', + '\u011B': 'e', + '\u0205': 'e', + '\u0207': 'e', + '\u1EB9': 'e', + '\u1EC7': 'e', + '\u0229': 'e', + '\u1E1D': 'e', + '\u0119': 'e', + '\u1E19': 'e', + '\u1E1B': 'e', + '\u0247': 'e', + '\u025B': 'e', + '\u01DD': 'e', + '\u24D5': 'f', + '\uFF46': 'f', + '\u1E1F': 'f', + '\u0192': 'f', + '\uA77C': 'f', + '\u24D6': 'g', + '\uFF47': 'g', + '\u01F5': 'g', + '\u011D': 'g', + '\u1E21': 'g', + '\u011F': 'g', + '\u0121': 'g', + '\u01E7': 'g', + '\u0123': 'g', + '\u01E5': 'g', + '\u0260': 'g', + '\uA7A1': 'g', + '\u1D79': 'g', + '\uA77F': 'g', + '\u24D7': 'h', + '\uFF48': 'h', + '\u0125': 'h', + '\u1E23': 'h', + '\u1E27': 'h', + '\u021F': 'h', + '\u1E25': 'h', + '\u1E29': 'h', + '\u1E2B': 'h', + '\u1E96': 'h', + '\u0127': 'h', + '\u2C68': 'h', + '\u2C76': 'h', + '\u0265': 'h', + '\u0195': 'hv', + '\u24D8': 'i', + '\uFF49': 'i', + '\u00EC': 'i', + '\u00ED': 'i', + '\u00EE': 'i', + '\u0129': 'i', + '\u012B': 'i', + '\u012D': 'i', + '\u00EF': 'i', + '\u1E2F': 'i', + '\u1EC9': 'i', + '\u01D0': 'i', + '\u0209': 'i', + '\u020B': 'i', + '\u1ECB': 'i', + '\u012F': 'i', + '\u1E2D': 'i', + '\u0268': 'i', + '\u0131': 'i', + '\u24D9': 'j', + '\uFF4A': 'j', + '\u0135': 'j', + '\u01F0': 'j', + '\u0249': 'j', + '\u24DA': 'k', + '\uFF4B': 'k', + '\u1E31': 'k', + '\u01E9': 'k', + '\u1E33': 'k', + '\u0137': 'k', + '\u1E35': 'k', + '\u0199': 'k', + '\u2C6A': 'k', + '\uA741': 'k', + '\uA743': 'k', + '\uA745': 'k', + '\uA7A3': 'k', + '\u24DB': 'l', + '\uFF4C': 'l', + '\u0140': 'l', + '\u013A': 'l', + '\u013E': 'l', + '\u1E37': 'l', + '\u1E39': 'l', + '\u013C': 'l', + '\u1E3D': 'l', + '\u1E3B': 'l', + '\u017F': 'l', + '\u0142': 'l', + '\u019A': 'l', + '\u026B': 'l', + '\u2C61': 'l', + '\uA749': 'l', + '\uA781': 'l', + '\uA747': 'l', + '\u01C9': 'lj', + '\u24DC': 'm', + '\uFF4D': 'm', + '\u1E3F': 'm', + '\u1E41': 'm', + '\u1E43': 'm', + '\u0271': 'm', + '\u026F': 'm', + '\u24DD': 'n', + '\uFF4E': 'n', + '\u01F9': 'n', + '\u0144': 'n', + '\u00F1': 'n', + '\u1E45': 'n', + '\u0148': 'n', + '\u1E47': 'n', + '\u0146': 'n', + '\u1E4B': 'n', + '\u1E49': 'n', + '\u019E': 'n', + '\u0272': 'n', + '\u0149': 'n', + '\uA791': 'n', + '\uA7A5': 'n', + '\u01CC': 'nj', + '\u24DE': 'o', + '\uFF4F': 'o', + '\u00F2': 'o', + '\u00F3': 'o', + '\u00F4': 'o', + '\u1ED3': 'o', + '\u1ED1': 'o', + '\u1ED7': 'o', + '\u1ED5': 'o', + '\u00F5': 'o', + '\u1E4D': 'o', + '\u022D': 'o', + '\u1E4F': 'o', + '\u014D': 'o', + '\u1E51': 'o', + '\u1E53': 'o', + '\u014F': 'o', + '\u022F': 'o', + '\u0231': 'o', + '\u00F6': 'o', + '\u022B': 'o', + '\u1ECF': 'o', + '\u0151': 'o', + '\u01D2': 'o', + '\u020D': 'o', + '\u020F': 'o', + '\u01A1': 'o', + '\u1EDD': 'o', + '\u1EDB': 'o', + '\u1EE1': 'o', + '\u1EDF': 'o', + '\u1EE3': 'o', + '\u1ECD': 'o', + '\u1ED9': 'o', + '\u01EB': 'o', + '\u01ED': 'o', + '\u00F8': 'o', + '\u01FF': 'o', + '\u0254': 'o', + '\uA74B': 'o', + '\uA74D': 'o', + '\u0275': 'o', + '\u0153': 'oe', + '\u01A3': 'oi', + '\u0223': 'ou', + '\uA74F': 'oo', + '\u24DF': 'p', + '\uFF50': 'p', + '\u1E55': 'p', + '\u1E57': 'p', + '\u01A5': 'p', + '\u1D7D': 'p', + '\uA751': 'p', + '\uA753': 'p', + '\uA755': 'p', + '\u24E0': 'q', + '\uFF51': 'q', + '\u024B': 'q', + '\uA757': 'q', + '\uA759': 'q', + '\u24E1': 'r', + '\uFF52': 'r', + '\u0155': 'r', + '\u1E59': 'r', + '\u0159': 'r', + '\u0211': 'r', + '\u0213': 'r', + '\u1E5B': 'r', + '\u1E5D': 'r', + '\u0157': 'r', + '\u1E5F': 'r', + '\u024D': 'r', + '\u027D': 'r', + '\uA75B': 'r', + '\uA7A7': 'r', + '\uA783': 'r', + '\u24E2': 's', + '\uFF53': 's', + '\u00DF': 's', + '\u015B': 's', + '\u1E65': 's', + '\u015D': 's', + '\u1E61': 's', + '\u0161': 's', + '\u1E67': 's', + '\u1E63': 's', + '\u1E69': 's', + '\u0219': 's', + '\u015F': 's', + '\u023F': 's', + '\uA7A9': 's', + '\uA785': 's', + '\u1E9B': 's', + '\u24E3': 't', + '\uFF54': 't', + '\u1E6B': 't', + '\u1E97': 't', + '\u0165': 't', + '\u1E6D': 't', + '\u021B': 't', + '\u0163': 't', + '\u1E71': 't', + '\u1E6F': 't', + '\u0167': 't', + '\u01AD': 't', + '\u0288': 't', + '\u2C66': 't', + '\uA787': 't', + '\uA729': 'tz', + '\u24E4': 'u', + '\uFF55': 'u', + '\u00F9': 'u', + '\u00FA': 'u', + '\u00FB': 'u', + '\u0169': 'u', + '\u1E79': 'u', + '\u016B': 'u', + '\u1E7B': 'u', + '\u016D': 'u', + '\u00FC': 'u', + '\u01DC': 'u', + '\u01D8': 'u', + '\u01D6': 'u', + '\u01DA': 'u', + '\u1EE7': 'u', + '\u016F': 'u', + '\u0171': 'u', + '\u01D4': 'u', + '\u0215': 'u', + '\u0217': 'u', + '\u01B0': 'u', + '\u1EEB': 'u', + '\u1EE9': 'u', + '\u1EEF': 'u', + '\u1EED': 'u', + '\u1EF1': 'u', + '\u1EE5': 'u', + '\u1E73': 'u', + '\u0173': 'u', + '\u1E77': 'u', + '\u1E75': 'u', + '\u0289': 'u', + '\u24E5': 'v', + '\uFF56': 'v', + '\u1E7D': 'v', + '\u1E7F': 'v', + '\u028B': 'v', + '\uA75F': 'v', + '\u028C': 'v', + '\uA761': 'vy', + '\u24E6': 'w', + '\uFF57': 'w', + '\u1E81': 'w', + '\u1E83': 'w', + '\u0175': 'w', + '\u1E87': 'w', + '\u1E85': 'w', + '\u1E98': 'w', + '\u1E89': 'w', + '\u2C73': 'w', + '\u24E7': 'x', + '\uFF58': 'x', + '\u1E8B': 'x', + '\u1E8D': 'x', + '\u24E8': 'y', + '\uFF59': 'y', + '\u1EF3': 'y', + '\u00FD': 'y', + '\u0177': 'y', + '\u1EF9': 'y', + '\u0233': 'y', + '\u1E8F': 'y', + '\u00FF': 'y', + '\u1EF7': 'y', + '\u1E99': 'y', + '\u1EF5': 'y', + '\u01B4': 'y', + '\u024F': 'y', + '\u1EFF': 'y', + '\u24E9': 'z', + '\uFF5A': 'z', + '\u017A': 'z', + '\u1E91': 'z', + '\u017C': 'z', + '\u017E': 'z', + '\u1E93': 'z', + '\u1E95': 'z', + '\u01B6': 'z', + '\u0225': 'z', + '\u0240': 'z', + '\u2C6C': 'z', + '\uA763': 'z', + '\u0386': '\u0391', + '\u0388': '\u0395', + '\u0389': '\u0397', + '\u038A': '\u0399', + '\u03AA': '\u0399', + '\u038C': '\u039F', + '\u038E': '\u03A5', + '\u03AB': '\u03A5', + '\u038F': '\u03A9', + '\u03AC': '\u03B1', + '\u03AD': '\u03B5', + '\u03AE': '\u03B7', + '\u03AF': '\u03B9', + '\u03CA': '\u03B9', + '\u0390': '\u03B9', + '\u03CC': '\u03BF', + '\u03CD': '\u03C5', + '\u03CB': '\u03C5', + '\u03B0': '\u03C5', + '\u03CE': '\u03C9', + '\u03C2': '\u03C3', + '\u2019': '\'' + }; + + return diacritics; +}); + +S2.define('select2/data/base',[ + '../utils' +], function (Utils) { + function BaseAdapter ($element, options) { + BaseAdapter.__super__.constructor.call(this); + } + + Utils.Extend(BaseAdapter, Utils.Observable); + + BaseAdapter.prototype.current = function (callback) { + throw new Error('The `current` method must be defined in child classes.'); + }; + + BaseAdapter.prototype.query = function (params, callback) { + throw new Error('The `query` method must be defined in child classes.'); + }; + + BaseAdapter.prototype.bind = function (container, $container) { + // Can be implemented in subclasses + }; + + BaseAdapter.prototype.destroy = function () { + // Can be implemented in subclasses + }; + + BaseAdapter.prototype.generateResultId = function (container, data) { + var id = container.id + '-result-'; + + id += Utils.generateChars(4); + + if (data.id != null) { + id += '-' + data.id.toString(); + } else { + id += '-' + Utils.generateChars(4); + } + return id; + }; + + return BaseAdapter; +}); + +S2.define('select2/data/select',[ + './base', + '../utils', + 'jquery' +], function (BaseAdapter, Utils, $) { + function SelectAdapter ($element, options) { + this.$element = $element; + this.options = options; + + SelectAdapter.__super__.constructor.call(this); + } + + Utils.Extend(SelectAdapter, BaseAdapter); + + SelectAdapter.prototype.current = function (callback) { + var data = []; + var self = this; + + this.$element.find(':selected').each(function () { + var $option = $(this); + + var option = self.item($option); + + data.push(option); + }); + + callback(data); + }; + + SelectAdapter.prototype.select = function (data) { + var self = this; + + data.selected = true; + + // If data.element is a DOM node, use it instead + if ($(data.element).is('option')) { + data.element.selected = true; + + this.$element.trigger('change'); + + return; + } + + if (this.$element.prop('multiple')) { + this.current(function (currentData) { + var val = []; + + data = [data]; + data.push.apply(data, currentData); + + for (var d = 0; d < data.length; d++) { + var id = data[d].id; + + if ($.inArray(id, val) === -1) { + val.push(id); + } + } + + self.$element.val(val); + self.$element.trigger('change'); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger('change'); + } + }; + + SelectAdapter.prototype.unselect = function (data) { + var self = this; + + if (!this.$element.prop('multiple')) { + return; + } + + data.selected = false; + + if ($(data.element).is('option')) { + data.element.selected = false; + + this.$element.trigger('change'); + + return; + } + + this.current(function (currentData) { + var val = []; + + for (var d = 0; d < currentData.length; d++) { + var id = currentData[d].id; + + if (id !== data.id && $.inArray(id, val) === -1) { + val.push(id); + } + } + + self.$element.val(val); + + self.$element.trigger('change'); + }); + }; + + SelectAdapter.prototype.bind = function (container, $container) { + var self = this; + + this.container = container; + + container.on('select', function (params) { + self.select(params.data); + }); + + container.on('unselect', function (params) { + self.unselect(params.data); + }); + }; + + SelectAdapter.prototype.destroy = function () { + // Remove anything added to child elements + this.$element.find('*').each(function () { + // Remove any custom data set by Select2 + Utils.RemoveData(this); + }); + }; + + SelectAdapter.prototype.query = function (params, callback) { + var data = []; + var self = this; + + var $options = this.$element.children(); + + $options.each(function () { + var $option = $(this); + + if (!$option.is('option') && !$option.is('optgroup')) { + return; + } + + var option = self.item($option); + + var matches = self.matches(params, option); + + if (matches !== null) { + data.push(matches); + } + }); + + callback({ + results: data + }); + }; + + SelectAdapter.prototype.addOptions = function ($options) { + Utils.appendMany(this.$element, $options); + }; + + SelectAdapter.prototype.option = function (data) { + var option; + + if (data.children) { + option = document.createElement('optgroup'); + option.label = data.text; + } else { + option = document.createElement('option'); + + if (option.textContent !== undefined) { + option.textContent = data.text; + } else { + option.innerText = data.text; + } + } + + if (data.id !== undefined) { + option.value = data.id; + } + + if (data.disabled) { + option.disabled = true; + } + + if (data.selected) { + option.selected = true; + } + + if (data.title) { + option.title = data.title; + } + + var $option = $(option); + + var normalizedData = this._normalizeItem(data); + normalizedData.element = option; + + // Override the option's data with the combined data + Utils.StoreData(option, 'data', normalizedData); + + return $option; + }; + + SelectAdapter.prototype.item = function ($option) { + var data = {}; + + data = Utils.GetData($option[0], 'data'); + + if (data != null) { + return data; + } + + if ($option.is('option')) { + data = { + id: $option.val(), + text: $option.text(), + disabled: $option.prop('disabled'), + selected: $option.prop('selected'), + title: $option.prop('title') + }; + } else if ($option.is('optgroup')) { + data = { + text: $option.prop('label'), + children: [], + title: $option.prop('title') + }; + + var $children = $option.children('option'); + var children = []; + + for (var c = 0; c < $children.length; c++) { + var $child = $($children[c]); + + var child = this.item($child); + + children.push(child); + } + + data.children = children; + } + + data = this._normalizeItem(data); + data.element = $option[0]; + + Utils.StoreData($option[0], 'data', data); + + return data; + }; + + SelectAdapter.prototype._normalizeItem = function (item) { + if (item !== Object(item)) { + item = { + id: item, + text: item + }; + } + + item = $.extend({}, { + text: '' + }, item); + + var defaults = { + selected: false, + disabled: false + }; + + if (item.id != null) { + item.id = item.id.toString(); + } + + if (item.text != null) { + item.text = item.text.toString(); + } + + if (item._resultId == null && item.id && this.container != null) { + item._resultId = this.generateResultId(this.container, item); + } + + return $.extend({}, defaults, item); + }; + + SelectAdapter.prototype.matches = function (params, data) { + var matcher = this.options.get('matcher'); + + return matcher(params, data); + }; + + return SelectAdapter; +}); + +S2.define('select2/data/array',[ + './select', + '../utils', + 'jquery' +], function (SelectAdapter, Utils, $) { + function ArrayAdapter ($element, options) { + var data = options.get('data') || []; + + ArrayAdapter.__super__.constructor.call(this, $element, options); + + this.addOptions(this.convertToOptions(data)); + } + + Utils.Extend(ArrayAdapter, SelectAdapter); + + ArrayAdapter.prototype.select = function (data) { + var $option = this.$element.find('option').filter(function (i, elm) { + return elm.value == data.id.toString(); + }); + + if ($option.length === 0) { + $option = this.option(data); + + this.addOptions($option); + } + + ArrayAdapter.__super__.select.call(this, data); + }; + + ArrayAdapter.prototype.convertToOptions = function (data) { + var self = this; + + var $existing = this.$element.find('option'); + var existingIds = $existing.map(function () { + return self.item($(this)).id; + }).get(); + + var $options = []; + + // Filter out all items except for the one passed in the argument + function onlyItem (item) { + return function () { + return $(this).val() == item.id; + }; + } + + for (var d = 0; d < data.length; d++) { + var item = this._normalizeItem(data[d]); + + // Skip items which were pre-loaded, only merge the data + if ($.inArray(item.id, existingIds) >= 0) { + var $existingOption = $existing.filter(onlyItem(item)); + + var existingData = this.item($existingOption); + var newData = $.extend(true, {}, item, existingData); + + var $newOption = this.option(newData); + + $existingOption.replaceWith($newOption); + + continue; + } + + var $option = this.option(item); + + if (item.children) { + var $children = this.convertToOptions(item.children); + + Utils.appendMany($option, $children); + } + + $options.push($option); + } + + return $options; + }; + + return ArrayAdapter; +}); + +S2.define('select2/data/ajax',[ + './array', + '../utils', + 'jquery' +], function (ArrayAdapter, Utils, $) { + function AjaxAdapter ($element, options) { + this.ajaxOptions = this._applyDefaults(options.get('ajax')); + + if (this.ajaxOptions.processResults != null) { + this.processResults = this.ajaxOptions.processResults; + } + + AjaxAdapter.__super__.constructor.call(this, $element, options); + } + + Utils.Extend(AjaxAdapter, ArrayAdapter); + + AjaxAdapter.prototype._applyDefaults = function (options) { + var defaults = { + data: function (params) { + return $.extend({}, params, { + q: params.term + }); + }, + transport: function (params, success, failure) { + var $request = $.ajax(params); + + $request.then(success); + $request.fail(failure); + + return $request; + } + }; + + return $.extend({}, defaults, options, true); + }; + + AjaxAdapter.prototype.processResults = function (results) { + return results; + }; + + AjaxAdapter.prototype.query = function (params, callback) { + var matches = []; + var self = this; + + if (this._request != null) { + // JSONP requests cannot always be aborted + if ($.isFunction(this._request.abort)) { + this._request.abort(); + } + + this._request = null; + } + + var options = $.extend({ + type: 'GET' + }, this.ajaxOptions); + + if (typeof options.url === 'function') { + options.url = options.url.call(this.$element, params); + } + + if (typeof options.data === 'function') { + options.data = options.data.call(this.$element, params); + } + + function request () { + var $request = options.transport(options, function (data) { + var results = self.processResults(data, params); + + if (self.options.get('debug') && window.console && console.error) { + // Check to make sure that the response included a `results` key. + if (!results || !results.results || !$.isArray(results.results)) { + console.error( + 'Select2: The AJAX results did not return an array in the ' + + '`results` key of the response.' + ); + } + } + + callback(results); + }, function () { + // Attempt to detect if a request was aborted + // Only works if the transport exposes a status property + if ('status' in $request && + ($request.status === 0 || $request.status === '0')) { + return; + } + + self.trigger('results:message', { + message: 'errorLoading' + }); + }); + + self._request = $request; + } + + if (this.ajaxOptions.delay && params.term != null) { + if (this._queryTimeout) { + window.clearTimeout(this._queryTimeout); + } + + this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay); + } else { + request(); + } + }; + + return AjaxAdapter; +}); + +S2.define('select2/data/tags',[ + 'jquery' +], function ($) { + function Tags (decorated, $element, options) { + var tags = options.get('tags'); + + var createTag = options.get('createTag'); + + if (createTag !== undefined) { + this.createTag = createTag; + } + + var insertTag = options.get('insertTag'); + + if (insertTag !== undefined) { + this.insertTag = insertTag; + } + + decorated.call(this, $element, options); + + if ($.isArray(tags)) { + for (var t = 0; t < tags.length; t++) { + var tag = tags[t]; + var item = this._normalizeItem(tag); + + var $option = this.option(item); + + this.$element.append($option); + } + } + } + + Tags.prototype.query = function (decorated, params, callback) { + var self = this; + + this._removeOldTags(); + + if (params.term == null || params.page != null) { + decorated.call(this, params, callback); + return; + } + + function wrapper (obj, child) { + var data = obj.results; + + for (var i = 0; i < data.length; i++) { + var option = data[i]; + + var checkChildren = ( + option.children != null && + !wrapper({ + results: option.children + }, true) + ); + + var optionText = (option.text || '').toUpperCase(); + var paramsTerm = (params.term || '').toUpperCase(); + + var checkText = optionText === paramsTerm; + + if (checkText || checkChildren) { + if (child) { + return false; + } + + obj.data = data; + callback(obj); + + return; + } + } + + if (child) { + return true; + } + + var tag = self.createTag(params); + + if (tag != null) { + var $option = self.option(tag); + $option.attr('data-select2-tag', true); + + self.addOptions([$option]); + + self.insertTag(data, tag); + } + + obj.results = data; + + callback(obj); + } + + decorated.call(this, params, wrapper); + }; + + Tags.prototype.createTag = function (decorated, params) { + var term = $.trim(params.term); + + if (term === '') { + return null; + } + + return { + id: term, + text: term + }; + }; + + Tags.prototype.insertTag = function (_, data, tag) { + data.unshift(tag); + }; + + Tags.prototype._removeOldTags = function (_) { + var tag = this._lastTag; + + var $options = this.$element.find('option[data-select2-tag]'); + + $options.each(function () { + if (this.selected) { + return; + } + + $(this).remove(); + }); + }; + + return Tags; +}); + +S2.define('select2/data/tokenizer',[ + 'jquery' +], function ($) { + function Tokenizer (decorated, $element, options) { + var tokenizer = options.get('tokenizer'); + + if (tokenizer !== undefined) { + this.tokenizer = tokenizer; + } + + decorated.call(this, $element, options); + } + + Tokenizer.prototype.bind = function (decorated, container, $container) { + decorated.call(this, container, $container); + + this.$search = container.dropdown.$search || container.selection.$search || + $container.find('.select2-search__field'); + }; + + Tokenizer.prototype.query = function (decorated, params, callback) { + var self = this; + + function createAndSelect (data) { + // Normalize the data object so we can use it for checks + var item = self._normalizeItem(data); + + // Check if the data object already exists as a tag + // Select it if it doesn't + var $existingOptions = self.$element.find('option').filter(function () { + return $(this).val() === item.id; + }); + + // If an existing option wasn't found for it, create the option + if (!$existingOptions.length) { + var $option = self.option(item); + $option.attr('data-select2-tag', true); + + self._removeOldTags(); + self.addOptions([$option]); + } + + // Select the item, now that we know there is an option for it + select(item); + } + + function select (data) { + self.trigger('select', { + data: data + }); + } + + params.term = params.term || ''; + + var tokenData = this.tokenizer(params, this.options, createAndSelect); + + if (tokenData.term !== params.term) { + // Replace the search term if we have the search box + if (this.$search.length) { + this.$search.val(tokenData.term); + this.$search.focus(); + } + + params.term = tokenData.term; + } + + decorated.call(this, params, callback); + }; + + Tokenizer.prototype.tokenizer = function (_, params, options, callback) { + var separators = options.get('tokenSeparators') || []; + var term = params.term; + var i = 0; + + var createTag = this.createTag || function (params) { + return { + id: params.term, + text: params.term + }; + }; + + while (i < term.length) { + var termChar = term[i]; + + if ($.inArray(termChar, separators) === -1) { + i++; + + continue; + } + + var part = term.substr(0, i); + var partParams = $.extend({}, params, { + term: part + }); + + var data = createTag(partParams); + + if (data == null) { + i++; + continue; + } + + callback(data); + + // Reset the term to not include the tokenized portion + term = term.substr(i + 1) || ''; + i = 0; + } + + return { + term: term + }; + }; + + return Tokenizer; +}); + +S2.define('select2/data/minimumInputLength',[ + +], function () { + function MinimumInputLength (decorated, $e, options) { + this.minimumInputLength = options.get('minimumInputLength'); + + decorated.call(this, $e, options); + } + + MinimumInputLength.prototype.query = function (decorated, params, callback) { + params.term = params.term || ''; + + if (params.term.length < this.minimumInputLength) { + this.trigger('results:message', { + message: 'inputTooShort', + args: { + minimum: this.minimumInputLength, + input: params.term, + params: params + } + }); + + return; + } + + decorated.call(this, params, callback); + }; + + return MinimumInputLength; +}); + +S2.define('select2/data/maximumInputLength',[ + +], function () { + function MaximumInputLength (decorated, $e, options) { + this.maximumInputLength = options.get('maximumInputLength'); + + decorated.call(this, $e, options); + } + + MaximumInputLength.prototype.query = function (decorated, params, callback) { + params.term = params.term || ''; + + if (this.maximumInputLength > 0 && + params.term.length > this.maximumInputLength) { + this.trigger('results:message', { + message: 'inputTooLong', + args: { + maximum: this.maximumInputLength, + input: params.term, + params: params + } + }); + + return; + } + + decorated.call(this, params, callback); + }; + + return MaximumInputLength; +}); + +S2.define('select2/data/maximumSelectionLength',[ + +], function (){ + function MaximumSelectionLength (decorated, $e, options) { + this.maximumSelectionLength = options.get('maximumSelectionLength'); + + decorated.call(this, $e, options); + } + + MaximumSelectionLength.prototype.query = + function (decorated, params, callback) { + var self = this; + + this.current(function (currentData) { + var count = currentData != null ? currentData.length : 0; + if (self.maximumSelectionLength > 0 && + count >= self.maximumSelectionLength) { + self.trigger('results:message', { + message: 'maximumSelected', + args: { + maximum: self.maximumSelectionLength + } + }); + return; + } + decorated.call(self, params, callback); + }); + }; + + return MaximumSelectionLength; +}); + +S2.define('select2/dropdown',[ + 'jquery', + './utils' +], function ($, Utils) { + function Dropdown ($element, options) { + this.$element = $element; + this.options = options; + + Dropdown.__super__.constructor.call(this); + } + + Utils.Extend(Dropdown, Utils.Observable); + + Dropdown.prototype.render = function () { + var $dropdown = $( + '' + + '' + + '' + ); + + $dropdown.attr('dir', this.options.get('dir')); + + this.$dropdown = $dropdown; + + return $dropdown; + }; + + Dropdown.prototype.bind = function () { + // Should be implemented in subclasses + }; + + Dropdown.prototype.position = function ($dropdown, $container) { + // Should be implemented in subclasses + }; + + Dropdown.prototype.destroy = function () { + // Remove the dropdown from the DOM + this.$dropdown.remove(); + }; + + return Dropdown; +}); + +S2.define('select2/dropdown/search',[ + 'jquery', + '../utils' +], function ($, Utils) { + function Search () { } + + Search.prototype.render = function (decorated) { + var $rendered = decorated.call(this); + + var $search = $( + '' + + '' + + '' + ); + + this.$searchContainer = $search; + this.$search = $search.find('input'); + + $rendered.prepend($search); + + return $rendered; + }; + + Search.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + this.$search.on('keydown', function (evt) { + self.trigger('keypress', evt); + + self._keyUpPrevented = evt.isDefaultPrevented(); + }); + + // Workaround for browsers which do not support the `input` event + // This will prevent double-triggering of events for browsers which support + // both the `keyup` and `input` events. + this.$search.on('input', function (evt) { + // Unbind the duplicated `keyup` event + $(this).off('keyup'); + }); + + this.$search.on('keyup input', function (evt) { + self.handleSearch(evt); + }); + + container.on('open', function () { + self.$search.attr('tabindex', 0); + + self.$search.focus(); + + window.setTimeout(function () { + self.$search.focus(); + }, 0); + }); + + container.on('close', function () { + self.$search.attr('tabindex', -1); + + self.$search.val(''); + self.$search.blur(); + }); + + container.on('focus', function () { + if (!container.isOpen()) { + self.$search.focus(); + } + }); + + container.on('results:all', function (params) { + if (params.query.term == null || params.query.term === '') { + var showSearch = self.showSearch(params); + + if (showSearch) { + self.$searchContainer.removeClass('select2-search--hide'); + } else { + self.$searchContainer.addClass('select2-search--hide'); + } + } + }); + }; + + Search.prototype.handleSearch = function (evt) { + if (!this._keyUpPrevented) { + var input = this.$search.val(); + + this.trigger('query', { + term: input + }); + } + + this._keyUpPrevented = false; + }; + + Search.prototype.showSearch = function (_, params) { + return true; + }; + + return Search; +}); + +S2.define('select2/dropdown/hidePlaceholder',[ + +], function () { + function HidePlaceholder (decorated, $element, options, dataAdapter) { + this.placeholder = this.normalizePlaceholder(options.get('placeholder')); + + decorated.call(this, $element, options, dataAdapter); + } + + HidePlaceholder.prototype.append = function (decorated, data) { + data.results = this.removePlaceholder(data.results); + + decorated.call(this, data); + }; + + HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) { + if (typeof placeholder === 'string') { + placeholder = { + id: '', + text: placeholder + }; + } + + return placeholder; + }; + + HidePlaceholder.prototype.removePlaceholder = function (_, data) { + var modifiedData = data.slice(0); + + for (var d = data.length - 1; d >= 0; d--) { + var item = data[d]; + + if (this.placeholder.id === item.id) { + modifiedData.splice(d, 1); + } + } + + return modifiedData; + }; + + return HidePlaceholder; +}); + +S2.define('select2/dropdown/infiniteScroll',[ + 'jquery' +], function ($) { + function InfiniteScroll (decorated, $element, options, dataAdapter) { + this.lastParams = {}; + + decorated.call(this, $element, options, dataAdapter); + + this.$loadingMore = this.createLoadingMore(); + this.loading = false; + } + + InfiniteScroll.prototype.append = function (decorated, data) { + this.$loadingMore.remove(); + this.loading = false; + + decorated.call(this, data); + + if (this.showLoadingMore(data)) { + this.$results.append(this.$loadingMore); + } + }; + + InfiniteScroll.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('query', function (params) { + self.lastParams = params; + self.loading = true; + }); + + container.on('query:append', function (params) { + self.lastParams = params; + self.loading = true; + }); + + this.$results.on('scroll', function () { + var isLoadMoreVisible = $.contains( + document.documentElement, + self.$loadingMore[0] + ); + + if (self.loading || !isLoadMoreVisible) { + return; + } + + var currentOffset = self.$results.offset().top + + self.$results.outerHeight(false); + var loadingMoreOffset = self.$loadingMore.offset().top + + self.$loadingMore.outerHeight(false); + + if (currentOffset + 50 >= loadingMoreOffset) { + self.loadMore(); + } + }); + }; + + InfiniteScroll.prototype.loadMore = function () { + this.loading = true; + + var params = $.extend({}, {page: 1}, this.lastParams); + + params.page++; + + this.trigger('query:append', params); + }; + + InfiniteScroll.prototype.showLoadingMore = function (_, data) { + return data.pagination && data.pagination.more; + }; + + InfiniteScroll.prototype.createLoadingMore = function () { + var $option = $( + '
      • ' + ); + + var message = this.options.get('translations').get('loadingMore'); + + $option.html(message(this.lastParams)); + + return $option; + }; + + return InfiniteScroll; +}); + +S2.define('select2/dropdown/attachBody',[ + 'jquery', + '../utils' +], function ($, Utils) { + function AttachBody (decorated, $element, options) { + this.$dropdownParent = options.get('dropdownParent') || $(document.body); + + decorated.call(this, $element, options); + } + + AttachBody.prototype.bind = function (decorated, container, $container) { + var self = this; + + var setupResultsEvents = false; + + decorated.call(this, container, $container); + + container.on('open', function () { + self._showDropdown(); + self._attachPositioningHandler(container); + + if (!setupResultsEvents) { + setupResultsEvents = true; + + container.on('results:all', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:append', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + } + }); + + container.on('close', function () { + self._hideDropdown(); + self._detachPositioningHandler(container); + }); + + this.$dropdownContainer.on('mousedown', function (evt) { + evt.stopPropagation(); + }); + }; + + AttachBody.prototype.destroy = function (decorated) { + decorated.call(this); + + this.$dropdownContainer.remove(); + }; + + AttachBody.prototype.position = function (decorated, $dropdown, $container) { + // Clone all of the container classes + $dropdown.attr('class', $container.attr('class')); + + $dropdown.removeClass('select2'); + $dropdown.addClass('select2-container--open'); + + $dropdown.css({ + position: 'absolute', + top: -999999 + }); + + this.$container = $container; + }; + + AttachBody.prototype.render = function (decorated) { + var $container = $(''); + + var $dropdown = decorated.call(this); + $container.append($dropdown); + + this.$dropdownContainer = $container; + + return $container; + }; + + AttachBody.prototype._hideDropdown = function (decorated) { + this.$dropdownContainer.detach(); + }; + + AttachBody.prototype._attachPositioningHandler = + function (decorated, container) { + var self = this; + + var scrollEvent = 'scroll.select2.' + container.id; + var resizeEvent = 'resize.select2.' + container.id; + var orientationEvent = 'orientationchange.select2.' + container.id; + + var $watchers = this.$container.parents().filter(Utils.hasScroll); + $watchers.each(function () { + Utils.StoreData(this, 'select2-scroll-position', { + x: $(this).scrollLeft(), + y: $(this).scrollTop() + }); + }); + + $watchers.on(scrollEvent, function (ev) { + var position = Utils.GetData(this, 'select2-scroll-position'); + $(this).scrollTop(position.y); + }); + + $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent, + function (e) { + self._positionDropdown(); + self._resizeDropdown(); + }); + }; + + AttachBody.prototype._detachPositioningHandler = + function (decorated, container) { + var scrollEvent = 'scroll.select2.' + container.id; + var resizeEvent = 'resize.select2.' + container.id; + var orientationEvent = 'orientationchange.select2.' + container.id; + + var $watchers = this.$container.parents().filter(Utils.hasScroll); + $watchers.off(scrollEvent); + + $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent); + }; + + AttachBody.prototype._positionDropdown = function () { + var $window = $(window); + + var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above'); + var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below'); + + var newDirection = null; + + var offset = this.$container.offset(); + + offset.bottom = offset.top + this.$container.outerHeight(false); + + var container = { + height: this.$container.outerHeight(false) + }; + + container.top = offset.top; + container.bottom = offset.top + container.height; + + var dropdown = { + height: this.$dropdown.outerHeight(false) + }; + + var viewport = { + top: $window.scrollTop(), + bottom: $window.scrollTop() + $window.height() + }; + + var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); + var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); + + var css = { + left: offset.left, + top: container.bottom + }; + + // Determine what the parent element is to use for calculating the offset + var $offsetParent = this.$dropdownParent; + + // For statically positioned elements, we need to get the element + // that is determining the offset + if ($offsetParent.css('position') === 'static') { + $offsetParent = $offsetParent.offsetParent(); + } + + var parentOffset = $offsetParent.offset(); + + css.top -= parentOffset.top; + css.left -= parentOffset.left; + + if (!isCurrentlyAbove && !isCurrentlyBelow) { + newDirection = 'below'; + } + + if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { + newDirection = 'above'; + } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { + newDirection = 'below'; + } + + if (newDirection == 'above' || + (isCurrentlyAbove && newDirection !== 'below')) { + css.top = container.top - parentOffset.top - dropdown.height; + } + + if (newDirection != null) { + this.$dropdown + .removeClass('select2-dropdown--below select2-dropdown--above') + .addClass('select2-dropdown--' + newDirection); + this.$container + .removeClass('select2-container--below select2-container--above') + .addClass('select2-container--' + newDirection); + } + + this.$dropdownContainer.css(css); + }; + + AttachBody.prototype._resizeDropdown = function () { + var css = { + width: this.$container.outerWidth(false) + 'px' + }; + + if (this.options.get('dropdownAutoWidth')) { + css.minWidth = css.width; + css.position = 'relative'; + css.width = 'auto'; + } + + this.$dropdown.css(css); + }; + + AttachBody.prototype._showDropdown = function (decorated) { + this.$dropdownContainer.appendTo(this.$dropdownParent); + + this._positionDropdown(); + this._resizeDropdown(); + }; + + return AttachBody; +}); + +S2.define('select2/dropdown/minimumResultsForSearch',[ + +], function () { + function countResults (data) { + var count = 0; + + for (var d = 0; d < data.length; d++) { + var item = data[d]; + + if (item.children) { + count += countResults(item.children); + } else { + count++; + } + } + + return count; + } + + function MinimumResultsForSearch (decorated, $element, options, dataAdapter) { + this.minimumResultsForSearch = options.get('minimumResultsForSearch'); + + if (this.minimumResultsForSearch < 0) { + this.minimumResultsForSearch = Infinity; + } + + decorated.call(this, $element, options, dataAdapter); + } + + MinimumResultsForSearch.prototype.showSearch = function (decorated, params) { + if (countResults(params.data.results) < this.minimumResultsForSearch) { + return false; + } + + return decorated.call(this, params); + }; + + return MinimumResultsForSearch; +}); + +S2.define('select2/dropdown/selectOnClose',[ + '../utils' +], function (Utils) { + function SelectOnClose () { } + + SelectOnClose.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('close', function (params) { + self._handleSelectOnClose(params); + }); + }; + + SelectOnClose.prototype._handleSelectOnClose = function (_, params) { + if (params && params.originalSelect2Event != null) { + var event = params.originalSelect2Event; + + // Don't select an item if the close event was triggered from a select or + // unselect event + if (event._type === 'select' || event._type === 'unselect') { + return; + } + } + + var $highlightedResults = this.getHighlightedResults(); + + // Only select highlighted results + if ($highlightedResults.length < 1) { + return; + } + + var data = Utils.GetData($highlightedResults[0], 'data'); + + // Don't re-select already selected resulte + if ( + (data.element != null && data.element.selected) || + (data.element == null && data.selected) + ) { + return; + } + + this.trigger('select', { + data: data + }); + }; + + return SelectOnClose; +}); + +S2.define('select2/dropdown/closeOnSelect',[ + +], function () { + function CloseOnSelect () { } + + CloseOnSelect.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('select', function (evt) { + self._selectTriggered(evt); + }); + + container.on('unselect', function (evt) { + self._selectTriggered(evt); + }); + }; + + CloseOnSelect.prototype._selectTriggered = function (_, evt) { + var originalEvent = evt.originalEvent; + + // Don't close if the control key is being held + if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) { + return; + } + + this.trigger('close', { + originalEvent: originalEvent, + originalSelect2Event: evt + }); + }; + + return CloseOnSelect; +}); + +S2.define('select2/i18n/en',[],function () { + // English + return { + errorLoading: function () { + return 'The results could not be loaded.'; + }, + inputTooLong: function (args) { + var overChars = args.input.length - args.maximum; + + var message = 'Please delete ' + overChars + ' character'; + + if (overChars != 1) { + message += 's'; + } + + return message; + }, + inputTooShort: function (args) { + var remainingChars = args.minimum - args.input.length; + + var message = 'Please enter ' + remainingChars + ' or more characters'; + + return message; + }, + loadingMore: function () { + return 'Loading more results…'; + }, + maximumSelected: function (args) { + var message = 'You can only select ' + args.maximum + ' item'; + + if (args.maximum != 1) { + message += 's'; + } + + return message; + }, + noResults: function () { + return 'No results found'; + }, + searching: function () { + return 'Searching…'; + }, + removeAllItems: function () { + return 'Remove all items'; + } + }; +}); + +S2.define('select2/defaults',[ + 'jquery', + 'require', + + './results', + + './selection/single', + './selection/multiple', + './selection/placeholder', + './selection/allowClear', + './selection/search', + './selection/eventRelay', + + './utils', + './translation', + './diacritics', + + './data/select', + './data/array', + './data/ajax', + './data/tags', + './data/tokenizer', + './data/minimumInputLength', + './data/maximumInputLength', + './data/maximumSelectionLength', + + './dropdown', + './dropdown/search', + './dropdown/hidePlaceholder', + './dropdown/infiniteScroll', + './dropdown/attachBody', + './dropdown/minimumResultsForSearch', + './dropdown/selectOnClose', + './dropdown/closeOnSelect', + + './i18n/en' +], function ($, require, + + ResultsList, + + SingleSelection, MultipleSelection, Placeholder, AllowClear, + SelectionSearch, EventRelay, + + Utils, Translation, DIACRITICS, + + SelectData, ArrayData, AjaxData, Tags, Tokenizer, + MinimumInputLength, MaximumInputLength, MaximumSelectionLength, + + Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, + AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect, + + EnglishTranslation) { + function Defaults () { + this.reset(); + } + + Defaults.prototype.apply = function (options) { + options = $.extend(true, {}, this.defaults, options); + + if (options.dataAdapter == null) { + if (options.ajax != null) { + options.dataAdapter = AjaxData; + } else if (options.data != null) { + options.dataAdapter = ArrayData; + } else { + options.dataAdapter = SelectData; + } + + if (options.minimumInputLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MinimumInputLength + ); + } + + if (options.maximumInputLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MaximumInputLength + ); + } + + if (options.maximumSelectionLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MaximumSelectionLength + ); + } + + if (options.tags) { + options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags); + } + + if (options.tokenSeparators != null || options.tokenizer != null) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + Tokenizer + ); + } + + if (options.query != null) { + var Query = require(options.amdBase + 'compat/query'); + + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + Query + ); + } + + if (options.initSelection != null) { + var InitSelection = require(options.amdBase + 'compat/initSelection'); + + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + InitSelection + ); + } + } + + if (options.resultsAdapter == null) { + options.resultsAdapter = ResultsList; + + if (options.ajax != null) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + InfiniteScroll + ); + } + + if (options.placeholder != null) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + HidePlaceholder + ); + } + + if (options.selectOnClose) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + SelectOnClose + ); + } + } + + if (options.dropdownAdapter == null) { + if (options.multiple) { + options.dropdownAdapter = Dropdown; + } else { + var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch); + + options.dropdownAdapter = SearchableDropdown; + } + + if (options.minimumResultsForSearch !== 0) { + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + MinimumResultsForSearch + ); + } + + if (options.closeOnSelect) { + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + CloseOnSelect + ); + } + + if ( + options.dropdownCssClass != null || + options.dropdownCss != null || + options.adaptDropdownCssClass != null + ) { + var DropdownCSS = require(options.amdBase + 'compat/dropdownCss'); + + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + DropdownCSS + ); + } + + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + AttachBody + ); + } + + if (options.selectionAdapter == null) { + if (options.multiple) { + options.selectionAdapter = MultipleSelection; + } else { + options.selectionAdapter = SingleSelection; + } + + // Add the placeholder mixin if a placeholder was specified + if (options.placeholder != null) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + Placeholder + ); + } + + if (options.allowClear) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + AllowClear + ); + } + + if (options.multiple) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + SelectionSearch + ); + } + + if ( + options.containerCssClass != null || + options.containerCss != null || + options.adaptContainerCssClass != null + ) { + var ContainerCSS = require(options.amdBase + 'compat/containerCss'); + + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + ContainerCSS + ); + } + + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + EventRelay + ); + } + + if (typeof options.language === 'string') { + // Check if the language is specified with a region + if (options.language.indexOf('-') > 0) { + // Extract the region information if it is included + var languageParts = options.language.split('-'); + var baseLanguage = languageParts[0]; + + options.language = [options.language, baseLanguage]; + } else { + options.language = [options.language]; + } + } + + if ($.isArray(options.language)) { + var languages = new Translation(); + options.language.push('en'); + + var languageNames = options.language; + + for (var l = 0; l < languageNames.length; l++) { + var name = languageNames[l]; + var language = {}; + + try { + // Try to load it with the original name + language = Translation.loadPath(name); + } catch (e) { + try { + // If we couldn't load it, check if it wasn't the full path + name = this.defaults.amdLanguageBase + name; + language = Translation.loadPath(name); + } catch (ex) { + // The translation could not be loaded at all. Sometimes this is + // because of a configuration problem, other times this can be + // because of how Select2 helps load all possible translation files. + if (options.debug && window.console && console.warn) { + console.warn( + 'Select2: The language file for "' + name + '" could not be ' + + 'automatically loaded. A fallback will be used instead.' + ); + } + + continue; + } + } + + languages.extend(language); + } + + options.translations = languages; + } else { + var baseTranslation = Translation.loadPath( + this.defaults.amdLanguageBase + 'en' + ); + var customTranslation = new Translation(options.language); + + customTranslation.extend(baseTranslation); + + options.translations = customTranslation; + } + + return options; + }; + + Defaults.prototype.reset = function () { + function stripDiacritics (text) { + // Used 'uni range + named function' from http://jsperf.com/diacritics/18 + function match(a) { + return DIACRITICS[a] || a; + } + + return text.replace(/[^\u0000-\u007E]/g, match); + } + + function matcher (params, data) { + // Always return the object if there is nothing to compare + if ($.trim(params.term) === '') { + return data; + } + + // Do a recursive check for options with children + if (data.children && data.children.length > 0) { + // Clone the data object if there are children + // This is required as we modify the object to remove any non-matches + var match = $.extend(true, {}, data); + + // Check each child of the option + for (var c = data.children.length - 1; c >= 0; c--) { + var child = data.children[c]; + + var matches = matcher(params, child); + + // If there wasn't a match, remove the object in the array + if (matches == null) { + match.children.splice(c, 1); + } + } + + // If any children matched, return the new object + if (match.children.length > 0) { + return match; + } + + // If there were no matching children, check just the plain object + return matcher(params, match); + } + + var original = stripDiacritics(data.text).toUpperCase(); + var term = stripDiacritics(params.term).toUpperCase(); + + // Check if the text contains the term + if (original.indexOf(term) > -1) { + return data; + } + + // If it doesn't contain the term, don't return anything + return null; + } + + this.defaults = { + amdBase: './', + amdLanguageBase: './i18n/', + closeOnSelect: true, + debug: false, + dropdownAutoWidth: false, + escapeMarkup: Utils.escapeMarkup, + language: EnglishTranslation, + matcher: matcher, + minimumInputLength: 0, + maximumInputLength: 0, + maximumSelectionLength: 0, + minimumResultsForSearch: 0, + selectOnClose: false, + scrollAfterSelect: false, + sorter: function (data) { + return data; + }, + templateResult: function (result) { + return result.text; + }, + templateSelection: function (selection) { + return selection.text; + }, + theme: 'default', + width: 'resolve' + }; + }; + + Defaults.prototype.set = function (key, value) { + var camelKey = $.camelCase(key); + + var data = {}; + data[camelKey] = value; + + var convertedData = Utils._convertData(data); + + $.extend(true, this.defaults, convertedData); + }; + + var defaults = new Defaults(); + + return defaults; +}); + +S2.define('select2/options',[ + 'require', + 'jquery', + './defaults', + './utils' +], function (require, $, Defaults, Utils) { + function Options (options, $element) { + this.options = options; + + if ($element != null) { + this.fromElement($element); + } + + this.options = Defaults.apply(this.options); + + if ($element && $element.is('input')) { + var InputCompat = require(this.get('amdBase') + 'compat/inputData'); + + this.options.dataAdapter = Utils.Decorate( + this.options.dataAdapter, + InputCompat + ); + } + } + + Options.prototype.fromElement = function ($e) { + var excludedData = ['select2']; + + if (this.options.multiple == null) { + this.options.multiple = $e.prop('multiple'); + } + + if (this.options.disabled == null) { + this.options.disabled = $e.prop('disabled'); + } + + if (this.options.language == null) { + if ($e.prop('lang')) { + this.options.language = $e.prop('lang').toLowerCase(); + } else if ($e.closest('[lang]').prop('lang')) { + this.options.language = $e.closest('[lang]').prop('lang'); + } + } + + if (this.options.dir == null) { + if ($e.prop('dir')) { + this.options.dir = $e.prop('dir'); + } else if ($e.closest('[dir]').prop('dir')) { + this.options.dir = $e.closest('[dir]').prop('dir'); + } else { + this.options.dir = 'ltr'; + } + } + + $e.prop('disabled', this.options.disabled); + $e.prop('multiple', this.options.multiple); + + if (Utils.GetData($e[0], 'select2Tags')) { + if (this.options.debug && window.console && console.warn) { + console.warn( + 'Select2: The `data-select2-tags` attribute has been changed to ' + + 'use the `data-data` and `data-tags="true"` attributes and will be ' + + 'removed in future versions of Select2.' + ); + } + + Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); + Utils.StoreData($e[0], 'tags', true); + } + + if (Utils.GetData($e[0], 'ajaxUrl')) { + if (this.options.debug && window.console && console.warn) { + console.warn( + 'Select2: The `data-ajax-url` attribute has been changed to ' + + '`data-ajax--url` and support for the old attribute will be removed' + + ' in future versions of Select2.' + ); + } + + $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); + Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); + } + + var dataset = {}; + + function upperCaseLetter(_, letter) { + return letter.toUpperCase(); + } + + // Pre-load all of the attributes which are prefixed with `data-` + for (var attr = 0; attr < $e[0].attributes.length; attr++) { + var attributeName = $e[0].attributes[attr].name; + var prefix = 'data-'; + + if (attributeName.substr(0, prefix.length) == prefix) { + // Get the contents of the attribute after `data-` + var dataName = attributeName.substring(prefix.length); + + // Get the data contents from the consistent source + // This is more than likely the jQuery data helper + var dataValue = Utils.GetData($e[0], dataName); + + // camelCase the attribute name to match the spec + var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter); + + // Store the data attribute contents into the dataset since + dataset[camelDataName] = dataValue; + } + } + + // Prefer the element's `dataset` attribute if it exists + // jQuery 1.x does not correctly handle data attributes with multiple dashes + if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { + dataset = $.extend(true, {}, $e[0].dataset, dataset); + } + + // Prefer our internal data cache if it exists + var data = $.extend(true, {}, Utils.GetData($e[0]), dataset); + + data = Utils._convertData(data); + + for (var key in data) { + if ($.inArray(key, excludedData) > -1) { + continue; + } + + if ($.isPlainObject(this.options[key])) { + $.extend(this.options[key], data[key]); + } else { + this.options[key] = data[key]; + } + } + + return this; + }; + + Options.prototype.get = function (key) { + return this.options[key]; + }; + + Options.prototype.set = function (key, val) { + this.options[key] = val; + }; + + return Options; +}); + +S2.define('select2/core',[ + 'jquery', + './options', + './utils', + './keys' +], function ($, Options, Utils, KEYS) { + var Select2 = function ($element, options) { + if (Utils.GetData($element[0], 'select2') != null) { + Utils.GetData($element[0], 'select2').destroy(); + } + + this.$element = $element; + + this.id = this._generateId($element); + + options = options || {}; + + this.options = new Options(options, $element); + + Select2.__super__.constructor.call(this); + + // Set up the tabindex + + var tabindex = $element.attr('tabindex') || 0; + Utils.StoreData($element[0], 'old-tabindex', tabindex); + $element.attr('tabindex', '-1'); + + // Set up containers and adapters + + var DataAdapter = this.options.get('dataAdapter'); + this.dataAdapter = new DataAdapter($element, this.options); + + var $container = this.render(); + + this._placeContainer($container); + + var SelectionAdapter = this.options.get('selectionAdapter'); + this.selection = new SelectionAdapter($element, this.options); + this.$selection = this.selection.render(); + + this.selection.position(this.$selection, $container); + + var DropdownAdapter = this.options.get('dropdownAdapter'); + this.dropdown = new DropdownAdapter($element, this.options); + this.$dropdown = this.dropdown.render(); + + this.dropdown.position(this.$dropdown, $container); + + var ResultsAdapter = this.options.get('resultsAdapter'); + this.results = new ResultsAdapter($element, this.options, this.dataAdapter); + this.$results = this.results.render(); + + this.results.position(this.$results, this.$dropdown); + + // Bind events + + var self = this; + + // Bind the container to all of the adapters + this._bindAdapters(); + + // Register any DOM event handlers + this._registerDomEvents(); + + // Register any internal event handlers + this._registerDataEvents(); + this._registerSelectionEvents(); + this._registerDropdownEvents(); + this._registerResultsEvents(); + this._registerEvents(); + + // Set the initial state + this.dataAdapter.current(function (initialData) { + self.trigger('selection:update', { + data: initialData + }); + }); + + // Hide the original select + $element.addClass('select2-hidden-accessible'); + $element.attr('aria-hidden', 'true'); + + // Synchronize any monitored attributes + this._syncAttributes(); + + Utils.StoreData($element[0], 'select2', this); + + // Ensure backwards compatibility with $element.data('select2'). + $element.data('select2', this); + }; + + Utils.Extend(Select2, Utils.Observable); + + Select2.prototype._generateId = function ($element) { + var id = ''; + + if ($element.attr('id') != null) { + id = $element.attr('id'); + } else if ($element.attr('name') != null) { + id = $element.attr('name') + '-' + Utils.generateChars(2); + } else { + id = Utils.generateChars(4); + } + + id = id.replace(/(:|\.|\[|\]|,)/g, ''); + id = 'select2-' + id; + + return id; + }; + + Select2.prototype._placeContainer = function ($container) { + $container.insertAfter(this.$element); + + var width = this._resolveWidth(this.$element, this.options.get('width')); + + if (width != null) { + $container.css('width', width); + } + }; + + Select2.prototype._resolveWidth = function ($element, method) { + var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; + + if (method == 'resolve') { + var styleWidth = this._resolveWidth($element, 'style'); + + if (styleWidth != null) { + return styleWidth; + } + + return this._resolveWidth($element, 'element'); + } + + if (method == 'element') { + var elementWidth = $element.outerWidth(false); + + if (elementWidth <= 0) { + return 'auto'; + } + + return elementWidth + 'px'; + } + + if (method == 'style') { + var style = $element.attr('style'); + + if (typeof(style) !== 'string') { + return null; + } + + var attrs = style.split(';'); + + for (var i = 0, l = attrs.length; i < l; i = i + 1) { + var attr = attrs[i].replace(/\s/g, ''); + var matches = attr.match(WIDTH); + + if (matches !== null && matches.length >= 1) { + return matches[1]; + } + } + + return null; + } + + return method; + }; + + Select2.prototype._bindAdapters = function () { + this.dataAdapter.bind(this, this.$container); + this.selection.bind(this, this.$container); + + this.dropdown.bind(this, this.$container); + this.results.bind(this, this.$container); + }; + + Select2.prototype._registerDomEvents = function () { + var self = this; + + this.$element.on('change.select2', function () { + self.dataAdapter.current(function (data) { + self.trigger('selection:update', { + data: data + }); + }); + }); + + this.$element.on('focus.select2', function (evt) { + self.trigger('focus', evt); + }); + + this._syncA = Utils.bind(this._syncAttributes, this); + this._syncS = Utils.bind(this._syncSubtree, this); + + if (this.$element[0].attachEvent) { + this.$element[0].attachEvent('onpropertychange', this._syncA); + } + + var observer = window.MutationObserver || + window.WebKitMutationObserver || + window.MozMutationObserver + ; + + if (observer != null) { + this._observer = new observer(function (mutations) { + $.each(mutations, self._syncA); + $.each(mutations, self._syncS); + }); + this._observer.observe(this.$element[0], { + attributes: true, + childList: true, + subtree: false + }); + } else if (this.$element[0].addEventListener) { + this.$element[0].addEventListener( + 'DOMAttrModified', + self._syncA, + false + ); + this.$element[0].addEventListener( + 'DOMNodeInserted', + self._syncS, + false + ); + this.$element[0].addEventListener( + 'DOMNodeRemoved', + self._syncS, + false + ); + } + }; + + Select2.prototype._registerDataEvents = function () { + var self = this; + + this.dataAdapter.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerSelectionEvents = function () { + var self = this; + var nonRelayEvents = ['toggle', 'focus']; + + this.selection.on('toggle', function () { + self.toggleDropdown(); + }); + + this.selection.on('focus', function (params) { + self.focus(params); + }); + + this.selection.on('*', function (name, params) { + if ($.inArray(name, nonRelayEvents) !== -1) { + return; + } + + self.trigger(name, params); + }); + }; + + Select2.prototype._registerDropdownEvents = function () { + var self = this; + + this.dropdown.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerResultsEvents = function () { + var self = this; + + this.results.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerEvents = function () { + var self = this; + + this.on('open', function () { + self.$container.addClass('select2-container--open'); + }); + + this.on('close', function () { + self.$container.removeClass('select2-container--open'); + }); + + this.on('enable', function () { + self.$container.removeClass('select2-container--disabled'); + }); + + this.on('disable', function () { + self.$container.addClass('select2-container--disabled'); + }); + + this.on('blur', function () { + self.$container.removeClass('select2-container--focus'); + }); + + this.on('query', function (params) { + if (!self.isOpen()) { + self.trigger('open', {}); + } + + this.dataAdapter.query(params, function (data) { + self.trigger('results:all', { + data: data, + query: params + }); + }); + }); + + this.on('query:append', function (params) { + this.dataAdapter.query(params, function (data) { + self.trigger('results:append', { + data: data, + query: params + }); + }); + }); + + this.on('keypress', function (evt) { + var key = evt.which; + + if (self.isOpen()) { + if (key === KEYS.ESC || key === KEYS.TAB || + (key === KEYS.UP && evt.altKey)) { + self.close(); + + evt.preventDefault(); + } else if (key === KEYS.ENTER) { + self.trigger('results:select', {}); + + evt.preventDefault(); + } else if ((key === KEYS.SPACE && evt.ctrlKey)) { + self.trigger('results:toggle', {}); + + evt.preventDefault(); + } else if (key === KEYS.UP) { + self.trigger('results:previous', {}); + + evt.preventDefault(); + } else if (key === KEYS.DOWN) { + self.trigger('results:next', {}); + + evt.preventDefault(); + } + } else { + if (key === KEYS.ENTER || key === KEYS.SPACE || + (key === KEYS.DOWN && evt.altKey)) { + self.open(); + + evt.preventDefault(); + } + } + }); + }; + + Select2.prototype._syncAttributes = function () { + this.options.set('disabled', this.$element.prop('disabled')); + + if (this.options.get('disabled')) { + if (this.isOpen()) { + this.close(); + } + + this.trigger('disable', {}); + } else { + this.trigger('enable', {}); + } + }; + + Select2.prototype._syncSubtree = function (evt, mutations) { + var changed = false; + var self = this; + + // Ignore any mutation events raised for elements that aren't options or + // optgroups. This handles the case when the select element is destroyed + if ( + evt && evt.target && ( + evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP' + ) + ) { + return; + } + + if (!mutations) { + // If mutation events aren't supported, then we can only assume that the + // change affected the selections + changed = true; + } else if (mutations.addedNodes && mutations.addedNodes.length > 0) { + for (var n = 0; n < mutations.addedNodes.length; n++) { + var node = mutations.addedNodes[n]; + + if (node.selected) { + changed = true; + } + } + } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { + changed = true; + } + + // Only re-pull the data if we think there is a change + if (changed) { + this.dataAdapter.current(function (currentData) { + self.trigger('selection:update', { + data: currentData + }); + }); + } + }; + + /** + * Override the trigger method to automatically trigger pre-events when + * there are events that can be prevented. + */ + Select2.prototype.trigger = function (name, args) { + var actualTrigger = Select2.__super__.trigger; + var preTriggerMap = { + 'open': 'opening', + 'close': 'closing', + 'select': 'selecting', + 'unselect': 'unselecting', + 'clear': 'clearing' + }; + + if (args === undefined) { + args = {}; + } + + if (name in preTriggerMap) { + var preTriggerName = preTriggerMap[name]; + var preTriggerArgs = { + prevented: false, + name: name, + args: args + }; + + actualTrigger.call(this, preTriggerName, preTriggerArgs); + + if (preTriggerArgs.prevented) { + args.prevented = true; + + return; + } + } + + actualTrigger.call(this, name, args); + }; + + Select2.prototype.toggleDropdown = function () { + if (this.options.get('disabled')) { + return; + } + + if (this.isOpen()) { + this.close(); + } else { + this.open(); + } + }; + + Select2.prototype.open = function () { + if (this.isOpen()) { + return; + } + + this.trigger('query', {}); + }; + + Select2.prototype.close = function () { + if (!this.isOpen()) { + return; + } + + this.trigger('close', {}); + }; + + Select2.prototype.isOpen = function () { + return this.$container.hasClass('select2-container--open'); + }; + + Select2.prototype.hasFocus = function () { + return this.$container.hasClass('select2-container--focus'); + }; + + Select2.prototype.focus = function (data) { + // No need to re-trigger focus events if we are already focused + if (this.hasFocus()) { + return; + } + + this.$container.addClass('select2-container--focus'); + this.trigger('focus', {}); + }; + + Select2.prototype.enable = function (args) { + if (this.options.get('debug') && window.console && console.warn) { + console.warn( + 'Select2: The `select2("enable")` method has been deprecated and will' + + ' be removed in later Select2 versions. Use $element.prop("disabled")' + + ' instead.' + ); + } + + if (args == null || args.length === 0) { + args = [true]; + } + + var disabled = !args[0]; + + this.$element.prop('disabled', disabled); + }; + + Select2.prototype.data = function () { + if (this.options.get('debug') && + arguments.length > 0 && window.console && console.warn) { + console.warn( + 'Select2: Data can no longer be set using `select2("data")`. You ' + + 'should consider setting the value instead using `$element.val()`.' + ); + } + + var data = []; + + this.dataAdapter.current(function (currentData) { + data = currentData; + }); + + return data; + }; + + Select2.prototype.val = function (args) { + if (this.options.get('debug') && window.console && console.warn) { + console.warn( + 'Select2: The `select2("val")` method has been deprecated and will be' + + ' removed in later Select2 versions. Use $element.val() instead.' + ); + } + + if (args == null || args.length === 0) { + return this.$element.val(); + } + + var newVal = args[0]; + + if ($.isArray(newVal)) { + newVal = $.map(newVal, function (obj) { + return obj.toString(); + }); + } + + this.$element.val(newVal).trigger('change'); + }; + + Select2.prototype.destroy = function () { + this.$container.remove(); + + if (this.$element[0].detachEvent) { + this.$element[0].detachEvent('onpropertychange', this._syncA); + } + + if (this._observer != null) { + this._observer.disconnect(); + this._observer = null; + } else if (this.$element[0].removeEventListener) { + this.$element[0] + .removeEventListener('DOMAttrModified', this._syncA, false); + this.$element[0] + .removeEventListener('DOMNodeInserted', this._syncS, false); + this.$element[0] + .removeEventListener('DOMNodeRemoved', this._syncS, false); + } + + this._syncA = null; + this._syncS = null; + + this.$element.off('.select2'); + this.$element.attr('tabindex', + Utils.GetData(this.$element[0], 'old-tabindex')); + + this.$element.removeClass('select2-hidden-accessible'); + this.$element.attr('aria-hidden', 'false'); + Utils.RemoveData(this.$element[0]); + this.$element.removeData('select2'); + + this.dataAdapter.destroy(); + this.selection.destroy(); + this.dropdown.destroy(); + this.results.destroy(); + + this.dataAdapter = null; + this.selection = null; + this.dropdown = null; + this.results = null; + }; + + Select2.prototype.render = function () { + var $container = $( + '' + + '' + + '' + + '' + ); + + $container.attr('dir', this.options.get('dir')); + + this.$container = $container; + + this.$container.addClass('select2-container--' + this.options.get('theme')); + + Utils.StoreData($container[0], 'element', this.$element); + + return $container; + }; + + return Select2; +}); + +S2.define('select2/compat/utils',[ + 'jquery' +], function ($) { + function syncCssClasses ($dest, $src, adapter) { + var classes, replacements = [], adapted; + + classes = $.trim($dest.attr('class')); + + if (classes) { + classes = '' + classes; // for IE which returns object + + $(classes.split(/\s+/)).each(function () { + // Save all Select2 classes + if (this.indexOf('select2-') === 0) { + replacements.push(this); + } + }); + } + + classes = $.trim($src.attr('class')); + + if (classes) { + classes = '' + classes; // for IE which returns object + + $(classes.split(/\s+/)).each(function () { + // Only adapt non-Select2 classes + if (this.indexOf('select2-') !== 0) { + adapted = adapter(this); + + if (adapted != null) { + replacements.push(adapted); + } + } + }); + } + + $dest.attr('class', replacements.join(' ')); + } + + return { + syncCssClasses: syncCssClasses + }; +}); + +S2.define('select2/compat/containerCss',[ + 'jquery', + './utils' +], function ($, CompatUtils) { + // No-op CSS adapter that discards all classes by default + function _containerAdapter (clazz) { + return null; + } + + function ContainerCSS () { } + + ContainerCSS.prototype.render = function (decorated) { + var $container = decorated.call(this); + + var containerCssClass = this.options.get('containerCssClass') || ''; + + if ($.isFunction(containerCssClass)) { + containerCssClass = containerCssClass(this.$element); + } + + var containerCssAdapter = this.options.get('adaptContainerCssClass'); + containerCssAdapter = containerCssAdapter || _containerAdapter; + + if (containerCssClass.indexOf(':all:') !== -1) { + containerCssClass = containerCssClass.replace(':all:', ''); + + var _cssAdapter = containerCssAdapter; + + containerCssAdapter = function (clazz) { + var adapted = _cssAdapter(clazz); + + if (adapted != null) { + // Append the old one along with the adapted one + return adapted + ' ' + clazz; + } + + return clazz; + }; + } + + var containerCss = this.options.get('containerCss') || {}; + + if ($.isFunction(containerCss)) { + containerCss = containerCss(this.$element); + } + + CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter); + + $container.css(containerCss); + $container.addClass(containerCssClass); + + return $container; + }; + + return ContainerCSS; +}); + +S2.define('select2/compat/dropdownCss',[ + 'jquery', + './utils' +], function ($, CompatUtils) { + // No-op CSS adapter that discards all classes by default + function _dropdownAdapter (clazz) { + return null; + } + + function DropdownCSS () { } + + DropdownCSS.prototype.render = function (decorated) { + var $dropdown = decorated.call(this); + + var dropdownCssClass = this.options.get('dropdownCssClass') || ''; + + if ($.isFunction(dropdownCssClass)) { + dropdownCssClass = dropdownCssClass(this.$element); + } + + var dropdownCssAdapter = this.options.get('adaptDropdownCssClass'); + dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter; + + if (dropdownCssClass.indexOf(':all:') !== -1) { + dropdownCssClass = dropdownCssClass.replace(':all:', ''); + + var _cssAdapter = dropdownCssAdapter; + + dropdownCssAdapter = function (clazz) { + var adapted = _cssAdapter(clazz); + + if (adapted != null) { + // Append the old one along with the adapted one + return adapted + ' ' + clazz; + } + + return clazz; + }; + } + + var dropdownCss = this.options.get('dropdownCss') || {}; + + if ($.isFunction(dropdownCss)) { + dropdownCss = dropdownCss(this.$element); + } + + CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter); + + $dropdown.css(dropdownCss); + $dropdown.addClass(dropdownCssClass); + + return $dropdown; + }; + + return DropdownCSS; +}); + +S2.define('select2/compat/initSelection',[ + 'jquery' +], function ($) { + function InitSelection (decorated, $element, options) { + if (options.get('debug') && window.console && console.warn) { + console.warn( + 'Select2: The `initSelection` option has been deprecated in favor' + + ' of a custom data adapter that overrides the `current` method. ' + + 'This method is now called multiple times instead of a single ' + + 'time when the instance is initialized. Support will be removed ' + + 'for the `initSelection` option in future versions of Select2' + ); + } + + this.initSelection = options.get('initSelection'); + this._isInitialized = false; + + decorated.call(this, $element, options); + } + + InitSelection.prototype.current = function (decorated, callback) { + var self = this; + + if (this._isInitialized) { + decorated.call(this, callback); + + return; + } + + this.initSelection.call(null, this.$element, function (data) { + self._isInitialized = true; + + if (!$.isArray(data)) { + data = [data]; + } + + callback(data); + }); + }; + + return InitSelection; +}); + +S2.define('select2/compat/inputData',[ + 'jquery', + '../utils' +], function ($, Utils) { + function InputData (decorated, $element, options) { + this._currentData = []; + this._valueSeparator = options.get('valueSeparator') || ','; + + if ($element.prop('type') === 'hidden') { + if (options.get('debug') && console && console.warn) { + console.warn( + 'Select2: Using a hidden input with Select2 is no longer ' + + 'supported and may stop working in the future. It is recommended ' + + 'to use a `');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("open",function(){i.$search.trigger("focus")}),t.on("close",function(){i.$search.val(""),i.$search.removeAttr("aria-activedescendant"),i.$search.trigger("focus")}),t.on("enable",function(){i.$search.prop("disabled",!1),i._transferTabIndex()}),t.on("disable",function(){i.$search.prop("disabled",!0)}),t.on("focus",function(e){i.$search.trigger("focus")}),t.on("results:focus",function(e){i.$search.attr("aria-activedescendant",e.id)}),this.$selection.on("focusin",".select2-search--inline",function(e){i.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){i._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===a.BACKSPACE&&""===i.$search.val()){var t=i.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.query=function(n,i,r){var o=this;this.current(function(e){var t=null!=e?e.length:0;0=o.maximumSelectionLength?o.trigger("results:message",{message:"maximumSelected",args:{maximum:o.maximumSelectionLength}}):n.call(o,i,r)})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(r,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=r('');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),this.$search.on("keydown",function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){r(this).off("keyup")}),this.$search.on("keyup input",function(e){i.handleSearch(e)}),t.on("open",function(){i.$search.attr("tabindex",0),i.$search.focus(),window.setTimeout(function(){i.$search.focus()},0)}),t.on("close",function(){i.$search.attr("tabindex",-1),i.$search.val(""),i.$search.blur()}),t.on("focus",function(){t.isOpen()||i.$search.focus()}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(i.showSearch(e)?i.$searchContainer.removeClass("select2-search--hide"):i.$searchContainer.addClass("select2-search--hide"))})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,i){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,i)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),i=t.length-1;0<=i;i--){var r=t[i];this.placeholder.id===r.id&&n.splice(i,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(r){function e(e,t,n,i){this.lastParams={},e.call(this,t,n,i),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&this.$results.append(this.$loadingMore)},e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("query",function(e){i.lastParams=e,i.loading=!0}),t.on("query:append",function(e){i.lastParams=e,i.loading=!0}),this.$results.on("scroll",function(){var e=r.contains(document.documentElement,i.$loadingMore[0]);if(!i.loading&&e){var t=i.$results.offset().top+i.$results.outerHeight(!1);i.$loadingMore.offset().top+i.$loadingMore.outerHeight(!1)<=t+50&&i.loadMore()}})},e.prototype.loadMore=function(){this.loading=!0;var e=r.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=r('
      • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=n.get("dropdownParent")||f(document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this,r=!1;e.call(this,t,n),t.on("open",function(){i._showDropdown(),i._attachPositioningHandler(t),r||(r=!0,t.on("results:all",function(){i._positionDropdown(),i._resizeDropdown()}),t.on("results:append",function(){i._positionDropdown(),i._resizeDropdown()}))}),t.on("close",function(){i._hideDropdown(),i._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._attachPositioningHandler=function(e,t){var n=this,i="scroll.select2."+t.id,r="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(i,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(i+" "+r+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,i="resize.select2."+t.id,r="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+i+" "+r)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=r.top,o.bottom=r.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ar.bottom+s,d={left:r.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h=p.offset();d.top-=h.top,d.left-=h.left,t||n||(i="below"),u||!c||t?!c&&u&&t&&(i="below"):i="above",("above"==i||t&&"below"!==i)&&(d.top=o.top-h.top-s),null!=i&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+i),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+i)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,i){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,i)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,i=0;i');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("select2/compat/utils",["jquery"],function(s){return{syncCssClasses:function(e,t,n){var i,r,o=[];(i=s.trim(e.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0===this.indexOf("select2-")&&o.push(this)}),(i=s.trim(t.attr("class")))&&s((i=""+i).split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(r=n(this))&&o.push(r)}),e.attr("class",o.join(" "))}}}),e.define("select2/compat/containerCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("containerCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptContainerCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("containerCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/dropdownCss",["jquery","./utils"],function(s,a){function l(e){return null}function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("dropdownCssClass")||"";s.isFunction(n)&&(n=n(this.$element));var i=this.options.get("adaptDropdownCssClass");if(i=i||l,-1!==n.indexOf(":all:")){n=n.replace(":all:","");var r=i;i=function(e){var t=r(e);return null!=t?t+" "+e:e}}var o=this.options.get("dropdownCss")||{};return s.isFunction(o)&&(o=o(this.$element)),a.syncCssClasses(t,this.$element,i),t.css(o),t.addClass(n),t},e}),e.define("select2/compat/initSelection",["jquery"],function(i){function e(e,t,n){n.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=n.get("initSelection"),this._isInitialized=!1,e.call(this,t,n)}return e.prototype.current=function(e,t){var n=this;this._isInitialized?e.call(this,t):this.initSelection.call(null,this.$element,function(e){n._isInitialized=!0,i.isArray(e)||(e=[e]),t(e)})},e}),e.define("select2/compat/inputData",["jquery","../utils"],function(s,i){function e(e,t,n){this._currentData=[],this._valueSeparator=n.get("valueSeparator")||",","hidden"===t.prop("type")&&n.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `' + + '' + ); + + this.$searchContainer = $search; + this.$search = $search.find('input'); + + var $rendered = decorated.call(this); + + this._transferTabIndex(); + + return $rendered; + }; + + Search.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('open', function () { + self.$search.trigger('focus'); + }); + + container.on('close', function () { + self.$search.val(''); + self.$search.removeAttr('aria-activedescendant'); + self.$search.trigger('focus'); + }); + + container.on('enable', function () { + self.$search.prop('disabled', false); + + self._transferTabIndex(); + }); + + container.on('disable', function () { + self.$search.prop('disabled', true); + }); + + container.on('focus', function (evt) { + self.$search.trigger('focus'); + }); + + container.on('results:focus', function (params) { + self.$search.attr('aria-activedescendant', params.id); + }); + + this.$selection.on('focusin', '.select2-search--inline', function (evt) { + self.trigger('focus', evt); + }); + + this.$selection.on('focusout', '.select2-search--inline', function (evt) { + self._handleBlur(evt); + }); + + this.$selection.on('keydown', '.select2-search--inline', function (evt) { + evt.stopPropagation(); + + self.trigger('keypress', evt); + + self._keyUpPrevented = evt.isDefaultPrevented(); + + var key = evt.which; + + if (key === KEYS.BACKSPACE && self.$search.val() === '') { + var $previousChoice = self.$searchContainer + .prev('.select2-selection__choice'); + + if ($previousChoice.length > 0) { + var item = Utils.GetData($previousChoice[0], 'data'); + + self.searchRemoveChoice(item); + + evt.preventDefault(); + } + } + }); + + // Try to detect the IE version should the `documentMode` property that + // is stored on the document. This is only implemented in IE and is + // slightly cleaner than doing a user agent check. + // This property is not available in Edge, but Edge also doesn't have + // this bug. + var msie = document.documentMode; + var disableInputEvents = msie && msie <= 11; + + // Workaround for browsers which do not support the `input` event + // This will prevent double-triggering of events for browsers which support + // both the `keyup` and `input` events. + this.$selection.on( + 'input.searchcheck', + '.select2-search--inline', + function (evt) { + // IE will trigger the `input` event when a placeholder is used on a + // search box. To get around this issue, we are forced to ignore all + // `input` events in IE and keep using `keyup`. + if (disableInputEvents) { + self.$selection.off('input.search input.searchcheck'); + return; + } + + // Unbind the duplicated `keyup` event + self.$selection.off('keyup.search'); + } + ); + + this.$selection.on( + 'keyup.search input.search', + '.select2-search--inline', + function (evt) { + // IE will trigger the `input` event when a placeholder is used on a + // search box. To get around this issue, we are forced to ignore all + // `input` events in IE and keep using `keyup`. + if (disableInputEvents && evt.type === 'input') { + self.$selection.off('input.search input.searchcheck'); + return; + } + + var key = evt.which; + + // We can freely ignore events from modifier keys + if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) { + return; + } + + // Tabbing will be handled during the `keydown` phase + if (key == KEYS.TAB) { + return; + } + + self.handleSearch(evt); + } + ); + }; + + /** + * This method will transfer the tabindex attribute from the rendered + * selection to the search box. This allows for the search box to be used as + * the primary focus instead of the selection container. + * + * @private + */ + Search.prototype._transferTabIndex = function (decorated) { + this.$search.attr('tabindex', this.$selection.attr('tabindex')); + this.$selection.attr('tabindex', '-1'); + }; + + Search.prototype.createPlaceholder = function (decorated, placeholder) { + this.$search.attr('placeholder', placeholder.text); + }; + + Search.prototype.update = function (decorated, data) { + var searchHadFocus = this.$search[0] == document.activeElement; + + this.$search.attr('placeholder', ''); + + decorated.call(this, data); + + this.$selection.find('.select2-selection__rendered') + .append(this.$searchContainer); + + this.resizeSearch(); + if (searchHadFocus) { + var isTagInput = this.$element.find('[data-select2-tag]').length; + if (isTagInput) { + // fix IE11 bug where tag input lost focus + this.$element.focus(); + } else { + this.$search.focus(); + } + } + }; + + Search.prototype.handleSearch = function () { + this.resizeSearch(); + + if (!this._keyUpPrevented) { + var input = this.$search.val(); + + this.trigger('query', { + term: input + }); + } + + this._keyUpPrevented = false; + }; + + Search.prototype.searchRemoveChoice = function (decorated, item) { + this.trigger('unselect', { + data: item + }); + + this.$search.val(item.text); + this.handleSearch(); + }; + + Search.prototype.resizeSearch = function () { + this.$search.css('width', '25px'); + + var width = ''; + + if (this.$search.attr('placeholder') !== '') { + width = this.$selection.find('.select2-selection__rendered').innerWidth(); + } else { + var minimumWidth = this.$search.val().length + 1; + + width = (minimumWidth * 0.75) + 'em'; + } + + this.$search.css('width', width); + }; + + return Search; +}); + +S2.define('select2/selection/eventRelay',[ + 'jquery' +], function ($) { + function EventRelay () { } + + EventRelay.prototype.bind = function (decorated, container, $container) { + var self = this; + var relayEvents = [ + 'open', 'opening', + 'close', 'closing', + 'select', 'selecting', + 'unselect', 'unselecting', + 'clear', 'clearing' + ]; + + var preventableEvents = [ + 'opening', 'closing', 'selecting', 'unselecting', 'clearing' + ]; + + decorated.call(this, container, $container); + + container.on('*', function (name, params) { + // Ignore events that should not be relayed + if ($.inArray(name, relayEvents) === -1) { + return; + } + + // The parameters should always be an object + params = params || {}; + + // Generate the jQuery event for the Select2 event + var evt = $.Event('select2:' + name, { + params: params + }); + + self.$element.trigger(evt); + + // Only handle preventable events if it was one + if ($.inArray(name, preventableEvents) === -1) { + return; + } + + params.prevented = evt.isDefaultPrevented(); + }); + }; + + return EventRelay; +}); + +S2.define('select2/translation',[ + 'jquery', + 'require' +], function ($, require) { + function Translation (dict) { + this.dict = dict || {}; + } + + Translation.prototype.all = function () { + return this.dict; + }; + + Translation.prototype.get = function (key) { + return this.dict[key]; + }; + + Translation.prototype.extend = function (translation) { + this.dict = $.extend({}, translation.all(), this.dict); + }; + + // Static functions + + Translation._cache = {}; + + Translation.loadPath = function (path) { + if (!(path in Translation._cache)) { + var translations = require(path); + + Translation._cache[path] = translations; + } + + return new Translation(Translation._cache[path]); + }; + + return Translation; +}); + +S2.define('select2/diacritics',[ + +], function () { + var diacritics = { + '\u24B6': 'A', + '\uFF21': 'A', + '\u00C0': 'A', + '\u00C1': 'A', + '\u00C2': 'A', + '\u1EA6': 'A', + '\u1EA4': 'A', + '\u1EAA': 'A', + '\u1EA8': 'A', + '\u00C3': 'A', + '\u0100': 'A', + '\u0102': 'A', + '\u1EB0': 'A', + '\u1EAE': 'A', + '\u1EB4': 'A', + '\u1EB2': 'A', + '\u0226': 'A', + '\u01E0': 'A', + '\u00C4': 'A', + '\u01DE': 'A', + '\u1EA2': 'A', + '\u00C5': 'A', + '\u01FA': 'A', + '\u01CD': 'A', + '\u0200': 'A', + '\u0202': 'A', + '\u1EA0': 'A', + '\u1EAC': 'A', + '\u1EB6': 'A', + '\u1E00': 'A', + '\u0104': 'A', + '\u023A': 'A', + '\u2C6F': 'A', + '\uA732': 'AA', + '\u00C6': 'AE', + '\u01FC': 'AE', + '\u01E2': 'AE', + '\uA734': 'AO', + '\uA736': 'AU', + '\uA738': 'AV', + '\uA73A': 'AV', + '\uA73C': 'AY', + '\u24B7': 'B', + '\uFF22': 'B', + '\u1E02': 'B', + '\u1E04': 'B', + '\u1E06': 'B', + '\u0243': 'B', + '\u0182': 'B', + '\u0181': 'B', + '\u24B8': 'C', + '\uFF23': 'C', + '\u0106': 'C', + '\u0108': 'C', + '\u010A': 'C', + '\u010C': 'C', + '\u00C7': 'C', + '\u1E08': 'C', + '\u0187': 'C', + '\u023B': 'C', + '\uA73E': 'C', + '\u24B9': 'D', + '\uFF24': 'D', + '\u1E0A': 'D', + '\u010E': 'D', + '\u1E0C': 'D', + '\u1E10': 'D', + '\u1E12': 'D', + '\u1E0E': 'D', + '\u0110': 'D', + '\u018B': 'D', + '\u018A': 'D', + '\u0189': 'D', + '\uA779': 'D', + '\u01F1': 'DZ', + '\u01C4': 'DZ', + '\u01F2': 'Dz', + '\u01C5': 'Dz', + '\u24BA': 'E', + '\uFF25': 'E', + '\u00C8': 'E', + '\u00C9': 'E', + '\u00CA': 'E', + '\u1EC0': 'E', + '\u1EBE': 'E', + '\u1EC4': 'E', + '\u1EC2': 'E', + '\u1EBC': 'E', + '\u0112': 'E', + '\u1E14': 'E', + '\u1E16': 'E', + '\u0114': 'E', + '\u0116': 'E', + '\u00CB': 'E', + '\u1EBA': 'E', + '\u011A': 'E', + '\u0204': 'E', + '\u0206': 'E', + '\u1EB8': 'E', + '\u1EC6': 'E', + '\u0228': 'E', + '\u1E1C': 'E', + '\u0118': 'E', + '\u1E18': 'E', + '\u1E1A': 'E', + '\u0190': 'E', + '\u018E': 'E', + '\u24BB': 'F', + '\uFF26': 'F', + '\u1E1E': 'F', + '\u0191': 'F', + '\uA77B': 'F', + '\u24BC': 'G', + '\uFF27': 'G', + '\u01F4': 'G', + '\u011C': 'G', + '\u1E20': 'G', + '\u011E': 'G', + '\u0120': 'G', + '\u01E6': 'G', + '\u0122': 'G', + '\u01E4': 'G', + '\u0193': 'G', + '\uA7A0': 'G', + '\uA77D': 'G', + '\uA77E': 'G', + '\u24BD': 'H', + '\uFF28': 'H', + '\u0124': 'H', + '\u1E22': 'H', + '\u1E26': 'H', + '\u021E': 'H', + '\u1E24': 'H', + '\u1E28': 'H', + '\u1E2A': 'H', + '\u0126': 'H', + '\u2C67': 'H', + '\u2C75': 'H', + '\uA78D': 'H', + '\u24BE': 'I', + '\uFF29': 'I', + '\u00CC': 'I', + '\u00CD': 'I', + '\u00CE': 'I', + '\u0128': 'I', + '\u012A': 'I', + '\u012C': 'I', + '\u0130': 'I', + '\u00CF': 'I', + '\u1E2E': 'I', + '\u1EC8': 'I', + '\u01CF': 'I', + '\u0208': 'I', + '\u020A': 'I', + '\u1ECA': 'I', + '\u012E': 'I', + '\u1E2C': 'I', + '\u0197': 'I', + '\u24BF': 'J', + '\uFF2A': 'J', + '\u0134': 'J', + '\u0248': 'J', + '\u24C0': 'K', + '\uFF2B': 'K', + '\u1E30': 'K', + '\u01E8': 'K', + '\u1E32': 'K', + '\u0136': 'K', + '\u1E34': 'K', + '\u0198': 'K', + '\u2C69': 'K', + '\uA740': 'K', + '\uA742': 'K', + '\uA744': 'K', + '\uA7A2': 'K', + '\u24C1': 'L', + '\uFF2C': 'L', + '\u013F': 'L', + '\u0139': 'L', + '\u013D': 'L', + '\u1E36': 'L', + '\u1E38': 'L', + '\u013B': 'L', + '\u1E3C': 'L', + '\u1E3A': 'L', + '\u0141': 'L', + '\u023D': 'L', + '\u2C62': 'L', + '\u2C60': 'L', + '\uA748': 'L', + '\uA746': 'L', + '\uA780': 'L', + '\u01C7': 'LJ', + '\u01C8': 'Lj', + '\u24C2': 'M', + '\uFF2D': 'M', + '\u1E3E': 'M', + '\u1E40': 'M', + '\u1E42': 'M', + '\u2C6E': 'M', + '\u019C': 'M', + '\u24C3': 'N', + '\uFF2E': 'N', + '\u01F8': 'N', + '\u0143': 'N', + '\u00D1': 'N', + '\u1E44': 'N', + '\u0147': 'N', + '\u1E46': 'N', + '\u0145': 'N', + '\u1E4A': 'N', + '\u1E48': 'N', + '\u0220': 'N', + '\u019D': 'N', + '\uA790': 'N', + '\uA7A4': 'N', + '\u01CA': 'NJ', + '\u01CB': 'Nj', + '\u24C4': 'O', + '\uFF2F': 'O', + '\u00D2': 'O', + '\u00D3': 'O', + '\u00D4': 'O', + '\u1ED2': 'O', + '\u1ED0': 'O', + '\u1ED6': 'O', + '\u1ED4': 'O', + '\u00D5': 'O', + '\u1E4C': 'O', + '\u022C': 'O', + '\u1E4E': 'O', + '\u014C': 'O', + '\u1E50': 'O', + '\u1E52': 'O', + '\u014E': 'O', + '\u022E': 'O', + '\u0230': 'O', + '\u00D6': 'O', + '\u022A': 'O', + '\u1ECE': 'O', + '\u0150': 'O', + '\u01D1': 'O', + '\u020C': 'O', + '\u020E': 'O', + '\u01A0': 'O', + '\u1EDC': 'O', + '\u1EDA': 'O', + '\u1EE0': 'O', + '\u1EDE': 'O', + '\u1EE2': 'O', + '\u1ECC': 'O', + '\u1ED8': 'O', + '\u01EA': 'O', + '\u01EC': 'O', + '\u00D8': 'O', + '\u01FE': 'O', + '\u0186': 'O', + '\u019F': 'O', + '\uA74A': 'O', + '\uA74C': 'O', + '\u0152': 'OE', + '\u01A2': 'OI', + '\uA74E': 'OO', + '\u0222': 'OU', + '\u24C5': 'P', + '\uFF30': 'P', + '\u1E54': 'P', + '\u1E56': 'P', + '\u01A4': 'P', + '\u2C63': 'P', + '\uA750': 'P', + '\uA752': 'P', + '\uA754': 'P', + '\u24C6': 'Q', + '\uFF31': 'Q', + '\uA756': 'Q', + '\uA758': 'Q', + '\u024A': 'Q', + '\u24C7': 'R', + '\uFF32': 'R', + '\u0154': 'R', + '\u1E58': 'R', + '\u0158': 'R', + '\u0210': 'R', + '\u0212': 'R', + '\u1E5A': 'R', + '\u1E5C': 'R', + '\u0156': 'R', + '\u1E5E': 'R', + '\u024C': 'R', + '\u2C64': 'R', + '\uA75A': 'R', + '\uA7A6': 'R', + '\uA782': 'R', + '\u24C8': 'S', + '\uFF33': 'S', + '\u1E9E': 'S', + '\u015A': 'S', + '\u1E64': 'S', + '\u015C': 'S', + '\u1E60': 'S', + '\u0160': 'S', + '\u1E66': 'S', + '\u1E62': 'S', + '\u1E68': 'S', + '\u0218': 'S', + '\u015E': 'S', + '\u2C7E': 'S', + '\uA7A8': 'S', + '\uA784': 'S', + '\u24C9': 'T', + '\uFF34': 'T', + '\u1E6A': 'T', + '\u0164': 'T', + '\u1E6C': 'T', + '\u021A': 'T', + '\u0162': 'T', + '\u1E70': 'T', + '\u1E6E': 'T', + '\u0166': 'T', + '\u01AC': 'T', + '\u01AE': 'T', + '\u023E': 'T', + '\uA786': 'T', + '\uA728': 'TZ', + '\u24CA': 'U', + '\uFF35': 'U', + '\u00D9': 'U', + '\u00DA': 'U', + '\u00DB': 'U', + '\u0168': 'U', + '\u1E78': 'U', + '\u016A': 'U', + '\u1E7A': 'U', + '\u016C': 'U', + '\u00DC': 'U', + '\u01DB': 'U', + '\u01D7': 'U', + '\u01D5': 'U', + '\u01D9': 'U', + '\u1EE6': 'U', + '\u016E': 'U', + '\u0170': 'U', + '\u01D3': 'U', + '\u0214': 'U', + '\u0216': 'U', + '\u01AF': 'U', + '\u1EEA': 'U', + '\u1EE8': 'U', + '\u1EEE': 'U', + '\u1EEC': 'U', + '\u1EF0': 'U', + '\u1EE4': 'U', + '\u1E72': 'U', + '\u0172': 'U', + '\u1E76': 'U', + '\u1E74': 'U', + '\u0244': 'U', + '\u24CB': 'V', + '\uFF36': 'V', + '\u1E7C': 'V', + '\u1E7E': 'V', + '\u01B2': 'V', + '\uA75E': 'V', + '\u0245': 'V', + '\uA760': 'VY', + '\u24CC': 'W', + '\uFF37': 'W', + '\u1E80': 'W', + '\u1E82': 'W', + '\u0174': 'W', + '\u1E86': 'W', + '\u1E84': 'W', + '\u1E88': 'W', + '\u2C72': 'W', + '\u24CD': 'X', + '\uFF38': 'X', + '\u1E8A': 'X', + '\u1E8C': 'X', + '\u24CE': 'Y', + '\uFF39': 'Y', + '\u1EF2': 'Y', + '\u00DD': 'Y', + '\u0176': 'Y', + '\u1EF8': 'Y', + '\u0232': 'Y', + '\u1E8E': 'Y', + '\u0178': 'Y', + '\u1EF6': 'Y', + '\u1EF4': 'Y', + '\u01B3': 'Y', + '\u024E': 'Y', + '\u1EFE': 'Y', + '\u24CF': 'Z', + '\uFF3A': 'Z', + '\u0179': 'Z', + '\u1E90': 'Z', + '\u017B': 'Z', + '\u017D': 'Z', + '\u1E92': 'Z', + '\u1E94': 'Z', + '\u01B5': 'Z', + '\u0224': 'Z', + '\u2C7F': 'Z', + '\u2C6B': 'Z', + '\uA762': 'Z', + '\u24D0': 'a', + '\uFF41': 'a', + '\u1E9A': 'a', + '\u00E0': 'a', + '\u00E1': 'a', + '\u00E2': 'a', + '\u1EA7': 'a', + '\u1EA5': 'a', + '\u1EAB': 'a', + '\u1EA9': 'a', + '\u00E3': 'a', + '\u0101': 'a', + '\u0103': 'a', + '\u1EB1': 'a', + '\u1EAF': 'a', + '\u1EB5': 'a', + '\u1EB3': 'a', + '\u0227': 'a', + '\u01E1': 'a', + '\u00E4': 'a', + '\u01DF': 'a', + '\u1EA3': 'a', + '\u00E5': 'a', + '\u01FB': 'a', + '\u01CE': 'a', + '\u0201': 'a', + '\u0203': 'a', + '\u1EA1': 'a', + '\u1EAD': 'a', + '\u1EB7': 'a', + '\u1E01': 'a', + '\u0105': 'a', + '\u2C65': 'a', + '\u0250': 'a', + '\uA733': 'aa', + '\u00E6': 'ae', + '\u01FD': 'ae', + '\u01E3': 'ae', + '\uA735': 'ao', + '\uA737': 'au', + '\uA739': 'av', + '\uA73B': 'av', + '\uA73D': 'ay', + '\u24D1': 'b', + '\uFF42': 'b', + '\u1E03': 'b', + '\u1E05': 'b', + '\u1E07': 'b', + '\u0180': 'b', + '\u0183': 'b', + '\u0253': 'b', + '\u24D2': 'c', + '\uFF43': 'c', + '\u0107': 'c', + '\u0109': 'c', + '\u010B': 'c', + '\u010D': 'c', + '\u00E7': 'c', + '\u1E09': 'c', + '\u0188': 'c', + '\u023C': 'c', + '\uA73F': 'c', + '\u2184': 'c', + '\u24D3': 'd', + '\uFF44': 'd', + '\u1E0B': 'd', + '\u010F': 'd', + '\u1E0D': 'd', + '\u1E11': 'd', + '\u1E13': 'd', + '\u1E0F': 'd', + '\u0111': 'd', + '\u018C': 'd', + '\u0256': 'd', + '\u0257': 'd', + '\uA77A': 'd', + '\u01F3': 'dz', + '\u01C6': 'dz', + '\u24D4': 'e', + '\uFF45': 'e', + '\u00E8': 'e', + '\u00E9': 'e', + '\u00EA': 'e', + '\u1EC1': 'e', + '\u1EBF': 'e', + '\u1EC5': 'e', + '\u1EC3': 'e', + '\u1EBD': 'e', + '\u0113': 'e', + '\u1E15': 'e', + '\u1E17': 'e', + '\u0115': 'e', + '\u0117': 'e', + '\u00EB': 'e', + '\u1EBB': 'e', + '\u011B': 'e', + '\u0205': 'e', + '\u0207': 'e', + '\u1EB9': 'e', + '\u1EC7': 'e', + '\u0229': 'e', + '\u1E1D': 'e', + '\u0119': 'e', + '\u1E19': 'e', + '\u1E1B': 'e', + '\u0247': 'e', + '\u025B': 'e', + '\u01DD': 'e', + '\u24D5': 'f', + '\uFF46': 'f', + '\u1E1F': 'f', + '\u0192': 'f', + '\uA77C': 'f', + '\u24D6': 'g', + '\uFF47': 'g', + '\u01F5': 'g', + '\u011D': 'g', + '\u1E21': 'g', + '\u011F': 'g', + '\u0121': 'g', + '\u01E7': 'g', + '\u0123': 'g', + '\u01E5': 'g', + '\u0260': 'g', + '\uA7A1': 'g', + '\u1D79': 'g', + '\uA77F': 'g', + '\u24D7': 'h', + '\uFF48': 'h', + '\u0125': 'h', + '\u1E23': 'h', + '\u1E27': 'h', + '\u021F': 'h', + '\u1E25': 'h', + '\u1E29': 'h', + '\u1E2B': 'h', + '\u1E96': 'h', + '\u0127': 'h', + '\u2C68': 'h', + '\u2C76': 'h', + '\u0265': 'h', + '\u0195': 'hv', + '\u24D8': 'i', + '\uFF49': 'i', + '\u00EC': 'i', + '\u00ED': 'i', + '\u00EE': 'i', + '\u0129': 'i', + '\u012B': 'i', + '\u012D': 'i', + '\u00EF': 'i', + '\u1E2F': 'i', + '\u1EC9': 'i', + '\u01D0': 'i', + '\u0209': 'i', + '\u020B': 'i', + '\u1ECB': 'i', + '\u012F': 'i', + '\u1E2D': 'i', + '\u0268': 'i', + '\u0131': 'i', + '\u24D9': 'j', + '\uFF4A': 'j', + '\u0135': 'j', + '\u01F0': 'j', + '\u0249': 'j', + '\u24DA': 'k', + '\uFF4B': 'k', + '\u1E31': 'k', + '\u01E9': 'k', + '\u1E33': 'k', + '\u0137': 'k', + '\u1E35': 'k', + '\u0199': 'k', + '\u2C6A': 'k', + '\uA741': 'k', + '\uA743': 'k', + '\uA745': 'k', + '\uA7A3': 'k', + '\u24DB': 'l', + '\uFF4C': 'l', + '\u0140': 'l', + '\u013A': 'l', + '\u013E': 'l', + '\u1E37': 'l', + '\u1E39': 'l', + '\u013C': 'l', + '\u1E3D': 'l', + '\u1E3B': 'l', + '\u017F': 'l', + '\u0142': 'l', + '\u019A': 'l', + '\u026B': 'l', + '\u2C61': 'l', + '\uA749': 'l', + '\uA781': 'l', + '\uA747': 'l', + '\u01C9': 'lj', + '\u24DC': 'm', + '\uFF4D': 'm', + '\u1E3F': 'm', + '\u1E41': 'm', + '\u1E43': 'm', + '\u0271': 'm', + '\u026F': 'm', + '\u24DD': 'n', + '\uFF4E': 'n', + '\u01F9': 'n', + '\u0144': 'n', + '\u00F1': 'n', + '\u1E45': 'n', + '\u0148': 'n', + '\u1E47': 'n', + '\u0146': 'n', + '\u1E4B': 'n', + '\u1E49': 'n', + '\u019E': 'n', + '\u0272': 'n', + '\u0149': 'n', + '\uA791': 'n', + '\uA7A5': 'n', + '\u01CC': 'nj', + '\u24DE': 'o', + '\uFF4F': 'o', + '\u00F2': 'o', + '\u00F3': 'o', + '\u00F4': 'o', + '\u1ED3': 'o', + '\u1ED1': 'o', + '\u1ED7': 'o', + '\u1ED5': 'o', + '\u00F5': 'o', + '\u1E4D': 'o', + '\u022D': 'o', + '\u1E4F': 'o', + '\u014D': 'o', + '\u1E51': 'o', + '\u1E53': 'o', + '\u014F': 'o', + '\u022F': 'o', + '\u0231': 'o', + '\u00F6': 'o', + '\u022B': 'o', + '\u1ECF': 'o', + '\u0151': 'o', + '\u01D2': 'o', + '\u020D': 'o', + '\u020F': 'o', + '\u01A1': 'o', + '\u1EDD': 'o', + '\u1EDB': 'o', + '\u1EE1': 'o', + '\u1EDF': 'o', + '\u1EE3': 'o', + '\u1ECD': 'o', + '\u1ED9': 'o', + '\u01EB': 'o', + '\u01ED': 'o', + '\u00F8': 'o', + '\u01FF': 'o', + '\u0254': 'o', + '\uA74B': 'o', + '\uA74D': 'o', + '\u0275': 'o', + '\u0153': 'oe', + '\u01A3': 'oi', + '\u0223': 'ou', + '\uA74F': 'oo', + '\u24DF': 'p', + '\uFF50': 'p', + '\u1E55': 'p', + '\u1E57': 'p', + '\u01A5': 'p', + '\u1D7D': 'p', + '\uA751': 'p', + '\uA753': 'p', + '\uA755': 'p', + '\u24E0': 'q', + '\uFF51': 'q', + '\u024B': 'q', + '\uA757': 'q', + '\uA759': 'q', + '\u24E1': 'r', + '\uFF52': 'r', + '\u0155': 'r', + '\u1E59': 'r', + '\u0159': 'r', + '\u0211': 'r', + '\u0213': 'r', + '\u1E5B': 'r', + '\u1E5D': 'r', + '\u0157': 'r', + '\u1E5F': 'r', + '\u024D': 'r', + '\u027D': 'r', + '\uA75B': 'r', + '\uA7A7': 'r', + '\uA783': 'r', + '\u24E2': 's', + '\uFF53': 's', + '\u00DF': 's', + '\u015B': 's', + '\u1E65': 's', + '\u015D': 's', + '\u1E61': 's', + '\u0161': 's', + '\u1E67': 's', + '\u1E63': 's', + '\u1E69': 's', + '\u0219': 's', + '\u015F': 's', + '\u023F': 's', + '\uA7A9': 's', + '\uA785': 's', + '\u1E9B': 's', + '\u24E3': 't', + '\uFF54': 't', + '\u1E6B': 't', + '\u1E97': 't', + '\u0165': 't', + '\u1E6D': 't', + '\u021B': 't', + '\u0163': 't', + '\u1E71': 't', + '\u1E6F': 't', + '\u0167': 't', + '\u01AD': 't', + '\u0288': 't', + '\u2C66': 't', + '\uA787': 't', + '\uA729': 'tz', + '\u24E4': 'u', + '\uFF55': 'u', + '\u00F9': 'u', + '\u00FA': 'u', + '\u00FB': 'u', + '\u0169': 'u', + '\u1E79': 'u', + '\u016B': 'u', + '\u1E7B': 'u', + '\u016D': 'u', + '\u00FC': 'u', + '\u01DC': 'u', + '\u01D8': 'u', + '\u01D6': 'u', + '\u01DA': 'u', + '\u1EE7': 'u', + '\u016F': 'u', + '\u0171': 'u', + '\u01D4': 'u', + '\u0215': 'u', + '\u0217': 'u', + '\u01B0': 'u', + '\u1EEB': 'u', + '\u1EE9': 'u', + '\u1EEF': 'u', + '\u1EED': 'u', + '\u1EF1': 'u', + '\u1EE5': 'u', + '\u1E73': 'u', + '\u0173': 'u', + '\u1E77': 'u', + '\u1E75': 'u', + '\u0289': 'u', + '\u24E5': 'v', + '\uFF56': 'v', + '\u1E7D': 'v', + '\u1E7F': 'v', + '\u028B': 'v', + '\uA75F': 'v', + '\u028C': 'v', + '\uA761': 'vy', + '\u24E6': 'w', + '\uFF57': 'w', + '\u1E81': 'w', + '\u1E83': 'w', + '\u0175': 'w', + '\u1E87': 'w', + '\u1E85': 'w', + '\u1E98': 'w', + '\u1E89': 'w', + '\u2C73': 'w', + '\u24E7': 'x', + '\uFF58': 'x', + '\u1E8B': 'x', + '\u1E8D': 'x', + '\u24E8': 'y', + '\uFF59': 'y', + '\u1EF3': 'y', + '\u00FD': 'y', + '\u0177': 'y', + '\u1EF9': 'y', + '\u0233': 'y', + '\u1E8F': 'y', + '\u00FF': 'y', + '\u1EF7': 'y', + '\u1E99': 'y', + '\u1EF5': 'y', + '\u01B4': 'y', + '\u024F': 'y', + '\u1EFF': 'y', + '\u24E9': 'z', + '\uFF5A': 'z', + '\u017A': 'z', + '\u1E91': 'z', + '\u017C': 'z', + '\u017E': 'z', + '\u1E93': 'z', + '\u1E95': 'z', + '\u01B6': 'z', + '\u0225': 'z', + '\u0240': 'z', + '\u2C6C': 'z', + '\uA763': 'z', + '\u0386': '\u0391', + '\u0388': '\u0395', + '\u0389': '\u0397', + '\u038A': '\u0399', + '\u03AA': '\u0399', + '\u038C': '\u039F', + '\u038E': '\u03A5', + '\u03AB': '\u03A5', + '\u038F': '\u03A9', + '\u03AC': '\u03B1', + '\u03AD': '\u03B5', + '\u03AE': '\u03B7', + '\u03AF': '\u03B9', + '\u03CA': '\u03B9', + '\u0390': '\u03B9', + '\u03CC': '\u03BF', + '\u03CD': '\u03C5', + '\u03CB': '\u03C5', + '\u03B0': '\u03C5', + '\u03CE': '\u03C9', + '\u03C2': '\u03C3', + '\u2019': '\'' + }; + + return diacritics; +}); + +S2.define('select2/data/base',[ + '../utils' +], function (Utils) { + function BaseAdapter ($element, options) { + BaseAdapter.__super__.constructor.call(this); + } + + Utils.Extend(BaseAdapter, Utils.Observable); + + BaseAdapter.prototype.current = function (callback) { + throw new Error('The `current` method must be defined in child classes.'); + }; + + BaseAdapter.prototype.query = function (params, callback) { + throw new Error('The `query` method must be defined in child classes.'); + }; + + BaseAdapter.prototype.bind = function (container, $container) { + // Can be implemented in subclasses + }; + + BaseAdapter.prototype.destroy = function () { + // Can be implemented in subclasses + }; + + BaseAdapter.prototype.generateResultId = function (container, data) { + var id = container.id + '-result-'; + + id += Utils.generateChars(4); + + if (data.id != null) { + id += '-' + data.id.toString(); + } else { + id += '-' + Utils.generateChars(4); + } + return id; + }; + + return BaseAdapter; +}); + +S2.define('select2/data/select',[ + './base', + '../utils', + 'jquery' +], function (BaseAdapter, Utils, $) { + function SelectAdapter ($element, options) { + this.$element = $element; + this.options = options; + + SelectAdapter.__super__.constructor.call(this); + } + + Utils.Extend(SelectAdapter, BaseAdapter); + + SelectAdapter.prototype.current = function (callback) { + var data = []; + var self = this; + + this.$element.find(':selected').each(function () { + var $option = $(this); + + var option = self.item($option); + + data.push(option); + }); + + callback(data); + }; + + SelectAdapter.prototype.select = function (data) { + var self = this; + + data.selected = true; + + // If data.element is a DOM node, use it instead + if ($(data.element).is('option')) { + data.element.selected = true; + + this.$element.trigger('change'); + + return; + } + + if (this.$element.prop('multiple')) { + this.current(function (currentData) { + var val = []; + + data = [data]; + data.push.apply(data, currentData); + + for (var d = 0; d < data.length; d++) { + var id = data[d].id; + + if ($.inArray(id, val) === -1) { + val.push(id); + } + } + + self.$element.val(val); + self.$element.trigger('change'); + }); + } else { + var val = data.id; + + this.$element.val(val); + this.$element.trigger('change'); + } + }; + + SelectAdapter.prototype.unselect = function (data) { + var self = this; + + if (!this.$element.prop('multiple')) { + return; + } + + data.selected = false; + + if ($(data.element).is('option')) { + data.element.selected = false; + + this.$element.trigger('change'); + + return; + } + + this.current(function (currentData) { + var val = []; + + for (var d = 0; d < currentData.length; d++) { + var id = currentData[d].id; + + if (id !== data.id && $.inArray(id, val) === -1) { + val.push(id); + } + } + + self.$element.val(val); + + self.$element.trigger('change'); + }); + }; + + SelectAdapter.prototype.bind = function (container, $container) { + var self = this; + + this.container = container; + + container.on('select', function (params) { + self.select(params.data); + }); + + container.on('unselect', function (params) { + self.unselect(params.data); + }); + }; + + SelectAdapter.prototype.destroy = function () { + // Remove anything added to child elements + this.$element.find('*').each(function () { + // Remove any custom data set by Select2 + Utils.RemoveData(this); + }); + }; + + SelectAdapter.prototype.query = function (params, callback) { + var data = []; + var self = this; + + var $options = this.$element.children(); + + $options.each(function () { + var $option = $(this); + + if (!$option.is('option') && !$option.is('optgroup')) { + return; + } + + var option = self.item($option); + + var matches = self.matches(params, option); + + if (matches !== null) { + data.push(matches); + } + }); + + callback({ + results: data + }); + }; + + SelectAdapter.prototype.addOptions = function ($options) { + Utils.appendMany(this.$element, $options); + }; + + SelectAdapter.prototype.option = function (data) { + var option; + + if (data.children) { + option = document.createElement('optgroup'); + option.label = data.text; + } else { + option = document.createElement('option'); + + if (option.textContent !== undefined) { + option.textContent = data.text; + } else { + option.innerText = data.text; + } + } + + if (data.id !== undefined) { + option.value = data.id; + } + + if (data.disabled) { + option.disabled = true; + } + + if (data.selected) { + option.selected = true; + } + + if (data.title) { + option.title = data.title; + } + + var $option = $(option); + + var normalizedData = this._normalizeItem(data); + normalizedData.element = option; + + // Override the option's data with the combined data + Utils.StoreData(option, 'data', normalizedData); + + return $option; + }; + + SelectAdapter.prototype.item = function ($option) { + var data = {}; + + data = Utils.GetData($option[0], 'data'); + + if (data != null) { + return data; + } + + if ($option.is('option')) { + data = { + id: $option.val(), + text: $option.text(), + disabled: $option.prop('disabled'), + selected: $option.prop('selected'), + title: $option.prop('title') + }; + } else if ($option.is('optgroup')) { + data = { + text: $option.prop('label'), + children: [], + title: $option.prop('title') + }; + + var $children = $option.children('option'); + var children = []; + + for (var c = 0; c < $children.length; c++) { + var $child = $($children[c]); + + var child = this.item($child); + + children.push(child); + } + + data.children = children; + } + + data = this._normalizeItem(data); + data.element = $option[0]; + + Utils.StoreData($option[0], 'data', data); + + return data; + }; + + SelectAdapter.prototype._normalizeItem = function (item) { + if (item !== Object(item)) { + item = { + id: item, + text: item + }; + } + + item = $.extend({}, { + text: '' + }, item); + + var defaults = { + selected: false, + disabled: false + }; + + if (item.id != null) { + item.id = item.id.toString(); + } + + if (item.text != null) { + item.text = item.text.toString(); + } + + if (item._resultId == null && item.id && this.container != null) { + item._resultId = this.generateResultId(this.container, item); + } + + return $.extend({}, defaults, item); + }; + + SelectAdapter.prototype.matches = function (params, data) { + var matcher = this.options.get('matcher'); + + return matcher(params, data); + }; + + return SelectAdapter; +}); + +S2.define('select2/data/array',[ + './select', + '../utils', + 'jquery' +], function (SelectAdapter, Utils, $) { + function ArrayAdapter ($element, options) { + var data = options.get('data') || []; + + ArrayAdapter.__super__.constructor.call(this, $element, options); + + this.addOptions(this.convertToOptions(data)); + } + + Utils.Extend(ArrayAdapter, SelectAdapter); + + ArrayAdapter.prototype.select = function (data) { + var $option = this.$element.find('option').filter(function (i, elm) { + return elm.value == data.id.toString(); + }); + + if ($option.length === 0) { + $option = this.option(data); + + this.addOptions($option); + } + + ArrayAdapter.__super__.select.call(this, data); + }; + + ArrayAdapter.prototype.convertToOptions = function (data) { + var self = this; + + var $existing = this.$element.find('option'); + var existingIds = $existing.map(function () { + return self.item($(this)).id; + }).get(); + + var $options = []; + + // Filter out all items except for the one passed in the argument + function onlyItem (item) { + return function () { + return $(this).val() == item.id; + }; + } + + for (var d = 0; d < data.length; d++) { + var item = this._normalizeItem(data[d]); + + // Skip items which were pre-loaded, only merge the data + if ($.inArray(item.id, existingIds) >= 0) { + var $existingOption = $existing.filter(onlyItem(item)); + + var existingData = this.item($existingOption); + var newData = $.extend(true, {}, item, existingData); + + var $newOption = this.option(newData); + + $existingOption.replaceWith($newOption); + + continue; + } + + var $option = this.option(item); + + if (item.children) { + var $children = this.convertToOptions(item.children); + + Utils.appendMany($option, $children); + } + + $options.push($option); + } + + return $options; + }; + + return ArrayAdapter; +}); + +S2.define('select2/data/ajax',[ + './array', + '../utils', + 'jquery' +], function (ArrayAdapter, Utils, $) { + function AjaxAdapter ($element, options) { + this.ajaxOptions = this._applyDefaults(options.get('ajax')); + + if (this.ajaxOptions.processResults != null) { + this.processResults = this.ajaxOptions.processResults; + } + + AjaxAdapter.__super__.constructor.call(this, $element, options); + } + + Utils.Extend(AjaxAdapter, ArrayAdapter); + + AjaxAdapter.prototype._applyDefaults = function (options) { + var defaults = { + data: function (params) { + return $.extend({}, params, { + q: params.term + }); + }, + transport: function (params, success, failure) { + var $request = $.ajax(params); + + $request.then(success); + $request.fail(failure); + + return $request; + } + }; + + return $.extend({}, defaults, options, true); + }; + + AjaxAdapter.prototype.processResults = function (results) { + return results; + }; + + AjaxAdapter.prototype.query = function (params, callback) { + var matches = []; + var self = this; + + if (this._request != null) { + // JSONP requests cannot always be aborted + if ($.isFunction(this._request.abort)) { + this._request.abort(); + } + + this._request = null; + } + + var options = $.extend({ + type: 'GET' + }, this.ajaxOptions); + + if (typeof options.url === 'function') { + options.url = options.url.call(this.$element, params); + } + + if (typeof options.data === 'function') { + options.data = options.data.call(this.$element, params); + } + + function request () { + var $request = options.transport(options, function (data) { + var results = self.processResults(data, params); + + if (self.options.get('debug') && window.console && console.error) { + // Check to make sure that the response included a `results` key. + if (!results || !results.results || !$.isArray(results.results)) { + console.error( + 'Select2: The AJAX results did not return an array in the ' + + '`results` key of the response.' + ); + } + } + + callback(results); + }, function () { + // Attempt to detect if a request was aborted + // Only works if the transport exposes a status property + if ('status' in $request && + ($request.status === 0 || $request.status === '0')) { + return; + } + + self.trigger('results:message', { + message: 'errorLoading' + }); + }); + + self._request = $request; + } + + if (this.ajaxOptions.delay && params.term != null) { + if (this._queryTimeout) { + window.clearTimeout(this._queryTimeout); + } + + this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay); + } else { + request(); + } + }; + + return AjaxAdapter; +}); + +S2.define('select2/data/tags',[ + 'jquery' +], function ($) { + function Tags (decorated, $element, options) { + var tags = options.get('tags'); + + var createTag = options.get('createTag'); + + if (createTag !== undefined) { + this.createTag = createTag; + } + + var insertTag = options.get('insertTag'); + + if (insertTag !== undefined) { + this.insertTag = insertTag; + } + + decorated.call(this, $element, options); + + if ($.isArray(tags)) { + for (var t = 0; t < tags.length; t++) { + var tag = tags[t]; + var item = this._normalizeItem(tag); + + var $option = this.option(item); + + this.$element.append($option); + } + } + } + + Tags.prototype.query = function (decorated, params, callback) { + var self = this; + + this._removeOldTags(); + + if (params.term == null || params.page != null) { + decorated.call(this, params, callback); + return; + } + + function wrapper (obj, child) { + var data = obj.results; + + for (var i = 0; i < data.length; i++) { + var option = data[i]; + + var checkChildren = ( + option.children != null && + !wrapper({ + results: option.children + }, true) + ); + + var optionText = (option.text || '').toUpperCase(); + var paramsTerm = (params.term || '').toUpperCase(); + + var checkText = optionText === paramsTerm; + + if (checkText || checkChildren) { + if (child) { + return false; + } + + obj.data = data; + callback(obj); + + return; + } + } + + if (child) { + return true; + } + + var tag = self.createTag(params); + + if (tag != null) { + var $option = self.option(tag); + $option.attr('data-select2-tag', true); + + self.addOptions([$option]); + + self.insertTag(data, tag); + } + + obj.results = data; + + callback(obj); + } + + decorated.call(this, params, wrapper); + }; + + Tags.prototype.createTag = function (decorated, params) { + var term = $.trim(params.term); + + if (term === '') { + return null; + } + + return { + id: term, + text: term + }; + }; + + Tags.prototype.insertTag = function (_, data, tag) { + data.unshift(tag); + }; + + Tags.prototype._removeOldTags = function (_) { + var tag = this._lastTag; + + var $options = this.$element.find('option[data-select2-tag]'); + + $options.each(function () { + if (this.selected) { + return; + } + + $(this).remove(); + }); + }; + + return Tags; +}); + +S2.define('select2/data/tokenizer',[ + 'jquery' +], function ($) { + function Tokenizer (decorated, $element, options) { + var tokenizer = options.get('tokenizer'); + + if (tokenizer !== undefined) { + this.tokenizer = tokenizer; + } + + decorated.call(this, $element, options); + } + + Tokenizer.prototype.bind = function (decorated, container, $container) { + decorated.call(this, container, $container); + + this.$search = container.dropdown.$search || container.selection.$search || + $container.find('.select2-search__field'); + }; + + Tokenizer.prototype.query = function (decorated, params, callback) { + var self = this; + + function createAndSelect (data) { + // Normalize the data object so we can use it for checks + var item = self._normalizeItem(data); + + // Check if the data object already exists as a tag + // Select it if it doesn't + var $existingOptions = self.$element.find('option').filter(function () { + return $(this).val() === item.id; + }); + + // If an existing option wasn't found for it, create the option + if (!$existingOptions.length) { + var $option = self.option(item); + $option.attr('data-select2-tag', true); + + self._removeOldTags(); + self.addOptions([$option]); + } + + // Select the item, now that we know there is an option for it + select(item); + } + + function select (data) { + self.trigger('select', { + data: data + }); + } + + params.term = params.term || ''; + + var tokenData = this.tokenizer(params, this.options, createAndSelect); + + if (tokenData.term !== params.term) { + // Replace the search term if we have the search box + if (this.$search.length) { + this.$search.val(tokenData.term); + this.$search.focus(); + } + + params.term = tokenData.term; + } + + decorated.call(this, params, callback); + }; + + Tokenizer.prototype.tokenizer = function (_, params, options, callback) { + var separators = options.get('tokenSeparators') || []; + var term = params.term; + var i = 0; + + var createTag = this.createTag || function (params) { + return { + id: params.term, + text: params.term + }; + }; + + while (i < term.length) { + var termChar = term[i]; + + if ($.inArray(termChar, separators) === -1) { + i++; + + continue; + } + + var part = term.substr(0, i); + var partParams = $.extend({}, params, { + term: part + }); + + var data = createTag(partParams); + + if (data == null) { + i++; + continue; + } + + callback(data); + + // Reset the term to not include the tokenized portion + term = term.substr(i + 1) || ''; + i = 0; + } + + return { + term: term + }; + }; + + return Tokenizer; +}); + +S2.define('select2/data/minimumInputLength',[ + +], function () { + function MinimumInputLength (decorated, $e, options) { + this.minimumInputLength = options.get('minimumInputLength'); + + decorated.call(this, $e, options); + } + + MinimumInputLength.prototype.query = function (decorated, params, callback) { + params.term = params.term || ''; + + if (params.term.length < this.minimumInputLength) { + this.trigger('results:message', { + message: 'inputTooShort', + args: { + minimum: this.minimumInputLength, + input: params.term, + params: params + } + }); + + return; + } + + decorated.call(this, params, callback); + }; + + return MinimumInputLength; +}); + +S2.define('select2/data/maximumInputLength',[ + +], function () { + function MaximumInputLength (decorated, $e, options) { + this.maximumInputLength = options.get('maximumInputLength'); + + decorated.call(this, $e, options); + } + + MaximumInputLength.prototype.query = function (decorated, params, callback) { + params.term = params.term || ''; + + if (this.maximumInputLength > 0 && + params.term.length > this.maximumInputLength) { + this.trigger('results:message', { + message: 'inputTooLong', + args: { + maximum: this.maximumInputLength, + input: params.term, + params: params + } + }); + + return; + } + + decorated.call(this, params, callback); + }; + + return MaximumInputLength; +}); + +S2.define('select2/data/maximumSelectionLength',[ + +], function (){ + function MaximumSelectionLength (decorated, $e, options) { + this.maximumSelectionLength = options.get('maximumSelectionLength'); + + decorated.call(this, $e, options); + } + + MaximumSelectionLength.prototype.query = + function (decorated, params, callback) { + var self = this; + + this.current(function (currentData) { + var count = currentData != null ? currentData.length : 0; + if (self.maximumSelectionLength > 0 && + count >= self.maximumSelectionLength) { + self.trigger('results:message', { + message: 'maximumSelected', + args: { + maximum: self.maximumSelectionLength + } + }); + return; + } + decorated.call(self, params, callback); + }); + }; + + return MaximumSelectionLength; +}); + +S2.define('select2/dropdown',[ + 'jquery', + './utils' +], function ($, Utils) { + function Dropdown ($element, options) { + this.$element = $element; + this.options = options; + + Dropdown.__super__.constructor.call(this); + } + + Utils.Extend(Dropdown, Utils.Observable); + + Dropdown.prototype.render = function () { + var $dropdown = $( + '' + + '' + + '' + ); + + $dropdown.attr('dir', this.options.get('dir')); + + this.$dropdown = $dropdown; + + return $dropdown; + }; + + Dropdown.prototype.bind = function () { + // Should be implemented in subclasses + }; + + Dropdown.prototype.position = function ($dropdown, $container) { + // Should be implemented in subclasses + }; + + Dropdown.prototype.destroy = function () { + // Remove the dropdown from the DOM + this.$dropdown.remove(); + }; + + return Dropdown; +}); + +S2.define('select2/dropdown/search',[ + 'jquery', + '../utils' +], function ($, Utils) { + function Search () { } + + Search.prototype.render = function (decorated) { + var $rendered = decorated.call(this); + + var $search = $( + '' + + '' + + '' + ); + + this.$searchContainer = $search; + this.$search = $search.find('input'); + + $rendered.prepend($search); + + return $rendered; + }; + + Search.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + this.$search.on('keydown', function (evt) { + self.trigger('keypress', evt); + + self._keyUpPrevented = evt.isDefaultPrevented(); + }); + + // Workaround for browsers which do not support the `input` event + // This will prevent double-triggering of events for browsers which support + // both the `keyup` and `input` events. + this.$search.on('input', function (evt) { + // Unbind the duplicated `keyup` event + $(this).off('keyup'); + }); + + this.$search.on('keyup input', function (evt) { + self.handleSearch(evt); + }); + + container.on('open', function () { + self.$search.attr('tabindex', 0); + + self.$search.focus(); + + window.setTimeout(function () { + self.$search.focus(); + }, 0); + }); + + container.on('close', function () { + self.$search.attr('tabindex', -1); + + self.$search.val(''); + self.$search.blur(); + }); + + container.on('focus', function () { + if (!container.isOpen()) { + self.$search.focus(); + } + }); + + container.on('results:all', function (params) { + if (params.query.term == null || params.query.term === '') { + var showSearch = self.showSearch(params); + + if (showSearch) { + self.$searchContainer.removeClass('select2-search--hide'); + } else { + self.$searchContainer.addClass('select2-search--hide'); + } + } + }); + }; + + Search.prototype.handleSearch = function (evt) { + if (!this._keyUpPrevented) { + var input = this.$search.val(); + + this.trigger('query', { + term: input + }); + } + + this._keyUpPrevented = false; + }; + + Search.prototype.showSearch = function (_, params) { + return true; + }; + + return Search; +}); + +S2.define('select2/dropdown/hidePlaceholder',[ + +], function () { + function HidePlaceholder (decorated, $element, options, dataAdapter) { + this.placeholder = this.normalizePlaceholder(options.get('placeholder')); + + decorated.call(this, $element, options, dataAdapter); + } + + HidePlaceholder.prototype.append = function (decorated, data) { + data.results = this.removePlaceholder(data.results); + + decorated.call(this, data); + }; + + HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) { + if (typeof placeholder === 'string') { + placeholder = { + id: '', + text: placeholder + }; + } + + return placeholder; + }; + + HidePlaceholder.prototype.removePlaceholder = function (_, data) { + var modifiedData = data.slice(0); + + for (var d = data.length - 1; d >= 0; d--) { + var item = data[d]; + + if (this.placeholder.id === item.id) { + modifiedData.splice(d, 1); + } + } + + return modifiedData; + }; + + return HidePlaceholder; +}); + +S2.define('select2/dropdown/infiniteScroll',[ + 'jquery' +], function ($) { + function InfiniteScroll (decorated, $element, options, dataAdapter) { + this.lastParams = {}; + + decorated.call(this, $element, options, dataAdapter); + + this.$loadingMore = this.createLoadingMore(); + this.loading = false; + } + + InfiniteScroll.prototype.append = function (decorated, data) { + this.$loadingMore.remove(); + this.loading = false; + + decorated.call(this, data); + + if (this.showLoadingMore(data)) { + this.$results.append(this.$loadingMore); + } + }; + + InfiniteScroll.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('query', function (params) { + self.lastParams = params; + self.loading = true; + }); + + container.on('query:append', function (params) { + self.lastParams = params; + self.loading = true; + }); + + this.$results.on('scroll', function () { + var isLoadMoreVisible = $.contains( + document.documentElement, + self.$loadingMore[0] + ); + + if (self.loading || !isLoadMoreVisible) { + return; + } + + var currentOffset = self.$results.offset().top + + self.$results.outerHeight(false); + var loadingMoreOffset = self.$loadingMore.offset().top + + self.$loadingMore.outerHeight(false); + + if (currentOffset + 50 >= loadingMoreOffset) { + self.loadMore(); + } + }); + }; + + InfiniteScroll.prototype.loadMore = function () { + this.loading = true; + + var params = $.extend({}, {page: 1}, this.lastParams); + + params.page++; + + this.trigger('query:append', params); + }; + + InfiniteScroll.prototype.showLoadingMore = function (_, data) { + return data.pagination && data.pagination.more; + }; + + InfiniteScroll.prototype.createLoadingMore = function () { + var $option = $( + '
      • ' + ); + + var message = this.options.get('translations').get('loadingMore'); + + $option.html(message(this.lastParams)); + + return $option; + }; + + return InfiniteScroll; +}); + +S2.define('select2/dropdown/attachBody',[ + 'jquery', + '../utils' +], function ($, Utils) { + function AttachBody (decorated, $element, options) { + this.$dropdownParent = options.get('dropdownParent') || $(document.body); + + decorated.call(this, $element, options); + } + + AttachBody.prototype.bind = function (decorated, container, $container) { + var self = this; + + var setupResultsEvents = false; + + decorated.call(this, container, $container); + + container.on('open', function () { + self._showDropdown(); + self._attachPositioningHandler(container); + + if (!setupResultsEvents) { + setupResultsEvents = true; + + container.on('results:all', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + + container.on('results:append', function () { + self._positionDropdown(); + self._resizeDropdown(); + }); + } + }); + + container.on('close', function () { + self._hideDropdown(); + self._detachPositioningHandler(container); + }); + + this.$dropdownContainer.on('mousedown', function (evt) { + evt.stopPropagation(); + }); + }; + + AttachBody.prototype.destroy = function (decorated) { + decorated.call(this); + + this.$dropdownContainer.remove(); + }; + + AttachBody.prototype.position = function (decorated, $dropdown, $container) { + // Clone all of the container classes + $dropdown.attr('class', $container.attr('class')); + + $dropdown.removeClass('select2'); + $dropdown.addClass('select2-container--open'); + + $dropdown.css({ + position: 'absolute', + top: -999999 + }); + + this.$container = $container; + }; + + AttachBody.prototype.render = function (decorated) { + var $container = $(''); + + var $dropdown = decorated.call(this); + $container.append($dropdown); + + this.$dropdownContainer = $container; + + return $container; + }; + + AttachBody.prototype._hideDropdown = function (decorated) { + this.$dropdownContainer.detach(); + }; + + AttachBody.prototype._attachPositioningHandler = + function (decorated, container) { + var self = this; + + var scrollEvent = 'scroll.select2.' + container.id; + var resizeEvent = 'resize.select2.' + container.id; + var orientationEvent = 'orientationchange.select2.' + container.id; + + var $watchers = this.$container.parents().filter(Utils.hasScroll); + $watchers.each(function () { + Utils.StoreData(this, 'select2-scroll-position', { + x: $(this).scrollLeft(), + y: $(this).scrollTop() + }); + }); + + $watchers.on(scrollEvent, function (ev) { + var position = Utils.GetData(this, 'select2-scroll-position'); + $(this).scrollTop(position.y); + }); + + $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent, + function (e) { + self._positionDropdown(); + self._resizeDropdown(); + }); + }; + + AttachBody.prototype._detachPositioningHandler = + function (decorated, container) { + var scrollEvent = 'scroll.select2.' + container.id; + var resizeEvent = 'resize.select2.' + container.id; + var orientationEvent = 'orientationchange.select2.' + container.id; + + var $watchers = this.$container.parents().filter(Utils.hasScroll); + $watchers.off(scrollEvent); + + $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent); + }; + + AttachBody.prototype._positionDropdown = function () { + var $window = $(window); + + var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above'); + var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below'); + + var newDirection = null; + + var offset = this.$container.offset(); + + offset.bottom = offset.top + this.$container.outerHeight(false); + + var container = { + height: this.$container.outerHeight(false) + }; + + container.top = offset.top; + container.bottom = offset.top + container.height; + + var dropdown = { + height: this.$dropdown.outerHeight(false) + }; + + var viewport = { + top: $window.scrollTop(), + bottom: $window.scrollTop() + $window.height() + }; + + var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); + var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); + + var css = { + left: offset.left, + top: container.bottom + }; + + // Determine what the parent element is to use for calculating the offset + var $offsetParent = this.$dropdownParent; + + // For statically positioned elements, we need to get the element + // that is determining the offset + if ($offsetParent.css('position') === 'static') { + $offsetParent = $offsetParent.offsetParent(); + } + + var parentOffset = $offsetParent.offset(); + + css.top -= parentOffset.top; + css.left -= parentOffset.left; + + if (!isCurrentlyAbove && !isCurrentlyBelow) { + newDirection = 'below'; + } + + if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { + newDirection = 'above'; + } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { + newDirection = 'below'; + } + + if (newDirection == 'above' || + (isCurrentlyAbove && newDirection !== 'below')) { + css.top = container.top - parentOffset.top - dropdown.height; + } + + if (newDirection != null) { + this.$dropdown + .removeClass('select2-dropdown--below select2-dropdown--above') + .addClass('select2-dropdown--' + newDirection); + this.$container + .removeClass('select2-container--below select2-container--above') + .addClass('select2-container--' + newDirection); + } + + this.$dropdownContainer.css(css); + }; + + AttachBody.prototype._resizeDropdown = function () { + var css = { + width: this.$container.outerWidth(false) + 'px' + }; + + if (this.options.get('dropdownAutoWidth')) { + css.minWidth = css.width; + css.position = 'relative'; + css.width = 'auto'; + } + + this.$dropdown.css(css); + }; + + AttachBody.prototype._showDropdown = function (decorated) { + this.$dropdownContainer.appendTo(this.$dropdownParent); + + this._positionDropdown(); + this._resizeDropdown(); + }; + + return AttachBody; +}); + +S2.define('select2/dropdown/minimumResultsForSearch',[ + +], function () { + function countResults (data) { + var count = 0; + + for (var d = 0; d < data.length; d++) { + var item = data[d]; + + if (item.children) { + count += countResults(item.children); + } else { + count++; + } + } + + return count; + } + + function MinimumResultsForSearch (decorated, $element, options, dataAdapter) { + this.minimumResultsForSearch = options.get('minimumResultsForSearch'); + + if (this.minimumResultsForSearch < 0) { + this.minimumResultsForSearch = Infinity; + } + + decorated.call(this, $element, options, dataAdapter); + } + + MinimumResultsForSearch.prototype.showSearch = function (decorated, params) { + if (countResults(params.data.results) < this.minimumResultsForSearch) { + return false; + } + + return decorated.call(this, params); + }; + + return MinimumResultsForSearch; +}); + +S2.define('select2/dropdown/selectOnClose',[ + '../utils' +], function (Utils) { + function SelectOnClose () { } + + SelectOnClose.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('close', function (params) { + self._handleSelectOnClose(params); + }); + }; + + SelectOnClose.prototype._handleSelectOnClose = function (_, params) { + if (params && params.originalSelect2Event != null) { + var event = params.originalSelect2Event; + + // Don't select an item if the close event was triggered from a select or + // unselect event + if (event._type === 'select' || event._type === 'unselect') { + return; + } + } + + var $highlightedResults = this.getHighlightedResults(); + + // Only select highlighted results + if ($highlightedResults.length < 1) { + return; + } + + var data = Utils.GetData($highlightedResults[0], 'data'); + + // Don't re-select already selected resulte + if ( + (data.element != null && data.element.selected) || + (data.element == null && data.selected) + ) { + return; + } + + this.trigger('select', { + data: data + }); + }; + + return SelectOnClose; +}); + +S2.define('select2/dropdown/closeOnSelect',[ + +], function () { + function CloseOnSelect () { } + + CloseOnSelect.prototype.bind = function (decorated, container, $container) { + var self = this; + + decorated.call(this, container, $container); + + container.on('select', function (evt) { + self._selectTriggered(evt); + }); + + container.on('unselect', function (evt) { + self._selectTriggered(evt); + }); + }; + + CloseOnSelect.prototype._selectTriggered = function (_, evt) { + var originalEvent = evt.originalEvent; + + // Don't close if the control key is being held + if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) { + return; + } + + this.trigger('close', { + originalEvent: originalEvent, + originalSelect2Event: evt + }); + }; + + return CloseOnSelect; +}); + +S2.define('select2/i18n/en',[],function () { + // English + return { + errorLoading: function () { + return 'The results could not be loaded.'; + }, + inputTooLong: function (args) { + var overChars = args.input.length - args.maximum; + + var message = 'Please delete ' + overChars + ' character'; + + if (overChars != 1) { + message += 's'; + } + + return message; + }, + inputTooShort: function (args) { + var remainingChars = args.minimum - args.input.length; + + var message = 'Please enter ' + remainingChars + ' or more characters'; + + return message; + }, + loadingMore: function () { + return 'Loading more results…'; + }, + maximumSelected: function (args) { + var message = 'You can only select ' + args.maximum + ' item'; + + if (args.maximum != 1) { + message += 's'; + } + + return message; + }, + noResults: function () { + return 'No results found'; + }, + searching: function () { + return 'Searching…'; + }, + removeAllItems: function () { + return 'Remove all items'; + } + }; +}); + +S2.define('select2/defaults',[ + 'jquery', + 'require', + + './results', + + './selection/single', + './selection/multiple', + './selection/placeholder', + './selection/allowClear', + './selection/search', + './selection/eventRelay', + + './utils', + './translation', + './diacritics', + + './data/select', + './data/array', + './data/ajax', + './data/tags', + './data/tokenizer', + './data/minimumInputLength', + './data/maximumInputLength', + './data/maximumSelectionLength', + + './dropdown', + './dropdown/search', + './dropdown/hidePlaceholder', + './dropdown/infiniteScroll', + './dropdown/attachBody', + './dropdown/minimumResultsForSearch', + './dropdown/selectOnClose', + './dropdown/closeOnSelect', + + './i18n/en' +], function ($, require, + + ResultsList, + + SingleSelection, MultipleSelection, Placeholder, AllowClear, + SelectionSearch, EventRelay, + + Utils, Translation, DIACRITICS, + + SelectData, ArrayData, AjaxData, Tags, Tokenizer, + MinimumInputLength, MaximumInputLength, MaximumSelectionLength, + + Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, + AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect, + + EnglishTranslation) { + function Defaults () { + this.reset(); + } + + Defaults.prototype.apply = function (options) { + options = $.extend(true, {}, this.defaults, options); + + if (options.dataAdapter == null) { + if (options.ajax != null) { + options.dataAdapter = AjaxData; + } else if (options.data != null) { + options.dataAdapter = ArrayData; + } else { + options.dataAdapter = SelectData; + } + + if (options.minimumInputLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MinimumInputLength + ); + } + + if (options.maximumInputLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MaximumInputLength + ); + } + + if (options.maximumSelectionLength > 0) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + MaximumSelectionLength + ); + } + + if (options.tags) { + options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags); + } + + if (options.tokenSeparators != null || options.tokenizer != null) { + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + Tokenizer + ); + } + + if (options.query != null) { + var Query = require(options.amdBase + 'compat/query'); + + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + Query + ); + } + + if (options.initSelection != null) { + var InitSelection = require(options.amdBase + 'compat/initSelection'); + + options.dataAdapter = Utils.Decorate( + options.dataAdapter, + InitSelection + ); + } + } + + if (options.resultsAdapter == null) { + options.resultsAdapter = ResultsList; + + if (options.ajax != null) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + InfiniteScroll + ); + } + + if (options.placeholder != null) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + HidePlaceholder + ); + } + + if (options.selectOnClose) { + options.resultsAdapter = Utils.Decorate( + options.resultsAdapter, + SelectOnClose + ); + } + } + + if (options.dropdownAdapter == null) { + if (options.multiple) { + options.dropdownAdapter = Dropdown; + } else { + var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch); + + options.dropdownAdapter = SearchableDropdown; + } + + if (options.minimumResultsForSearch !== 0) { + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + MinimumResultsForSearch + ); + } + + if (options.closeOnSelect) { + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + CloseOnSelect + ); + } + + if ( + options.dropdownCssClass != null || + options.dropdownCss != null || + options.adaptDropdownCssClass != null + ) { + var DropdownCSS = require(options.amdBase + 'compat/dropdownCss'); + + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + DropdownCSS + ); + } + + options.dropdownAdapter = Utils.Decorate( + options.dropdownAdapter, + AttachBody + ); + } + + if (options.selectionAdapter == null) { + if (options.multiple) { + options.selectionAdapter = MultipleSelection; + } else { + options.selectionAdapter = SingleSelection; + } + + // Add the placeholder mixin if a placeholder was specified + if (options.placeholder != null) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + Placeholder + ); + } + + if (options.allowClear) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + AllowClear + ); + } + + if (options.multiple) { + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + SelectionSearch + ); + } + + if ( + options.containerCssClass != null || + options.containerCss != null || + options.adaptContainerCssClass != null + ) { + var ContainerCSS = require(options.amdBase + 'compat/containerCss'); + + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + ContainerCSS + ); + } + + options.selectionAdapter = Utils.Decorate( + options.selectionAdapter, + EventRelay + ); + } + + if (typeof options.language === 'string') { + // Check if the language is specified with a region + if (options.language.indexOf('-') > 0) { + // Extract the region information if it is included + var languageParts = options.language.split('-'); + var baseLanguage = languageParts[0]; + + options.language = [options.language, baseLanguage]; + } else { + options.language = [options.language]; + } + } + + if ($.isArray(options.language)) { + var languages = new Translation(); + options.language.push('en'); + + var languageNames = options.language; + + for (var l = 0; l < languageNames.length; l++) { + var name = languageNames[l]; + var language = {}; + + try { + // Try to load it with the original name + language = Translation.loadPath(name); + } catch (e) { + try { + // If we couldn't load it, check if it wasn't the full path + name = this.defaults.amdLanguageBase + name; + language = Translation.loadPath(name); + } catch (ex) { + // The translation could not be loaded at all. Sometimes this is + // because of a configuration problem, other times this can be + // because of how Select2 helps load all possible translation files. + if (options.debug && window.console && console.warn) { + console.warn( + 'Select2: The language file for "' + name + '" could not be ' + + 'automatically loaded. A fallback will be used instead.' + ); + } + + continue; + } + } + + languages.extend(language); + } + + options.translations = languages; + } else { + var baseTranslation = Translation.loadPath( + this.defaults.amdLanguageBase + 'en' + ); + var customTranslation = new Translation(options.language); + + customTranslation.extend(baseTranslation); + + options.translations = customTranslation; + } + + return options; + }; + + Defaults.prototype.reset = function () { + function stripDiacritics (text) { + // Used 'uni range + named function' from http://jsperf.com/diacritics/18 + function match(a) { + return DIACRITICS[a] || a; + } + + return text.replace(/[^\u0000-\u007E]/g, match); + } + + function matcher (params, data) { + // Always return the object if there is nothing to compare + if ($.trim(params.term) === '') { + return data; + } + + // Do a recursive check for options with children + if (data.children && data.children.length > 0) { + // Clone the data object if there are children + // This is required as we modify the object to remove any non-matches + var match = $.extend(true, {}, data); + + // Check each child of the option + for (var c = data.children.length - 1; c >= 0; c--) { + var child = data.children[c]; + + var matches = matcher(params, child); + + // If there wasn't a match, remove the object in the array + if (matches == null) { + match.children.splice(c, 1); + } + } + + // If any children matched, return the new object + if (match.children.length > 0) { + return match; + } + + // If there were no matching children, check just the plain object + return matcher(params, match); + } + + var original = stripDiacritics(data.text).toUpperCase(); + var term = stripDiacritics(params.term).toUpperCase(); + + // Check if the text contains the term + if (original.indexOf(term) > -1) { + return data; + } + + // If it doesn't contain the term, don't return anything + return null; + } + + this.defaults = { + amdBase: './', + amdLanguageBase: './i18n/', + closeOnSelect: true, + debug: false, + dropdownAutoWidth: false, + escapeMarkup: Utils.escapeMarkup, + language: EnglishTranslation, + matcher: matcher, + minimumInputLength: 0, + maximumInputLength: 0, + maximumSelectionLength: 0, + minimumResultsForSearch: 0, + selectOnClose: false, + scrollAfterSelect: false, + sorter: function (data) { + return data; + }, + templateResult: function (result) { + return result.text; + }, + templateSelection: function (selection) { + return selection.text; + }, + theme: 'default', + width: 'resolve' + }; + }; + + Defaults.prototype.set = function (key, value) { + var camelKey = $.camelCase(key); + + var data = {}; + data[camelKey] = value; + + var convertedData = Utils._convertData(data); + + $.extend(true, this.defaults, convertedData); + }; + + var defaults = new Defaults(); + + return defaults; +}); + +S2.define('select2/options',[ + 'require', + 'jquery', + './defaults', + './utils' +], function (require, $, Defaults, Utils) { + function Options (options, $element) { + this.options = options; + + if ($element != null) { + this.fromElement($element); + } + + this.options = Defaults.apply(this.options); + + if ($element && $element.is('input')) { + var InputCompat = require(this.get('amdBase') + 'compat/inputData'); + + this.options.dataAdapter = Utils.Decorate( + this.options.dataAdapter, + InputCompat + ); + } + } + + Options.prototype.fromElement = function ($e) { + var excludedData = ['select2']; + + if (this.options.multiple == null) { + this.options.multiple = $e.prop('multiple'); + } + + if (this.options.disabled == null) { + this.options.disabled = $e.prop('disabled'); + } + + if (this.options.language == null) { + if ($e.prop('lang')) { + this.options.language = $e.prop('lang').toLowerCase(); + } else if ($e.closest('[lang]').prop('lang')) { + this.options.language = $e.closest('[lang]').prop('lang'); + } + } + + if (this.options.dir == null) { + if ($e.prop('dir')) { + this.options.dir = $e.prop('dir'); + } else if ($e.closest('[dir]').prop('dir')) { + this.options.dir = $e.closest('[dir]').prop('dir'); + } else { + this.options.dir = 'ltr'; + } + } + + $e.prop('disabled', this.options.disabled); + $e.prop('multiple', this.options.multiple); + + if (Utils.GetData($e[0], 'select2Tags')) { + if (this.options.debug && window.console && console.warn) { + console.warn( + 'Select2: The `data-select2-tags` attribute has been changed to ' + + 'use the `data-data` and `data-tags="true"` attributes and will be ' + + 'removed in future versions of Select2.' + ); + } + + Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); + Utils.StoreData($e[0], 'tags', true); + } + + if (Utils.GetData($e[0], 'ajaxUrl')) { + if (this.options.debug && window.console && console.warn) { + console.warn( + 'Select2: The `data-ajax-url` attribute has been changed to ' + + '`data-ajax--url` and support for the old attribute will be removed' + + ' in future versions of Select2.' + ); + } + + $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); + Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); + } + + var dataset = {}; + + function upperCaseLetter(_, letter) { + return letter.toUpperCase(); + } + + // Pre-load all of the attributes which are prefixed with `data-` + for (var attr = 0; attr < $e[0].attributes.length; attr++) { + var attributeName = $e[0].attributes[attr].name; + var prefix = 'data-'; + + if (attributeName.substr(0, prefix.length) == prefix) { + // Get the contents of the attribute after `data-` + var dataName = attributeName.substring(prefix.length); + + // Get the data contents from the consistent source + // This is more than likely the jQuery data helper + var dataValue = Utils.GetData($e[0], dataName); + + // camelCase the attribute name to match the spec + var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter); + + // Store the data attribute contents into the dataset since + dataset[camelDataName] = dataValue; + } + } + + // Prefer the element's `dataset` attribute if it exists + // jQuery 1.x does not correctly handle data attributes with multiple dashes + if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { + dataset = $.extend(true, {}, $e[0].dataset, dataset); + } + + // Prefer our internal data cache if it exists + var data = $.extend(true, {}, Utils.GetData($e[0]), dataset); + + data = Utils._convertData(data); + + for (var key in data) { + if ($.inArray(key, excludedData) > -1) { + continue; + } + + if ($.isPlainObject(this.options[key])) { + $.extend(this.options[key], data[key]); + } else { + this.options[key] = data[key]; + } + } + + return this; + }; + + Options.prototype.get = function (key) { + return this.options[key]; + }; + + Options.prototype.set = function (key, val) { + this.options[key] = val; + }; + + return Options; +}); + +S2.define('select2/core',[ + 'jquery', + './options', + './utils', + './keys' +], function ($, Options, Utils, KEYS) { + var Select2 = function ($element, options) { + if (Utils.GetData($element[0], 'select2') != null) { + Utils.GetData($element[0], 'select2').destroy(); + } + + this.$element = $element; + + this.id = this._generateId($element); + + options = options || {}; + + this.options = new Options(options, $element); + + Select2.__super__.constructor.call(this); + + // Set up the tabindex + + var tabindex = $element.attr('tabindex') || 0; + Utils.StoreData($element[0], 'old-tabindex', tabindex); + $element.attr('tabindex', '-1'); + + // Set up containers and adapters + + var DataAdapter = this.options.get('dataAdapter'); + this.dataAdapter = new DataAdapter($element, this.options); + + var $container = this.render(); + + this._placeContainer($container); + + var SelectionAdapter = this.options.get('selectionAdapter'); + this.selection = new SelectionAdapter($element, this.options); + this.$selection = this.selection.render(); + + this.selection.position(this.$selection, $container); + + var DropdownAdapter = this.options.get('dropdownAdapter'); + this.dropdown = new DropdownAdapter($element, this.options); + this.$dropdown = this.dropdown.render(); + + this.dropdown.position(this.$dropdown, $container); + + var ResultsAdapter = this.options.get('resultsAdapter'); + this.results = new ResultsAdapter($element, this.options, this.dataAdapter); + this.$results = this.results.render(); + + this.results.position(this.$results, this.$dropdown); + + // Bind events + + var self = this; + + // Bind the container to all of the adapters + this._bindAdapters(); + + // Register any DOM event handlers + this._registerDomEvents(); + + // Register any internal event handlers + this._registerDataEvents(); + this._registerSelectionEvents(); + this._registerDropdownEvents(); + this._registerResultsEvents(); + this._registerEvents(); + + // Set the initial state + this.dataAdapter.current(function (initialData) { + self.trigger('selection:update', { + data: initialData + }); + }); + + // Hide the original select + $element.addClass('select2-hidden-accessible'); + $element.attr('aria-hidden', 'true'); + + // Synchronize any monitored attributes + this._syncAttributes(); + + Utils.StoreData($element[0], 'select2', this); + + // Ensure backwards compatibility with $element.data('select2'). + $element.data('select2', this); + }; + + Utils.Extend(Select2, Utils.Observable); + + Select2.prototype._generateId = function ($element) { + var id = ''; + + if ($element.attr('id') != null) { + id = $element.attr('id'); + } else if ($element.attr('name') != null) { + id = $element.attr('name') + '-' + Utils.generateChars(2); + } else { + id = Utils.generateChars(4); + } + + id = id.replace(/(:|\.|\[|\]|,)/g, ''); + id = 'select2-' + id; + + return id; + }; + + Select2.prototype._placeContainer = function ($container) { + $container.insertAfter(this.$element); + + var width = this._resolveWidth(this.$element, this.options.get('width')); + + if (width != null) { + $container.css('width', width); + } + }; + + Select2.prototype._resolveWidth = function ($element, method) { + var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; + + if (method == 'resolve') { + var styleWidth = this._resolveWidth($element, 'style'); + + if (styleWidth != null) { + return styleWidth; + } + + return this._resolveWidth($element, 'element'); + } + + if (method == 'element') { + var elementWidth = $element.outerWidth(false); + + if (elementWidth <= 0) { + return 'auto'; + } + + return elementWidth + 'px'; + } + + if (method == 'style') { + var style = $element.attr('style'); + + if (typeof(style) !== 'string') { + return null; + } + + var attrs = style.split(';'); + + for (var i = 0, l = attrs.length; i < l; i = i + 1) { + var attr = attrs[i].replace(/\s/g, ''); + var matches = attr.match(WIDTH); + + if (matches !== null && matches.length >= 1) { + return matches[1]; + } + } + + return null; + } + + return method; + }; + + Select2.prototype._bindAdapters = function () { + this.dataAdapter.bind(this, this.$container); + this.selection.bind(this, this.$container); + + this.dropdown.bind(this, this.$container); + this.results.bind(this, this.$container); + }; + + Select2.prototype._registerDomEvents = function () { + var self = this; + + this.$element.on('change.select2', function () { + self.dataAdapter.current(function (data) { + self.trigger('selection:update', { + data: data + }); + }); + }); + + this.$element.on('focus.select2', function (evt) { + self.trigger('focus', evt); + }); + + this._syncA = Utils.bind(this._syncAttributes, this); + this._syncS = Utils.bind(this._syncSubtree, this); + + if (this.$element[0].attachEvent) { + this.$element[0].attachEvent('onpropertychange', this._syncA); + } + + var observer = window.MutationObserver || + window.WebKitMutationObserver || + window.MozMutationObserver + ; + + if (observer != null) { + this._observer = new observer(function (mutations) { + $.each(mutations, self._syncA); + $.each(mutations, self._syncS); + }); + this._observer.observe(this.$element[0], { + attributes: true, + childList: true, + subtree: false + }); + } else if (this.$element[0].addEventListener) { + this.$element[0].addEventListener( + 'DOMAttrModified', + self._syncA, + false + ); + this.$element[0].addEventListener( + 'DOMNodeInserted', + self._syncS, + false + ); + this.$element[0].addEventListener( + 'DOMNodeRemoved', + self._syncS, + false + ); + } + }; + + Select2.prototype._registerDataEvents = function () { + var self = this; + + this.dataAdapter.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerSelectionEvents = function () { + var self = this; + var nonRelayEvents = ['toggle', 'focus']; + + this.selection.on('toggle', function () { + self.toggleDropdown(); + }); + + this.selection.on('focus', function (params) { + self.focus(params); + }); + + this.selection.on('*', function (name, params) { + if ($.inArray(name, nonRelayEvents) !== -1) { + return; + } + + self.trigger(name, params); + }); + }; + + Select2.prototype._registerDropdownEvents = function () { + var self = this; + + this.dropdown.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerResultsEvents = function () { + var self = this; + + this.results.on('*', function (name, params) { + self.trigger(name, params); + }); + }; + + Select2.prototype._registerEvents = function () { + var self = this; + + this.on('open', function () { + self.$container.addClass('select2-container--open'); + }); + + this.on('close', function () { + self.$container.removeClass('select2-container--open'); + }); + + this.on('enable', function () { + self.$container.removeClass('select2-container--disabled'); + }); + + this.on('disable', function () { + self.$container.addClass('select2-container--disabled'); + }); + + this.on('blur', function () { + self.$container.removeClass('select2-container--focus'); + }); + + this.on('query', function (params) { + if (!self.isOpen()) { + self.trigger('open', {}); + } + + this.dataAdapter.query(params, function (data) { + self.trigger('results:all', { + data: data, + query: params + }); + }); + }); + + this.on('query:append', function (params) { + this.dataAdapter.query(params, function (data) { + self.trigger('results:append', { + data: data, + query: params + }); + }); + }); + + this.on('keypress', function (evt) { + var key = evt.which; + + if (self.isOpen()) { + if (key === KEYS.ESC || key === KEYS.TAB || + (key === KEYS.UP && evt.altKey)) { + self.close(); + + evt.preventDefault(); + } else if (key === KEYS.ENTER) { + self.trigger('results:select', {}); + + evt.preventDefault(); + } else if ((key === KEYS.SPACE && evt.ctrlKey)) { + self.trigger('results:toggle', {}); + + evt.preventDefault(); + } else if (key === KEYS.UP) { + self.trigger('results:previous', {}); + + evt.preventDefault(); + } else if (key === KEYS.DOWN) { + self.trigger('results:next', {}); + + evt.preventDefault(); + } + } else { + if (key === KEYS.ENTER || key === KEYS.SPACE || + (key === KEYS.DOWN && evt.altKey)) { + self.open(); + + evt.preventDefault(); + } + } + }); + }; + + Select2.prototype._syncAttributes = function () { + this.options.set('disabled', this.$element.prop('disabled')); + + if (this.options.get('disabled')) { + if (this.isOpen()) { + this.close(); + } + + this.trigger('disable', {}); + } else { + this.trigger('enable', {}); + } + }; + + Select2.prototype._syncSubtree = function (evt, mutations) { + var changed = false; + var self = this; + + // Ignore any mutation events raised for elements that aren't options or + // optgroups. This handles the case when the select element is destroyed + if ( + evt && evt.target && ( + evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP' + ) + ) { + return; + } + + if (!mutations) { + // If mutation events aren't supported, then we can only assume that the + // change affected the selections + changed = true; + } else if (mutations.addedNodes && mutations.addedNodes.length > 0) { + for (var n = 0; n < mutations.addedNodes.length; n++) { + var node = mutations.addedNodes[n]; + + if (node.selected) { + changed = true; + } + } + } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { + changed = true; + } + + // Only re-pull the data if we think there is a change + if (changed) { + this.dataAdapter.current(function (currentData) { + self.trigger('selection:update', { + data: currentData + }); + }); + } + }; + + /** + * Override the trigger method to automatically trigger pre-events when + * there are events that can be prevented. + */ + Select2.prototype.trigger = function (name, args) { + var actualTrigger = Select2.__super__.trigger; + var preTriggerMap = { + 'open': 'opening', + 'close': 'closing', + 'select': 'selecting', + 'unselect': 'unselecting', + 'clear': 'clearing' + }; + + if (args === undefined) { + args = {}; + } + + if (name in preTriggerMap) { + var preTriggerName = preTriggerMap[name]; + var preTriggerArgs = { + prevented: false, + name: name, + args: args + }; + + actualTrigger.call(this, preTriggerName, preTriggerArgs); + + if (preTriggerArgs.prevented) { + args.prevented = true; + + return; + } + } + + actualTrigger.call(this, name, args); + }; + + Select2.prototype.toggleDropdown = function () { + if (this.options.get('disabled')) { + return; + } + + if (this.isOpen()) { + this.close(); + } else { + this.open(); + } + }; + + Select2.prototype.open = function () { + if (this.isOpen()) { + return; + } + + this.trigger('query', {}); + }; + + Select2.prototype.close = function () { + if (!this.isOpen()) { + return; + } + + this.trigger('close', {}); + }; + + Select2.prototype.isOpen = function () { + return this.$container.hasClass('select2-container--open'); + }; + + Select2.prototype.hasFocus = function () { + return this.$container.hasClass('select2-container--focus'); + }; + + Select2.prototype.focus = function (data) { + // No need to re-trigger focus events if we are already focused + if (this.hasFocus()) { + return; + } + + this.$container.addClass('select2-container--focus'); + this.trigger('focus', {}); + }; + + Select2.prototype.enable = function (args) { + if (this.options.get('debug') && window.console && console.warn) { + console.warn( + 'Select2: The `select2("enable")` method has been deprecated and will' + + ' be removed in later Select2 versions. Use $element.prop("disabled")' + + ' instead.' + ); + } + + if (args == null || args.length === 0) { + args = [true]; + } + + var disabled = !args[0]; + + this.$element.prop('disabled', disabled); + }; + + Select2.prototype.data = function () { + if (this.options.get('debug') && + arguments.length > 0 && window.console && console.warn) { + console.warn( + 'Select2: Data can no longer be set using `select2("data")`. You ' + + 'should consider setting the value instead using `$element.val()`.' + ); + } + + var data = []; + + this.dataAdapter.current(function (currentData) { + data = currentData; + }); + + return data; + }; + + Select2.prototype.val = function (args) { + if (this.options.get('debug') && window.console && console.warn) { + console.warn( + 'Select2: The `select2("val")` method has been deprecated and will be' + + ' removed in later Select2 versions. Use $element.val() instead.' + ); + } + + if (args == null || args.length === 0) { + return this.$element.val(); + } + + var newVal = args[0]; + + if ($.isArray(newVal)) { + newVal = $.map(newVal, function (obj) { + return obj.toString(); + }); + } + + this.$element.val(newVal).trigger('change'); + }; + + Select2.prototype.destroy = function () { + this.$container.remove(); + + if (this.$element[0].detachEvent) { + this.$element[0].detachEvent('onpropertychange', this._syncA); + } + + if (this._observer != null) { + this._observer.disconnect(); + this._observer = null; + } else if (this.$element[0].removeEventListener) { + this.$element[0] + .removeEventListener('DOMAttrModified', this._syncA, false); + this.$element[0] + .removeEventListener('DOMNodeInserted', this._syncS, false); + this.$element[0] + .removeEventListener('DOMNodeRemoved', this._syncS, false); + } + + this._syncA = null; + this._syncS = null; + + this.$element.off('.select2'); + this.$element.attr('tabindex', + Utils.GetData(this.$element[0], 'old-tabindex')); + + this.$element.removeClass('select2-hidden-accessible'); + this.$element.attr('aria-hidden', 'false'); + Utils.RemoveData(this.$element[0]); + this.$element.removeData('select2'); + + this.dataAdapter.destroy(); + this.selection.destroy(); + this.dropdown.destroy(); + this.results.destroy(); + + this.dataAdapter = null; + this.selection = null; + this.dropdown = null; + this.results = null; + }; + + Select2.prototype.render = function () { + var $container = $( + '' + + '' + + '' + + '' + ); + + $container.attr('dir', this.options.get('dir')); + + this.$container = $container; + + this.$container.addClass('select2-container--' + this.options.get('theme')); + + Utils.StoreData($container[0], 'element', this.$element); + + return $container; + }; + + return Select2; +}); + +S2.define('jquery-mousewheel',[ + 'jquery' +], function ($) { + // Used to shim jQuery.mousewheel for non-full builds. + return $; +}); + +S2.define('jquery.select2',[ + 'jquery', + 'jquery-mousewheel', + + './select2/core', + './select2/defaults', + './select2/utils' +], function ($, _, Select2, Defaults, Utils) { + if ($.fn.select2 == null) { + // All methods that should return the element + var thisMethods = ['open', 'close', 'destroy']; + + $.fn.select2 = function (options) { + options = options || {}; + + if (typeof options === 'object') { + this.each(function () { + var instanceOptions = $.extend(true, {}, options); + + var instance = new Select2($(this), instanceOptions); + }); + + return this; + } else if (typeof options === 'string') { + var ret; + var args = Array.prototype.slice.call(arguments, 1); + + this.each(function () { + var instance = Utils.GetData(this, 'select2'); + + if (instance == null && window.console && console.error) { + console.error( + 'The select2(\'' + options + '\') method was called on an ' + + 'element that is not using Select2.' + ); + } + + ret = instance[options].apply(instance, args); + }); + + // Check if we should be returning `this` + if ($.inArray(options, thisMethods) > -1) { + return this; + } + + return ret; + } else { + throw new Error('Invalid arguments for Select2: ' + options); + } + }; + } + + if ($.fn.select2.defaults == null) { + $.fn.select2.defaults = Defaults; + } + + return Select2; +}); + + // Return the AMD loader configuration so it can be used outside of this file + return { + define: S2.define, + require: S2.require + }; +}()); + + // Autoload the jQuery bindings + // We know that all of the modules exist above this, so we're safe + var select2 = S2.require('jquery.select2'); + + // Hold the AMD module references on the jQuery function that was just loaded + // This allows Select2 to use the internal loader outside of this file, such + // as in the language files. + jQuery.fn.select2.amd = S2; + + // Return the Select2 instance for anyone who is importing it. + return select2; +})); diff --git a/assets/3rd/select2/js/select2.min.js b/assets/3rd/select2/js/select2.min.js new file mode 100755 index 00000000..ee6bf6d0 --- /dev/null +++ b/assets/3rd/select2/js/select2.min.js @@ -0,0 +1,2 @@ +/*! Select2 4.0.7 | https://github.com/select2/select2/blob/master/LICENSE.md */ +!function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,r,h,o,s,f,g,m,v,y,_,i,a,w;function b(e,t){return i.call(e,t)}function l(e,t){var n,r,i,o,s,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(s=(e=e.split("/")).length-1,y.nodeIdCompat&&w.test(e[s])&&(e[s]=e[s].replace(w,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},i.appendMany=function(e,t){if("1.7"===o.fn.jquery.substr(0,3)){var n=o();o.map(t,function(e){n=n.add(e)}),t=n}e.append(t)},i.__cache={};var n=0;return i.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null==t&&(e.id?(t=e.id,e.setAttribute("data-select2-id",t)):(e.setAttribute("data-select2-id",++n),t=n.toString())),t},i.StoreData=function(e,t,n){var r=i.GetUniqueElementId(e);i.__cache[r]||(i.__cache[r]={}),i.__cache[r][t]=n},i.GetData=function(e,t){var n=i.GetUniqueElementId(e);return t?i.__cache[n]&&null!=i.__cache[n][t]?i.__cache[n][t]:o(e).data(t):i.__cache[n]},i.RemoveData=function(e){var t=i.GetUniqueElementId(e);null!=i.__cache[t]&&delete i.__cache[t]},i}),e.define("select2/results",["jquery","./utils"],function(p,h){function r(e,t,n){this.$element=e,this.data=n,this.options=t,r.__super__.constructor.call(this)}return h.Extend(r,h.Observable),r.prototype.render=function(){var e=p('
          ');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},r.prototype.clear=function(){this.$results.empty()},r.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=p('
        • '),r=this.options.get("translations").get(e.message);n.append(t(r(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},r.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},r.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested"});d.append(a),o.append(s),o.append(d)}else this.template(e,t);return h.StoreData(t,"data",e),t},r.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=h.GetData(e[0],"data");"true"==e.attr("aria-selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e);if(!(n<=0)){var r=n-1;0===e.length&&(r=0);var i=t.eq(r);i.trigger("mouseenter");var o=l.$results.offset().top,s=i.offset().top,a=l.$results.scrollTop()+(s-o);0===r?l.$results.scrollTop(0):s-o<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find("[aria-selected]"),n=t.index(e)+1;if(!(n>=t.length)){var r=t.eq(n);r.trigger("mouseenter");var i=l.$results.offset().top+l.$results.outerHeight(!1),o=r.offset().top+r.outerHeight(!1),s=l.$results.scrollTop()+o-i;0===n?l.$results.scrollTop(0):ithis.$results.outerHeight()||o<0)&&this.$results.scrollTop(i)}},r.prototype.template=function(e,t){var n=this.options.get("templateResult"),r=this.options.get("escapeMarkup"),i=n(e,t);null==i?t.style.display="none":"string"==typeof i?t.innerHTML=r(i):p(t).append(i)},r}),e.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,r,i){function o(e,t){this.$element=e,this.options=t,o.__super__.constructor.call(this)}return r.Extend(o,r.Observable),o.prototype.render=function(){var e=n('');return this._tabindex=0,null!=r.GetData(this.$element[0],"old-tabindex")?this._tabindex=r.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),this.$selection=e},o.prototype.bind=function(e,t){var n=this,r=(e.id,e.id+"-results");this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===i.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",r),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),window.setTimeout(function(){n.$selection.focus()},0),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex)}),e.on("disable",function(){n.$selection.attr("tabindex","-1")})},o.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},o.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){n(this);this!=t[0]&&r.GetData(this,"element").select2("close")})})},o.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},o.prototype.position=function(e,t){t.find(".selection").append(e)},o.prototype.destroy=function(){this._detachCloseHandler(this.container)},o.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},o}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,r){function i(){i.__super__.constructor.apply(this,arguments)}return n.Extend(i,t),i.prototype.render=function(){var e=i.__super__.render.call(this);return e.addClass("select2-selection--single"),e.html(''),e},i.prototype.bind=function(t,e){var n=this;i.__super__.bind.apply(this,arguments);var r=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",r).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",r),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.focus()})},i.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},i.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},i.prototype.selectionContainer=function(){return e("")},i.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),r=this.display(t,n);n.empty().append(r),n.attr("title",t.title||t.text)}else this.clear()},i}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(i,e,a){function n(e,t){n.__super__.constructor.apply(this,arguments)}return a.Extend(n,e),n.prototype.render=function(){var e=n.__super__.render.call(this);return e.addClass("select2-selection--multiple"),e.html('
            '),e},n.prototype.bind=function(e,t){var r=this;n.__super__.bind.apply(this,arguments),this.$selection.on("click",function(e){r.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!r.options.get("disabled")){var t=i(this).parent(),n=a.GetData(t[0],"data");r.trigger("unselect",{originalEvent:e,data:n})}})},n.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},n.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},n.prototype.selectionContainer=function(){return i('
          • ×
          • ')},n.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=0;n×');a.StoreData(r[0],"data",t),this.$selection.find(".select2-selection__rendered").prepend(r)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(r,s,a){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=r('');this.$searchContainer=t,this.$search=t.find("input");var n=e.call(this);return this._transferTabIndex(),n},e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("open",function(){r.$search.trigger("focus")}),t.on("close",function(){r.$search.val(""),r.$search.removeAttr("aria-activedescendant"),r.$search.trigger("focus")}),t.on("enable",function(){r.$search.prop("disabled",!1),r._transferTabIndex()}),t.on("disable",function(){r.$search.prop("disabled",!0)}),t.on("focus",function(e){r.$search.trigger("focus")}),t.on("results:focus",function(e){r.$search.attr("aria-activedescendant",e.id)}),this.$selection.on("focusin",".select2-search--inline",function(e){r.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){r._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented(),e.which===a.BACKSPACE&&""===r.$search.val()){var t=r.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.query=function(n,r,i){var o=this;this.current(function(e){var t=null!=e?e.length:0;0=o.maximumSelectionLength?o.trigger("results:message",{message:"maximumSelected",args:{maximum:o.maximumSelectionLength}}):n.call(o,r,i)})},e}),e.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),e.define("select2/dropdown/search",["jquery","../utils"],function(i,e){function t(){}return t.prototype.render=function(e){var t=e.call(this),n=i('');return this.$searchContainer=n,this.$search=n.find("input"),t.prepend(n),t},t.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),this.$search.on("keydown",function(e){r.trigger("keypress",e),r._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){i(this).off("keyup")}),this.$search.on("keyup input",function(e){r.handleSearch(e)}),t.on("open",function(){r.$search.attr("tabindex",0),r.$search.focus(),window.setTimeout(function(){r.$search.focus()},0)}),t.on("close",function(){r.$search.attr("tabindex",-1),r.$search.val(""),r.$search.blur()}),t.on("focus",function(){t.isOpen()||r.$search.focus()}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(r.showSearch(e)?r.$searchContainer.removeClass("select2-search--hide"):r.$searchContainer.addClass("select2-search--hide"))})},t.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},t.prototype.showSearch=function(e,t){return!0},t}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,r){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,r)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),r=t.length-1;0<=r;r--){var i=t[r];this.placeholder.id===i.id&&n.splice(r,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(i){function e(e,t,n,r){this.lastParams={},e.call(this,t,n,r),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&this.$results.append(this.$loadingMore)},e.prototype.bind=function(e,t,n){var r=this;e.call(this,t,n),t.on("query",function(e){r.lastParams=e,r.loading=!0}),t.on("query:append",function(e){r.lastParams=e,r.loading=!0}),this.$results.on("scroll",function(){var e=i.contains(document.documentElement,r.$loadingMore[0]);if(!r.loading&&e){var t=r.$results.offset().top+r.$results.outerHeight(!1);r.$loadingMore.offset().top+r.$loadingMore.outerHeight(!1)<=t+50&&r.loadMore()}})},e.prototype.loadMore=function(){this.loading=!0;var e=i.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=i('
          • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=n.get("dropdownParent")||f(document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var r=this,i=!1;e.call(this,t,n),t.on("open",function(){r._showDropdown(),r._attachPositioningHandler(t),i||(i=!0,t.on("results:all",function(){r._positionDropdown(),r._resizeDropdown()}),t.on("results:append",function(){r._positionDropdown(),r._resizeDropdown()}))}),t.on("close",function(){r._hideDropdown(),r._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t.removeClass("select2"),t.addClass("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._attachPositioningHandler=function(e,t){var n=this,r="scroll.select2."+t.id,i="resize.select2."+t.id,o="orientationchange.select2."+t.id,s=this.$container.parents().filter(a.hasScroll);s.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),s.on(r,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(r+" "+i+" "+o,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,r="resize.select2."+t.id,i="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+r+" "+i)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown.hasClass("select2-dropdown--above"),n=this.$dropdown.hasClass("select2-dropdown--below"),r=null,i=this.$container.offset();i.bottom=i.top+this.$container.outerHeight(!1);var o={height:this.$container.outerHeight(!1)};o.top=i.top,o.bottom=i.top+o.height;var s=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ai.bottom+s,d={left:i.left,top:o.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h=p.offset();d.top-=h.top,d.left-=h.left,t||n||(r="below"),u||!c||t?!c&&u&&t&&(r="below"):r="above",("above"==r||t&&"below"!==r)&&(d.top=o.top-h.top-s),null!=r&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+r),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+r)),this.$dropdownContainer.css(d)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,r){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,r)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,r=0;r');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container.addClass("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("jquery-mousewheel",["jquery"],function(e){return e}),e.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(i,e,o,t,s){if(null==i.fn.select2){var a=["open","close","destroy"];i.fn.select2=function(t){if("object"==typeof(t=t||{}))return this.each(function(){var e=i.extend(!0,{},t);new o(i(this),e)}),this;if("string"!=typeof t)throw new Error("Invalid arguments for Select2: "+t);var n,r=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=s.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+t+"') method was called on an element that is not using Select2."),n=e[t].apply(e,r)}),-1"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, +u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), +a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", +y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n .swiper-wrapper { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; +} +.swiper-wrapper { + position: relative; + width: 100%; + height: 100%; + z-index: 1; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-transition-property: -webkit-transform; + transition-property: -webkit-transform; + -o-transition-property: transform; + transition-property: transform; + transition-property: transform, -webkit-transform; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} +.swiper-container-android .swiper-slide, +.swiper-wrapper { + -webkit-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); +} +.swiper-container-multirow > .swiper-wrapper { + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} +.swiper-container-free-mode > .swiper-wrapper { + -webkit-transition-timing-function: ease-out; + -o-transition-timing-function: ease-out; + transition-timing-function: ease-out; + margin: 0 auto; +} +.swiper-slide { + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 100%; + height: 100%; + position: relative; + -webkit-transition-property: -webkit-transform; + transition-property: -webkit-transform; + -o-transition-property: transform; + transition-property: transform; + transition-property: transform, -webkit-transform; +} +.swiper-slide-invisible-blank { + visibility: hidden; +} +/* Auto Height */ +.swiper-container-autoheight, +.swiper-container-autoheight .swiper-slide { + height: auto; +} +.swiper-container-autoheight .swiper-wrapper { + -webkit-box-align: start; + -webkit-align-items: flex-start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-transition-property: height, -webkit-transform; + transition-property: height, -webkit-transform; + -o-transition-property: transform, height; + transition-property: transform, height; + transition-property: transform, height, -webkit-transform; +} +/* 3D Effects */ +.swiper-container-3d { + -webkit-perspective: 1200px; + perspective: 1200px; +} +.swiper-container-3d .swiper-wrapper, +.swiper-container-3d .swiper-slide, +.swiper-container-3d .swiper-slide-shadow-left, +.swiper-container-3d .swiper-slide-shadow-right, +.swiper-container-3d .swiper-slide-shadow-top, +.swiper-container-3d .swiper-slide-shadow-bottom, +.swiper-container-3d .swiper-cube-shadow { + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.swiper-container-3d .swiper-slide-shadow-left, +.swiper-container-3d .swiper-slide-shadow-right, +.swiper-container-3d .swiper-slide-shadow-top, +.swiper-container-3d .swiper-slide-shadow-bottom { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 10; +} +.swiper-container-3d .swiper-slide-shadow-left { + background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: -o-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); +} +.swiper-container-3d .swiper-slide-shadow-right { + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); +} +.swiper-container-3d .swiper-slide-shadow-top { + background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: -o-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); +} +.swiper-container-3d .swiper-slide-shadow-bottom { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); +} +/* IE10 Windows Phone 8 Fixes */ +.swiper-container-wp8-horizontal, +.swiper-container-wp8-horizontal > .swiper-wrapper { + -ms-touch-action: pan-y; + touch-action: pan-y; +} +.swiper-container-wp8-vertical, +.swiper-container-wp8-vertical > .swiper-wrapper { + -ms-touch-action: pan-x; + touch-action: pan-x; +} +.swiper-button-prev, +.swiper-button-next { + position: absolute; + top: 50%; + width: 27px; + height: 44px; + margin-top: -22px; + z-index: 10; + cursor: pointer; + background-size: 27px 44px; + background-position: center; + background-repeat: no-repeat; +} +.swiper-button-prev.swiper-button-disabled, +.swiper-button-next.swiper-button-disabled { + opacity: 0.35; + cursor: auto; + pointer-events: none; +} +.swiper-button-prev, +.swiper-container-rtl .swiper-button-next { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E"); + left: 10px; + right: auto; +} +.swiper-button-next, +.swiper-container-rtl .swiper-button-prev { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E"); + right: 10px; + left: auto; +} +.swiper-button-prev.swiper-button-white, +.swiper-container-rtl .swiper-button-next.swiper-button-white { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E"); +} +.swiper-button-next.swiper-button-white, +.swiper-container-rtl .swiper-button-prev.swiper-button-white { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E"); +} +.swiper-button-prev.swiper-button-black, +.swiper-container-rtl .swiper-button-next.swiper-button-black { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E"); +} +.swiper-button-next.swiper-button-black, +.swiper-container-rtl .swiper-button-prev.swiper-button-black { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E"); +} +.swiper-button-lock { + display: none; +} +.swiper-pagination { + position: absolute; + text-align: center; + -webkit-transition: 300ms opacity; + -o-transition: 300ms opacity; + transition: 300ms opacity; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + z-index: 10; +} +.swiper-pagination.swiper-pagination-hidden { + opacity: 0; +} +/* Common Styles */ +.swiper-pagination-fraction, +.swiper-pagination-custom, +.swiper-container-horizontal > .swiper-pagination-bullets { + bottom: 10px; + left: 0; + width: 100%; +} +/* Bullets */ +.swiper-pagination-bullets-dynamic { + overflow: hidden; + font-size: 0; +} +.swiper-pagination-bullets-dynamic .swiper-pagination-bullet { + -webkit-transform: scale(0.33); + -ms-transform: scale(0.33); + transform: scale(0.33); + position: relative; +} +.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); +} +.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main { + -webkit-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); +} +.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev { + -webkit-transform: scale(0.66); + -ms-transform: scale(0.66); + transform: scale(0.66); +} +.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev { + -webkit-transform: scale(0.33); + -ms-transform: scale(0.33); + transform: scale(0.33); +} +.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next { + -webkit-transform: scale(0.66); + -ms-transform: scale(0.66); + transform: scale(0.66); +} +.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next { + -webkit-transform: scale(0.33); + -ms-transform: scale(0.33); + transform: scale(0.33); +} +.swiper-pagination-bullet { + width: 8px; + height: 8px; + display: inline-block; + border-radius: 100%; + background: #000; + opacity: 0.2; +} +button.swiper-pagination-bullet { + border: none; + margin: 0; + padding: 0; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.swiper-pagination-clickable .swiper-pagination-bullet { + cursor: pointer; +} +.swiper-pagination-bullet-active { + opacity: 1; + background: #007aff; +} +.swiper-container-vertical > .swiper-pagination-bullets { + right: 10px; + top: 50%; + -webkit-transform: translate3d(0px, -50%, 0); + transform: translate3d(0px, -50%, 0); +} +.swiper-container-vertical > .swiper-pagination-bullets .swiper-pagination-bullet { + margin: 6px 0; + display: block; +} +.swiper-container-vertical > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic { + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); + width: 8px; +} +.swiper-container-vertical > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet { + display: inline-block; + -webkit-transition: 200ms top, 200ms -webkit-transform; + transition: 200ms top, 200ms -webkit-transform; + -o-transition: 200ms transform, 200ms top; + transition: 200ms transform, 200ms top; + transition: 200ms transform, 200ms top, 200ms -webkit-transform; +} +.swiper-container-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet { + margin: 0 4px; +} +.swiper-container-horizontal > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic { + left: 50%; + -webkit-transform: translateX(-50%); + -ms-transform: translateX(-50%); + transform: translateX(-50%); + white-space: nowrap; +} +.swiper-container-horizontal > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet { + -webkit-transition: 200ms left, 200ms -webkit-transform; + transition: 200ms left, 200ms -webkit-transform; + -o-transition: 200ms transform, 200ms left; + transition: 200ms transform, 200ms left; + transition: 200ms transform, 200ms left, 200ms -webkit-transform; +} +.swiper-container-horizontal.swiper-container-rtl > .swiper-pagination-bullets-dynamic .swiper-pagination-bullet { + -webkit-transition: 200ms right, 200ms -webkit-transform; + transition: 200ms right, 200ms -webkit-transform; + -o-transition: 200ms transform, 200ms right; + transition: 200ms transform, 200ms right; + transition: 200ms transform, 200ms right, 200ms -webkit-transform; +} +/* Progress */ +.swiper-pagination-progressbar { + background: rgba(0, 0, 0, 0.25); + position: absolute; +} +.swiper-pagination-progressbar .swiper-pagination-progressbar-fill { + background: #007aff; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -webkit-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + -webkit-transform-origin: left top; + -ms-transform-origin: left top; + transform-origin: left top; +} +.swiper-container-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill { + -webkit-transform-origin: right top; + -ms-transform-origin: right top; + transform-origin: right top; +} +.swiper-container-horizontal > .swiper-pagination-progressbar, +.swiper-container-vertical > .swiper-pagination-progressbar.swiper-pagination-progressbar-opposite { + width: 100%; + height: 4px; + left: 0; + top: 0; +} +.swiper-container-vertical > .swiper-pagination-progressbar, +.swiper-container-horizontal > .swiper-pagination-progressbar.swiper-pagination-progressbar-opposite { + width: 4px; + height: 100%; + left: 0; + top: 0; +} +.swiper-pagination-white .swiper-pagination-bullet-active { + background: #ffffff; +} +.swiper-pagination-progressbar.swiper-pagination-white { + background: rgba(255, 255, 255, 0.25); +} +.swiper-pagination-progressbar.swiper-pagination-white .swiper-pagination-progressbar-fill { + background: #ffffff; +} +.swiper-pagination-black .swiper-pagination-bullet-active { + background: #000000; +} +.swiper-pagination-progressbar.swiper-pagination-black { + background: rgba(0, 0, 0, 0.25); +} +.swiper-pagination-progressbar.swiper-pagination-black .swiper-pagination-progressbar-fill { + background: #000000; +} +.swiper-pagination-lock { + display: none; +} +/* Scrollbar */ +.swiper-scrollbar { + border-radius: 10px; + position: relative; + -ms-touch-action: none; + background: rgba(0, 0, 0, 0.1); +} +.swiper-container-horizontal > .swiper-scrollbar { + position: absolute; + left: 1%; + bottom: 3px; + z-index: 50; + height: 5px; + width: 98%; +} +.swiper-container-vertical > .swiper-scrollbar { + position: absolute; + right: 3px; + top: 1%; + z-index: 50; + width: 5px; + height: 98%; +} +.swiper-scrollbar-drag { + height: 100%; + width: 100%; + position: relative; + background: rgba(0, 0, 0, 0.5); + border-radius: 10px; + left: 0; + top: 0; +} +.swiper-scrollbar-cursor-drag { + cursor: move; +} +.swiper-scrollbar-lock { + display: none; +} +.swiper-zoom-container { + width: 100%; + height: 100%; + 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; + text-align: center; +} +.swiper-zoom-container > img, +.swiper-zoom-container > svg, +.swiper-zoom-container > canvas { + max-width: 100%; + max-height: 100%; + -o-object-fit: contain; + object-fit: contain; +} +.swiper-slide-zoomed { + cursor: move; +} +/* Preloader */ +.swiper-lazy-preloader { + width: 42px; + height: 42px; + position: absolute; + left: 50%; + top: 50%; + margin-left: -21px; + margin-top: -21px; + z-index: 10; + -webkit-transform-origin: 50%; + -ms-transform-origin: 50%; + transform-origin: 50%; + -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite; + animation: swiper-preloader-spin 1s steps(12, end) infinite; +} +.swiper-lazy-preloader:after { + display: block; + content: ''; + width: 100%; + height: 100%; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); + background-position: 50%; + background-size: 100%; + background-repeat: no-repeat; +} +.swiper-lazy-preloader-white:after { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} +@-webkit-keyframes swiper-preloader-spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes swiper-preloader-spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +/* a11y */ +.swiper-container .swiper-notification { + position: absolute; + left: 0; + top: 0; + pointer-events: none; + opacity: 0; + z-index: -1000; +} +.swiper-container-fade.swiper-container-free-mode .swiper-slide { + -webkit-transition-timing-function: ease-out; + -o-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} +.swiper-container-fade .swiper-slide { + pointer-events: none; + -webkit-transition-property: opacity; + -o-transition-property: opacity; + transition-property: opacity; +} +.swiper-container-fade .swiper-slide .swiper-slide { + pointer-events: none; +} +.swiper-container-fade .swiper-slide-active, +.swiper-container-fade .swiper-slide-active .swiper-slide-active { + pointer-events: auto; +} +.swiper-container-cube { + overflow: visible; +} +.swiper-container-cube .swiper-slide { + pointer-events: none; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + z-index: 1; + visibility: hidden; + -webkit-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; + width: 100%; + height: 100%; +} +.swiper-container-cube .swiper-slide .swiper-slide { + pointer-events: none; +} +.swiper-container-cube.swiper-container-rtl .swiper-slide { + -webkit-transform-origin: 100% 0; + -ms-transform-origin: 100% 0; + transform-origin: 100% 0; +} +.swiper-container-cube .swiper-slide-active, +.swiper-container-cube .swiper-slide-active .swiper-slide-active { + pointer-events: auto; +} +.swiper-container-cube .swiper-slide-active, +.swiper-container-cube .swiper-slide-next, +.swiper-container-cube .swiper-slide-prev, +.swiper-container-cube .swiper-slide-next + .swiper-slide { + pointer-events: auto; + visibility: visible; +} +.swiper-container-cube .swiper-slide-shadow-top, +.swiper-container-cube .swiper-slide-shadow-bottom, +.swiper-container-cube .swiper-slide-shadow-left, +.swiper-container-cube .swiper-slide-shadow-right { + z-index: 0; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} +.swiper-container-cube .swiper-cube-shadow { + position: absolute; + left: 0; + bottom: 0px; + width: 100%; + height: 100%; + background: #000; + opacity: 0.6; + -webkit-filter: blur(50px); + filter: blur(50px); + z-index: 0; +} +.swiper-container-flip { + overflow: visible; +} +.swiper-container-flip .swiper-slide { + pointer-events: none; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + z-index: 1; +} +.swiper-container-flip .swiper-slide .swiper-slide { + pointer-events: none; +} +.swiper-container-flip .swiper-slide-active, +.swiper-container-flip .swiper-slide-active .swiper-slide-active { + pointer-events: auto; +} +.swiper-container-flip .swiper-slide-shadow-top, +.swiper-container-flip .swiper-slide-shadow-bottom, +.swiper-container-flip .swiper-slide-shadow-left, +.swiper-container-flip .swiper-slide-shadow-right { + z-index: 0; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} +.swiper-container-coverflow .swiper-wrapper { + /* Windows 8 IE 10 fix */ + -ms-perspective: 1200px; +} diff --git a/assets/3rd/swiper/css/swiper.min.css b/assets/3rd/swiper/css/swiper.min.css new file mode 100755 index 00000000..c4a633d6 --- /dev/null +++ b/assets/3rd/swiper/css/swiper.min.css @@ -0,0 +1,12 @@ +/** + * Swiper 4.5.0 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * http://www.idangero.us/swiper/ + * + * Copyright 2014-2019 Vladimir Kharlampidi + * + * Released under the MIT License + * + * Released on: February 22, 2019 + */ +.swiper-container{margin:0 auto;position:relative;overflow:hidden;list-style:none;padding:0;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-transition-property:-webkit-transform;transition-property:-webkit-transform;-o-transition-property:transform;transition-property:transform;transition-property:transform,-webkit-transform;-webkit-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;height:100%;position:relative;-webkit-transition-property:-webkit-transform;transition-property:-webkit-transform;-o-transition-property:transform;transition-property:transform;transition-property:transform,-webkit-transform}.swiper-slide-invisible-blank{visibility:hidden}.swiper-container-autoheight,.swiper-container-autoheight .swiper-slide{height:auto}.swiper-container-autoheight .swiper-wrapper{-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;-webkit-transition-property:height,-webkit-transform;transition-property:height,-webkit-transform;-o-transition-property:transform,height;transition-property:transform,height;transition-property:transform,height,-webkit-transform}.swiper-container-3d{-webkit-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-wp8-horizontal,.swiper-container-wp8-horizontal>.swiper-wrapper{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-container-wp8-vertical,.swiper-container-wp8-vertical>.swiper-wrapper{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-lock{display:none}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:.3s opacity;-o-transition:.3s opacity;transition:.3s opacity;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullets-dynamic{overflow:hidden;font-size:0}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{-webkit-transform:scale(.33);-ms-transform:scale(.33);transform:scale(.33);position:relative}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{-webkit-transform:scale(.66);-ms-transform:scale(.66);transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{-webkit-transform:scale(.33);-ms-transform:scale(.33);transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{-webkit-transform:scale(.66);-ms-transform:scale(.66);transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{-webkit-transform:scale(.33);-ms-transform:scale(.33);transform:scale(.33)}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-container-vertical>.swiper-pagination-bullets{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:6px 0;display:block}.swiper-container-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:8px}.swiper-container-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;-webkit-transition:.2s top,.2s -webkit-transform;transition:.2s top,.2s -webkit-transform;-o-transition:.2s transform,.2s top;transition:.2s transform,.2s top;transition:.2s transform,.2s top,.2s -webkit-transform}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 4px}.swiper-container-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);white-space:nowrap}.swiper-container-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{-webkit-transition:.2s left,.2s -webkit-transform;transition:.2s left,.2s -webkit-transform;-o-transition:.2s transform,.2s left;transition:.2s transform,.2s left;transition:.2s transform,.2s left,.2s -webkit-transform}.swiper-container-horizontal.swiper-container-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{-webkit-transition:.2s right,.2s -webkit-transform;transition:.2s right,.2s -webkit-transform;-o-transition:.2s transform,.2s right;transition:.2s transform,.2s right;transition:.2s transform,.2s right,.2s -webkit-transform}.swiper-pagination-progressbar{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:#007aff;position:absolute;left:0;top:0;width:100%;height:100%;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transform-origin:left top;-ms-transform-origin:left top;transform-origin:left top}.swiper-container-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{-webkit-transform-origin:right top;-ms-transform-origin:right top;transform-origin:right top}.swiper-container-horizontal>.swiper-pagination-progressbar,.swiper-container-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{width:100%;height:4px;left:0;top:0}.swiper-container-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-container-vertical>.swiper-pagination-progressbar{width:4px;height:100%;left:0;top:0}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-progressbar.swiper-pagination-white{background:rgba(255,255,255,.25)}.swiper-pagination-progressbar.swiper-pagination-white .swiper-pagination-progressbar-fill{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-pagination-progressbar.swiper-pagination-black{background:rgba(0,0,0,.25)}.swiper-pagination-progressbar.swiper-pagination-black .swiper-pagination-progressbar-fill{background:#000}.swiper-pagination-lock{display:none}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-scrollbar-lock{display:none}.swiper-zoom-container{width:100%;height:100%;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;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;-o-object-fit:contain;object-fit:contain}.swiper-slide-zoomed{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-ms-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:'';width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none;-webkit-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube{overflow:visible}.swiper-container-cube .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;visibility:hidden;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%}.swiper-container-cube .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-container-flip{overflow:visible}.swiper-container-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-container-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-flip .swiper-slide-active,.swiper-container-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-flip .swiper-slide-shadow-bottom,.swiper-container-flip .swiper-slide-shadow-left,.swiper-container-flip .swiper-slide-shadow-right,.swiper-container-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-coverflow .swiper-wrapper{-ms-perspective:1200px} \ No newline at end of file diff --git a/assets/3rd/swiper/js/swiper.esm.bundle.js b/assets/3rd/swiper/js/swiper.esm.bundle.js new file mode 100755 index 00000000..585c5446 --- /dev/null +++ b/assets/3rd/swiper/js/swiper.esm.bundle.js @@ -0,0 +1,7151 @@ +/** + * Swiper 4.5.0 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * http://www.idangero.us/swiper/ + * + * Copyright 2014-2019 Vladimir Kharlampidi + * + * Released under the MIT License + * + * Released on: February 22, 2019 + */ + +import { $, addClass, removeClass, hasClass, toggleClass, attr, removeAttr, data, transform, transition as transition$1, on, off, trigger, transitionEnd as transitionEnd$1, outerWidth, outerHeight, offset, css, each, html, text, is, index, eq, append, prepend, next, nextAll, prev, prevAll, parent, parents, closest, find, children, remove, add, styles } from 'dom7/dist/dom7.modular'; +import { window, document } from 'ssr-window'; + +const Methods = { + addClass, + removeClass, + hasClass, + toggleClass, + attr, + removeAttr, + data, + transform, + transition: transition$1, + on, + off, + trigger, + transitionEnd: transitionEnd$1, + outerWidth, + outerHeight, + offset, + css, + each, + html, + text, + is, + index, + eq, + append, + prepend, + next, + nextAll, + prev, + prevAll, + parent, + parents, + closest, + find, + children, + remove, + add, + styles, +}; + +Object.keys(Methods).forEach((methodName) => { + $.fn[methodName] = Methods[methodName]; +}); + +const Utils = { + deleteProps(obj) { + const object = obj; + Object.keys(object).forEach((key) => { + try { + object[key] = null; + } catch (e) { + // no getter for object + } + try { + delete object[key]; + } catch (e) { + // something got wrong + } + }); + }, + nextTick(callback, delay = 0) { + return setTimeout(callback, delay); + }, + now() { + return Date.now(); + }, + getTranslate(el, axis = 'x') { + let matrix; + let curTransform; + let transformMatrix; + + const curStyle = window.getComputedStyle(el, null); + + if (window.WebKitCSSMatrix) { + curTransform = curStyle.transform || curStyle.webkitTransform; + if (curTransform.split(',').length > 6) { + curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', '); + } + // Some old versions of Webkit choke when 'none' is passed; pass + // empty string instead in this case + transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform); + } else { + transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,'); + matrix = transformMatrix.toString().split(','); + } + + if (axis === 'x') { + // Latest Chrome and webkits Fix + if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41; + // Crazy IE10 Matrix + else if (matrix.length === 16) curTransform = parseFloat(matrix[12]); + // Normal Browsers + else curTransform = parseFloat(matrix[4]); + } + if (axis === 'y') { + // Latest Chrome and webkits Fix + if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42; + // Crazy IE10 Matrix + else if (matrix.length === 16) curTransform = parseFloat(matrix[13]); + // Normal Browsers + else curTransform = parseFloat(matrix[5]); + } + return curTransform || 0; + }, + parseUrlQuery(url) { + const query = {}; + let urlToParse = url || window.location.href; + let i; + let params; + let param; + let length; + if (typeof urlToParse === 'string' && urlToParse.length) { + urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\S*\?/, '') : ''; + params = urlToParse.split('&').filter(paramsPart => paramsPart !== ''); + length = params.length; + + for (i = 0; i < length; i += 1) { + param = params[i].replace(/#\S+/g, '').split('='); + query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param[1]) || ''; + } + } + return query; + }, + isObject(o) { + return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object; + }, + extend(...args) { + const to = Object(args[0]); + for (let i = 1; i < args.length; i += 1) { + const nextSource = args[i]; + if (nextSource !== undefined && nextSource !== null) { + const keysArray = Object.keys(Object(nextSource)); + for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) { + const nextKey = keysArray[nextIndex]; + const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); + if (desc !== undefined && desc.enumerable) { + if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) { + Utils.extend(to[nextKey], nextSource[nextKey]); + } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) { + to[nextKey] = {}; + Utils.extend(to[nextKey], nextSource[nextKey]); + } else { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + } + return to; + }, +}; + +const Support = (function Support() { + const testDiv = document.createElement('div'); + return { + touch: (window.Modernizr && window.Modernizr.touch === true) || (function checkTouch() { + return !!((window.navigator.maxTouchPoints > 0) || ('ontouchstart' in window) || (window.DocumentTouch && document instanceof window.DocumentTouch)); + }()), + + pointerEvents: !!(window.navigator.pointerEnabled || window.PointerEvent || ('maxTouchPoints' in window.navigator && window.navigator.maxTouchPoints > 0)), + prefixedPointerEvents: !!window.navigator.msPointerEnabled, + + transition: (function checkTransition() { + const style = testDiv.style; + return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style); + }()), + transforms3d: (window.Modernizr && window.Modernizr.csstransforms3d === true) || (function checkTransforms3d() { + const style = testDiv.style; + return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style); + }()), + + flexbox: (function checkFlexbox() { + const style = testDiv.style; + const styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' '); + for (let i = 0; i < styles.length; i += 1) { + if (styles[i] in style) return true; + } + return false; + }()), + + observer: (function checkObserver() { + return ('MutationObserver' in window || 'WebkitMutationObserver' in window); + }()), + + passiveListener: (function checkPassiveListener() { + let supportsPassive = false; + try { + const opts = Object.defineProperty({}, 'passive', { + // eslint-disable-next-line + get() { + supportsPassive = true; + }, + }); + window.addEventListener('testPassiveListener', null, opts); + } catch (e) { + // No support + } + return supportsPassive; + }()), + + gestures: (function checkGestures() { + return 'ongesturestart' in window; + }()), + }; +}()); + +const Browser = (function Browser() { + function isSafari() { + const ua = window.navigator.userAgent.toLowerCase(); + return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0); + } + return { + isIE: !!window.navigator.userAgent.match(/Trident/g) || !!window.navigator.userAgent.match(/MSIE/g), + isEdge: !!window.navigator.userAgent.match(/Edge/g), + isSafari: isSafari(), + isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent), + }; +}()); + +class SwiperClass { + constructor(params = {}) { + const self = this; + self.params = params; + + // Events + self.eventsListeners = {}; + + if (self.params && self.params.on) { + Object.keys(self.params.on).forEach((eventName) => { + self.on(eventName, self.params.on[eventName]); + }); + } + } + + on(events, handler, priority) { + const self = this; + if (typeof handler !== 'function') return self; + const method = priority ? 'unshift' : 'push'; + events.split(' ').forEach((event) => { + if (!self.eventsListeners[event]) self.eventsListeners[event] = []; + self.eventsListeners[event][method](handler); + }); + return self; + } + + once(events, handler, priority) { + const self = this; + if (typeof handler !== 'function') return self; + function onceHandler(...args) { + handler.apply(self, args); + self.off(events, onceHandler); + if (onceHandler.f7proxy) { + delete onceHandler.f7proxy; + } + } + onceHandler.f7proxy = handler; + return self.on(events, onceHandler, priority); + } + + off(events, handler) { + const self = this; + if (!self.eventsListeners) return self; + events.split(' ').forEach((event) => { + if (typeof handler === 'undefined') { + self.eventsListeners[event] = []; + } else if (self.eventsListeners[event] && self.eventsListeners[event].length) { + self.eventsListeners[event].forEach((eventHandler, index) => { + if (eventHandler === handler || (eventHandler.f7proxy && eventHandler.f7proxy === handler)) { + self.eventsListeners[event].splice(index, 1); + } + }); + } + }); + return self; + } + + emit(...args) { + const self = this; + if (!self.eventsListeners) return self; + let events; + let data; + let context; + if (typeof args[0] === 'string' || Array.isArray(args[0])) { + events = args[0]; + data = args.slice(1, args.length); + context = self; + } else { + events = args[0].events; + data = args[0].data; + context = args[0].context || self; + } + const eventsArray = Array.isArray(events) ? events : events.split(' '); + eventsArray.forEach((event) => { + if (self.eventsListeners && self.eventsListeners[event]) { + const handlers = []; + self.eventsListeners[event].forEach((eventHandler) => { + handlers.push(eventHandler); + }); + handlers.forEach((eventHandler) => { + eventHandler.apply(context, data); + }); + } + }); + return self; + } + + useModulesParams(instanceParams) { + const instance = this; + if (!instance.modules) return; + Object.keys(instance.modules).forEach((moduleName) => { + const module = instance.modules[moduleName]; + // Extend params + if (module.params) { + Utils.extend(instanceParams, module.params); + } + }); + } + + useModules(modulesParams = {}) { + const instance = this; + if (!instance.modules) return; + Object.keys(instance.modules).forEach((moduleName) => { + const module = instance.modules[moduleName]; + const moduleParams = modulesParams[moduleName] || {}; + // Extend instance methods and props + if (module.instance) { + Object.keys(module.instance).forEach((modulePropName) => { + const moduleProp = module.instance[modulePropName]; + if (typeof moduleProp === 'function') { + instance[modulePropName] = moduleProp.bind(instance); + } else { + instance[modulePropName] = moduleProp; + } + }); + } + // Add event listeners + if (module.on && instance.on) { + Object.keys(module.on).forEach((moduleEventName) => { + instance.on(moduleEventName, module.on[moduleEventName]); + }); + } + + // Module create callback + if (module.create) { + module.create.bind(instance)(moduleParams); + } + }); + } + + static set components(components) { + const Class = this; + if (!Class.use) return; + Class.use(components); + } + + static installModule(module, ...params) { + const Class = this; + if (!Class.prototype.modules) Class.prototype.modules = {}; + const name = module.name || (`${Object.keys(Class.prototype.modules).length}_${Utils.now()}`); + Class.prototype.modules[name] = module; + // Prototype + if (module.proto) { + Object.keys(module.proto).forEach((key) => { + Class.prototype[key] = module.proto[key]; + }); + } + // Class + if (module.static) { + Object.keys(module.static).forEach((key) => { + Class[key] = module.static[key]; + }); + } + // Callback + if (module.install) { + module.install.apply(Class, params); + } + return Class; + } + + static use(module, ...params) { + const Class = this; + if (Array.isArray(module)) { + module.forEach(m => Class.installModule(m)); + return Class; + } + return Class.installModule(module, ...params); + } +} + +function updateSize () { + const swiper = this; + let width; + let height; + const $el = swiper.$el; + if (typeof swiper.params.width !== 'undefined') { + width = swiper.params.width; + } else { + width = $el[0].clientWidth; + } + if (typeof swiper.params.height !== 'undefined') { + height = swiper.params.height; + } else { + height = $el[0].clientHeight; + } + if ((width === 0 && swiper.isHorizontal()) || (height === 0 && swiper.isVertical())) { + return; + } + + // Subtract paddings + width = width - parseInt($el.css('padding-left'), 10) - parseInt($el.css('padding-right'), 10); + height = height - parseInt($el.css('padding-top'), 10) - parseInt($el.css('padding-bottom'), 10); + + Utils.extend(swiper, { + width, + height, + size: swiper.isHorizontal() ? width : height, + }); +} + +function updateSlides () { + const swiper = this; + const params = swiper.params; + + const { + $wrapperEl, size: swiperSize, rtlTranslate: rtl, wrongRTL, + } = swiper; + const isVirtual = swiper.virtual && params.virtual.enabled; + const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length; + const slides = $wrapperEl.children(`.${swiper.params.slideClass}`); + const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length; + let snapGrid = []; + const slidesGrid = []; + const slidesSizesGrid = []; + + let offsetBefore = params.slidesOffsetBefore; + if (typeof offsetBefore === 'function') { + offsetBefore = params.slidesOffsetBefore.call(swiper); + } + + let offsetAfter = params.slidesOffsetAfter; + if (typeof offsetAfter === 'function') { + offsetAfter = params.slidesOffsetAfter.call(swiper); + } + + const previousSnapGridLength = swiper.snapGrid.length; + const previousSlidesGridLength = swiper.snapGrid.length; + + let spaceBetween = params.spaceBetween; + let slidePosition = -offsetBefore; + let prevSlideSize = 0; + let index = 0; + if (typeof swiperSize === 'undefined') { + return; + } + if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { + spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiperSize; + } + + swiper.virtualSize = -spaceBetween; + + // reset margins + if (rtl) slides.css({ marginLeft: '', marginTop: '' }); + else slides.css({ marginRight: '', marginBottom: '' }); + + let slidesNumberEvenToRows; + if (params.slidesPerColumn > 1) { + if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) { + slidesNumberEvenToRows = slidesLength; + } else { + slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn; + } + if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') { + slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, params.slidesPerView * params.slidesPerColumn); + } + } + + // Calc slides + let slideSize; + const slidesPerColumn = params.slidesPerColumn; + const slidesPerRow = slidesNumberEvenToRows / slidesPerColumn; + const numFullColumns = Math.floor(slidesLength / params.slidesPerColumn); + for (let i = 0; i < slidesLength; i += 1) { + slideSize = 0; + const slide = slides.eq(i); + if (params.slidesPerColumn > 1) { + // Set slides order + let newSlideOrderIndex; + let column; + let row; + if (params.slidesPerColumnFill === 'column') { + column = Math.floor(i / slidesPerColumn); + row = i - (column * slidesPerColumn); + if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) { + row += 1; + if (row >= slidesPerColumn) { + row = 0; + column += 1; + } + } + newSlideOrderIndex = column + ((row * slidesNumberEvenToRows) / slidesPerColumn); + slide + .css({ + '-webkit-box-ordinal-group': newSlideOrderIndex, + '-moz-box-ordinal-group': newSlideOrderIndex, + '-ms-flex-order': newSlideOrderIndex, + '-webkit-order': newSlideOrderIndex, + order: newSlideOrderIndex, + }); + } else { + row = Math.floor(i / slidesPerRow); + column = i - (row * slidesPerRow); + } + slide + .css( + `margin-${swiper.isHorizontal() ? 'top' : 'left'}`, + (row !== 0 && params.spaceBetween) && (`${params.spaceBetween}px`) + ) + .attr('data-swiper-column', column) + .attr('data-swiper-row', row); + } + if (slide.css('display') === 'none') continue; // eslint-disable-line + + if (params.slidesPerView === 'auto') { + const slideStyles = window.getComputedStyle(slide[0], null); + const currentTransform = slide[0].style.transform; + const currentWebKitTransform = slide[0].style.webkitTransform; + if (currentTransform) { + slide[0].style.transform = 'none'; + } + if (currentWebKitTransform) { + slide[0].style.webkitTransform = 'none'; + } + if (params.roundLengths) { + slideSize = swiper.isHorizontal() + ? slide.outerWidth(true) + : slide.outerHeight(true); + } else { + // eslint-disable-next-line + if (swiper.isHorizontal()) { + const width = parseFloat(slideStyles.getPropertyValue('width')); + const paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left')); + const paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right')); + const marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left')); + const marginRight = parseFloat(slideStyles.getPropertyValue('margin-right')); + const boxSizing = slideStyles.getPropertyValue('box-sizing'); + if (boxSizing && boxSizing === 'border-box') { + slideSize = width + marginLeft + marginRight; + } else { + slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight; + } + } else { + const height = parseFloat(slideStyles.getPropertyValue('height')); + const paddingTop = parseFloat(slideStyles.getPropertyValue('padding-top')); + const paddingBottom = parseFloat(slideStyles.getPropertyValue('padding-bottom')); + const marginTop = parseFloat(slideStyles.getPropertyValue('margin-top')); + const marginBottom = parseFloat(slideStyles.getPropertyValue('margin-bottom')); + const boxSizing = slideStyles.getPropertyValue('box-sizing'); + if (boxSizing && boxSizing === 'border-box') { + slideSize = height + marginTop + marginBottom; + } else { + slideSize = height + paddingTop + paddingBottom + marginTop + marginBottom; + } + } + } + if (currentTransform) { + slide[0].style.transform = currentTransform; + } + if (currentWebKitTransform) { + slide[0].style.webkitTransform = currentWebKitTransform; + } + if (params.roundLengths) slideSize = Math.floor(slideSize); + } else { + slideSize = (swiperSize - ((params.slidesPerView - 1) * spaceBetween)) / params.slidesPerView; + if (params.roundLengths) slideSize = Math.floor(slideSize); + + if (slides[i]) { + if (swiper.isHorizontal()) { + slides[i].style.width = `${slideSize}px`; + } else { + slides[i].style.height = `${slideSize}px`; + } + } + } + if (slides[i]) { + slides[i].swiperSlideSize = slideSize; + } + slidesSizesGrid.push(slideSize); + + + if (params.centeredSlides) { + slidePosition = slidePosition + (slideSize / 2) + (prevSlideSize / 2) + spaceBetween; + if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; + if (i === 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; + if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0; + if (params.roundLengths) slidePosition = Math.floor(slidePosition); + if ((index) % params.slidesPerGroup === 0) snapGrid.push(slidePosition); + slidesGrid.push(slidePosition); + } else { + if (params.roundLengths) slidePosition = Math.floor(slidePosition); + if ((index) % params.slidesPerGroup === 0) snapGrid.push(slidePosition); + slidesGrid.push(slidePosition); + slidePosition = slidePosition + slideSize + spaceBetween; + } + + swiper.virtualSize += slideSize + spaceBetween; + + prevSlideSize = slideSize; + + index += 1; + } + swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter; + let newSlidesGrid; + + if ( + rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) { + $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); + } + if (!Support.flexbox || params.setWrapperSize) { + if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); + else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` }); + } + + if (params.slidesPerColumn > 1) { + swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumberEvenToRows; + swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween; + if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); + else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` }); + if (params.centeredSlides) { + newSlidesGrid = []; + for (let i = 0; i < snapGrid.length; i += 1) { + let slidesGridItem = snapGrid[i]; + if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); + if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem); + } + snapGrid = newSlidesGrid; + } + } + + // Remove last grid elements depending on width + if (!params.centeredSlides) { + newSlidesGrid = []; + for (let i = 0; i < snapGrid.length; i += 1) { + let slidesGridItem = snapGrid[i]; + if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); + if (snapGrid[i] <= swiper.virtualSize - swiperSize) { + newSlidesGrid.push(slidesGridItem); + } + } + snapGrid = newSlidesGrid; + if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) { + snapGrid.push(swiper.virtualSize - swiperSize); + } + } + if (snapGrid.length === 0) snapGrid = [0]; + + if (params.spaceBetween !== 0) { + if (swiper.isHorizontal()) { + if (rtl) slides.css({ marginLeft: `${spaceBetween}px` }); + else slides.css({ marginRight: `${spaceBetween}px` }); + } else slides.css({ marginBottom: `${spaceBetween}px` }); + } + + if (params.centerInsufficientSlides) { + let allSlidesSize = 0; + slidesSizesGrid.forEach((slideSizeValue) => { + allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0); + }); + allSlidesSize -= params.spaceBetween; + if (allSlidesSize < swiperSize) { + const allSlidesOffset = (swiperSize - allSlidesSize) / 2; + snapGrid.forEach((snap, snapIndex) => { + snapGrid[snapIndex] = snap - allSlidesOffset; + }); + slidesGrid.forEach((snap, snapIndex) => { + slidesGrid[snapIndex] = snap + allSlidesOffset; + }); + } + } + + Utils.extend(swiper, { + slides, + snapGrid, + slidesGrid, + slidesSizesGrid, + }); + + if (slidesLength !== previousSlidesLength) { + swiper.emit('slidesLengthChange'); + } + if (snapGrid.length !== previousSnapGridLength) { + if (swiper.params.watchOverflow) swiper.checkOverflow(); + swiper.emit('snapGridLengthChange'); + } + if (slidesGrid.length !== previousSlidesGridLength) { + swiper.emit('slidesGridLengthChange'); + } + + if (params.watchSlidesProgress || params.watchSlidesVisibility) { + swiper.updateSlidesOffset(); + } +} + +function updateAutoHeight (speed) { + const swiper = this; + const activeSlides = []; + let newHeight = 0; + let i; + if (typeof speed === 'number') { + swiper.setTransition(speed); + } else if (speed === true) { + swiper.setTransition(swiper.params.speed); + } + // Find slides currently in view + if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) { + for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) { + const index = swiper.activeIndex + i; + if (index > swiper.slides.length) break; + activeSlides.push(swiper.slides.eq(index)[0]); + } + } else { + activeSlides.push(swiper.slides.eq(swiper.activeIndex)[0]); + } + + // Find new height from highest slide in view + for (i = 0; i < activeSlides.length; i += 1) { + if (typeof activeSlides[i] !== 'undefined') { + const height = activeSlides[i].offsetHeight; + newHeight = height > newHeight ? height : newHeight; + } + } + + // Update Height + if (newHeight) swiper.$wrapperEl.css('height', `${newHeight}px`); +} + +function updateSlidesOffset () { + const swiper = this; + const slides = swiper.slides; + for (let i = 0; i < slides.length; i += 1) { + slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop; + } +} + +function updateSlidesProgress (translate = (this && this.translate) || 0) { + const swiper = this; + const params = swiper.params; + + const { slides, rtlTranslate: rtl } = swiper; + + if (slides.length === 0) return; + if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset(); + + let offsetCenter = -translate; + if (rtl) offsetCenter = translate; + + // Visible Slides + slides.removeClass(params.slideVisibleClass); + + swiper.visibleSlidesIndexes = []; + swiper.visibleSlides = []; + + for (let i = 0; i < slides.length; i += 1) { + const slide = slides[i]; + const slideProgress = ( + (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0)) - slide.swiperSlideOffset + ) / (slide.swiperSlideSize + params.spaceBetween); + if (params.watchSlidesVisibility) { + const slideBefore = -(offsetCenter - slide.swiperSlideOffset); + const slideAfter = slideBefore + swiper.slidesSizesGrid[i]; + const isVisible = (slideBefore >= 0 && slideBefore < swiper.size) + || (slideAfter > 0 && slideAfter <= swiper.size) + || (slideBefore <= 0 && slideAfter >= swiper.size); + if (isVisible) { + swiper.visibleSlides.push(slide); + swiper.visibleSlidesIndexes.push(i); + slides.eq(i).addClass(params.slideVisibleClass); + } + } + slide.progress = rtl ? -slideProgress : slideProgress; + } + swiper.visibleSlides = $(swiper.visibleSlides); +} + +function updateProgress (translate = (this && this.translate) || 0) { + const swiper = this; + const params = swiper.params; + + const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); + let { progress, isBeginning, isEnd } = swiper; + const wasBeginning = isBeginning; + const wasEnd = isEnd; + if (translatesDiff === 0) { + progress = 0; + isBeginning = true; + isEnd = true; + } else { + progress = (translate - swiper.minTranslate()) / (translatesDiff); + isBeginning = progress <= 0; + isEnd = progress >= 1; + } + Utils.extend(swiper, { + progress, + isBeginning, + isEnd, + }); + + if (params.watchSlidesProgress || params.watchSlidesVisibility) swiper.updateSlidesProgress(translate); + + if (isBeginning && !wasBeginning) { + swiper.emit('reachBeginning toEdge'); + } + if (isEnd && !wasEnd) { + swiper.emit('reachEnd toEdge'); + } + if ((wasBeginning && !isBeginning) || (wasEnd && !isEnd)) { + swiper.emit('fromEdge'); + } + + swiper.emit('progress', progress); +} + +function updateSlidesClasses () { + const swiper = this; + + const { + slides, params, $wrapperEl, activeIndex, realIndex, + } = swiper; + const isVirtual = swiper.virtual && params.virtual.enabled; + + slides.removeClass(`${params.slideActiveClass} ${params.slideNextClass} ${params.slidePrevClass} ${params.slideDuplicateActiveClass} ${params.slideDuplicateNextClass} ${params.slideDuplicatePrevClass}`); + + let activeSlide; + if (isVirtual) { + activeSlide = swiper.$wrapperEl.find(`.${params.slideClass}[data-swiper-slide-index="${activeIndex}"]`); + } else { + activeSlide = slides.eq(activeIndex); + } + + // Active classes + activeSlide.addClass(params.slideActiveClass); + + if (params.loop) { + // Duplicate to all looped slides + if (activeSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${realIndex}"]`) + .addClass(params.slideDuplicateActiveClass); + } else { + $wrapperEl + .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${realIndex}"]`) + .addClass(params.slideDuplicateActiveClass); + } + } + // Next Slide + let nextSlide = activeSlide.nextAll(`.${params.slideClass}`).eq(0).addClass(params.slideNextClass); + if (params.loop && nextSlide.length === 0) { + nextSlide = slides.eq(0); + nextSlide.addClass(params.slideNextClass); + } + // Prev Slide + let prevSlide = activeSlide.prevAll(`.${params.slideClass}`).eq(0).addClass(params.slidePrevClass); + if (params.loop && prevSlide.length === 0) { + prevSlide = slides.eq(-1); + prevSlide.addClass(params.slidePrevClass); + } + if (params.loop) { + // Duplicate to all looped slides + if (nextSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicateNextClass); + } else { + $wrapperEl + .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicateNextClass); + } + if (prevSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicatePrevClass); + } else { + $wrapperEl + .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicatePrevClass); + } + } +} + +function updateActiveIndex (newActiveIndex) { + const swiper = this; + const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; + const { + slidesGrid, snapGrid, params, activeIndex: previousIndex, realIndex: previousRealIndex, snapIndex: previousSnapIndex, + } = swiper; + let activeIndex = newActiveIndex; + let snapIndex; + if (typeof activeIndex === 'undefined') { + for (let i = 0; i < slidesGrid.length; i += 1) { + if (typeof slidesGrid[i + 1] !== 'undefined') { + if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - ((slidesGrid[i + 1] - slidesGrid[i]) / 2)) { + activeIndex = i; + } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) { + activeIndex = i + 1; + } + } else if (translate >= slidesGrid[i]) { + activeIndex = i; + } + } + // Normalize slideIndex + if (params.normalizeSlideIndex) { + if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0; + } + } + if (snapGrid.indexOf(translate) >= 0) { + snapIndex = snapGrid.indexOf(translate); + } else { + snapIndex = Math.floor(activeIndex / params.slidesPerGroup); + } + if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; + if (activeIndex === previousIndex) { + if (snapIndex !== previousSnapIndex) { + swiper.snapIndex = snapIndex; + swiper.emit('snapIndexChange'); + } + return; + } + + // Get real index + const realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10); + + Utils.extend(swiper, { + snapIndex, + realIndex, + previousIndex, + activeIndex, + }); + swiper.emit('activeIndexChange'); + swiper.emit('snapIndexChange'); + if (previousRealIndex !== realIndex) { + swiper.emit('realIndexChange'); + } + swiper.emit('slideChange'); +} + +function updateClickedSlide (e) { + const swiper = this; + const params = swiper.params; + const slide = $(e.target).closest(`.${params.slideClass}`)[0]; + let slideFound = false; + if (slide) { + for (let i = 0; i < swiper.slides.length; i += 1) { + if (swiper.slides[i] === slide) slideFound = true; + } + } + + if (slide && slideFound) { + swiper.clickedSlide = slide; + if (swiper.virtual && swiper.params.virtual.enabled) { + swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10); + } else { + swiper.clickedIndex = $(slide).index(); + } + } else { + swiper.clickedSlide = undefined; + swiper.clickedIndex = undefined; + return; + } + if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) { + swiper.slideToClickedSlide(); + } +} + +var update = { + updateSize, + updateSlides, + updateAutoHeight, + updateSlidesOffset, + updateSlidesProgress, + updateProgress, + updateSlidesClasses, + updateActiveIndex, + updateClickedSlide, +}; + +function getTranslate (axis = this.isHorizontal() ? 'x' : 'y') { + const swiper = this; + + const { + params, rtlTranslate: rtl, translate, $wrapperEl, + } = swiper; + + if (params.virtualTranslate) { + return rtl ? -translate : translate; + } + + let currentTranslate = Utils.getTranslate($wrapperEl[0], axis); + if (rtl) currentTranslate = -currentTranslate; + + return currentTranslate || 0; +} + +function setTranslate (translate, byController) { + const swiper = this; + const { + rtlTranslate: rtl, params, $wrapperEl, progress, + } = swiper; + let x = 0; + let y = 0; + const z = 0; + + if (swiper.isHorizontal()) { + x = rtl ? -translate : translate; + } else { + y = translate; + } + + if (params.roundLengths) { + x = Math.floor(x); + y = Math.floor(y); + } + + if (!params.virtualTranslate) { + if (Support.transforms3d) $wrapperEl.transform(`translate3d(${x}px, ${y}px, ${z}px)`); + else $wrapperEl.transform(`translate(${x}px, ${y}px)`); + } + swiper.previousTranslate = swiper.translate; + swiper.translate = swiper.isHorizontal() ? x : y; + + // Check if we need to update progress + let newProgress; + const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); + if (translatesDiff === 0) { + newProgress = 0; + } else { + newProgress = (translate - swiper.minTranslate()) / (translatesDiff); + } + if (newProgress !== progress) { + swiper.updateProgress(translate); + } + + swiper.emit('setTranslate', swiper.translate, byController); +} + +function minTranslate () { + return (-this.snapGrid[0]); +} + +function maxTranslate () { + return (-this.snapGrid[this.snapGrid.length - 1]); +} + +var translate = { + getTranslate, + setTranslate, + minTranslate, + maxTranslate, +}; + +function setTransition (duration, byController) { + const swiper = this; + + swiper.$wrapperEl.transition(duration); + + swiper.emit('setTransition', duration, byController); +} + +function transitionStart (runCallbacks = true, direction) { + const swiper = this; + const { activeIndex, params, previousIndex } = swiper; + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + + let dir = direction; + if (!dir) { + if (activeIndex > previousIndex) dir = 'next'; + else if (activeIndex < previousIndex) dir = 'prev'; + else dir = 'reset'; + } + + swiper.emit('transitionStart'); + + if (runCallbacks && activeIndex !== previousIndex) { + if (dir === 'reset') { + swiper.emit('slideResetTransitionStart'); + return; + } + swiper.emit('slideChangeTransitionStart'); + if (dir === 'next') { + swiper.emit('slideNextTransitionStart'); + } else { + swiper.emit('slidePrevTransitionStart'); + } + } +} + +function transitionEnd (runCallbacks = true, direction) { + const swiper = this; + const { activeIndex, previousIndex } = swiper; + swiper.animating = false; + swiper.setTransition(0); + + let dir = direction; + if (!dir) { + if (activeIndex > previousIndex) dir = 'next'; + else if (activeIndex < previousIndex) dir = 'prev'; + else dir = 'reset'; + } + + swiper.emit('transitionEnd'); + + if (runCallbacks && activeIndex !== previousIndex) { + if (dir === 'reset') { + swiper.emit('slideResetTransitionEnd'); + return; + } + swiper.emit('slideChangeTransitionEnd'); + if (dir === 'next') { + swiper.emit('slideNextTransitionEnd'); + } else { + swiper.emit('slidePrevTransitionEnd'); + } + } +} + +var transition = { + setTransition, + transitionStart, + transitionEnd, +}; + +function slideTo (index = 0, speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + let slideIndex = index; + if (slideIndex < 0) slideIndex = 0; + + const { + params, snapGrid, slidesGrid, previousIndex, activeIndex, rtlTranslate: rtl, + } = swiper; + if (swiper.animating && params.preventInteractionOnTransition) { + return false; + } + + let snapIndex = Math.floor(slideIndex / params.slidesPerGroup); + if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; + + if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) { + swiper.emit('beforeSlideChangeStart'); + } + + const translate = -snapGrid[snapIndex]; + + // Update progress + swiper.updateProgress(translate); + + // Normalize slideIndex + if (params.normalizeSlideIndex) { + for (let i = 0; i < slidesGrid.length; i += 1) { + if (-Math.floor(translate * 100) >= Math.floor(slidesGrid[i] * 100)) { + slideIndex = i; + } + } + } + // Directions locks + if (swiper.initialized && slideIndex !== activeIndex) { + if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) { + return false; + } + if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) { + if ((activeIndex || 0) !== slideIndex) return false; + } + } + + let direction; + if (slideIndex > activeIndex) direction = 'next'; + else if (slideIndex < activeIndex) direction = 'prev'; + else direction = 'reset'; + + + // Update Index + if ((rtl && -translate === swiper.translate) || (!rtl && translate === swiper.translate)) { + swiper.updateActiveIndex(slideIndex); + // Update Height + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + swiper.updateSlidesClasses(); + if (params.effect !== 'slide') { + swiper.setTranslate(translate); + } + if (direction !== 'reset') { + swiper.transitionStart(runCallbacks, direction); + swiper.transitionEnd(runCallbacks, direction); + } + return false; + } + + if (speed === 0 || !Support.transition) { + swiper.setTransition(0); + swiper.setTranslate(translate); + swiper.updateActiveIndex(slideIndex); + swiper.updateSlidesClasses(); + swiper.emit('beforeTransitionStart', speed, internal); + swiper.transitionStart(runCallbacks, direction); + swiper.transitionEnd(runCallbacks, direction); + } else { + swiper.setTransition(speed); + swiper.setTranslate(translate); + swiper.updateActiveIndex(slideIndex); + swiper.updateSlidesClasses(); + swiper.emit('beforeTransitionStart', speed, internal); + swiper.transitionStart(runCallbacks, direction); + if (!swiper.animating) { + swiper.animating = true; + if (!swiper.onSlideToWrapperTransitionEnd) { + swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) { + if (!swiper || swiper.destroyed) return; + if (e.target !== this) return; + swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); + swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); + swiper.onSlideToWrapperTransitionEnd = null; + delete swiper.onSlideToWrapperTransitionEnd; + swiper.transitionEnd(runCallbacks, direction); + }; + } + swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); + swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); + } + } + + return true; +} + +function slideToLoop (index = 0, speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + let newIndex = index; + if (swiper.params.loop) { + newIndex += swiper.loopedSlides; + } + + return swiper.slideTo(newIndex, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slideNext (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + const { params, animating } = swiper; + if (params.loop) { + if (animating) return false; + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal); + } + return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slidePrev (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + const { + params, animating, snapGrid, slidesGrid, rtlTranslate, + } = swiper; + + if (params.loop) { + if (animating) return false; + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + } + const translate = rtlTranslate ? swiper.translate : -swiper.translate; + function normalize(val) { + if (val < 0) return -Math.floor(Math.abs(val)); + return Math.floor(val); + } + const normalizedTranslate = normalize(translate); + const normalizedSnapGrid = snapGrid.map(val => normalize(val)); + const normalizedSlidesGrid = slidesGrid.map(val => normalize(val)); + + const currentSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate)]; + const prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1]; + let prevIndex; + if (typeof prevSnap !== 'undefined') { + prevIndex = slidesGrid.indexOf(prevSnap); + if (prevIndex < 0) prevIndex = swiper.activeIndex - 1; + } + return swiper.slideTo(prevIndex, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slideReset (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slideToClosest (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + let index = swiper.activeIndex; + const snapIndex = Math.floor(index / swiper.params.slidesPerGroup); + + if (snapIndex < swiper.snapGrid.length - 1) { + const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; + + const currentSnap = swiper.snapGrid[snapIndex]; + const nextSnap = swiper.snapGrid[snapIndex + 1]; + + if ((translate - currentSnap) > (nextSnap - currentSnap) / 2) { + index = swiper.params.slidesPerGroup; + } + } + + return swiper.slideTo(index, speed, runCallbacks, internal); +} + +function slideToClickedSlide () { + const swiper = this; + const { params, $wrapperEl } = swiper; + + const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView; + let slideToIndex = swiper.clickedIndex; + let realIndex; + if (params.loop) { + if (swiper.animating) return; + realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10); + if (params.centeredSlides) { + if ( + (slideToIndex < swiper.loopedSlides - (slidesPerView / 2)) + || (slideToIndex > (swiper.slides.length - swiper.loopedSlides) + (slidesPerView / 2)) + ) { + swiper.loopFix(); + slideToIndex = $wrapperEl + .children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`) + .eq(0) + .index(); + + Utils.nextTick(() => { + swiper.slideTo(slideToIndex); + }); + } else { + swiper.slideTo(slideToIndex); + } + } else if (slideToIndex > swiper.slides.length - slidesPerView) { + swiper.loopFix(); + slideToIndex = $wrapperEl + .children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`) + .eq(0) + .index(); + + Utils.nextTick(() => { + swiper.slideTo(slideToIndex); + }); + } else { + swiper.slideTo(slideToIndex); + } + } else { + swiper.slideTo(slideToIndex); + } +} + +var slide = { + slideTo, + slideToLoop, + slideNext, + slidePrev, + slideReset, + slideToClosest, + slideToClickedSlide, +}; + +function loopCreate () { + const swiper = this; + const { params, $wrapperEl } = swiper; + // Remove duplicated slides + $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}`).remove(); + + let slides = $wrapperEl.children(`.${params.slideClass}`); + + if (params.loopFillGroupWithBlank) { + const blankSlidesNum = params.slidesPerGroup - (slides.length % params.slidesPerGroup); + if (blankSlidesNum !== params.slidesPerGroup) { + for (let i = 0; i < blankSlidesNum; i += 1) { + const blankNode = $(document.createElement('div')).addClass(`${params.slideClass} ${params.slideBlankClass}`); + $wrapperEl.append(blankNode); + } + slides = $wrapperEl.children(`.${params.slideClass}`); + } + } + + if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length; + + swiper.loopedSlides = parseInt(params.loopedSlides || params.slidesPerView, 10); + swiper.loopedSlides += params.loopAdditionalSlides; + if (swiper.loopedSlides > slides.length) { + swiper.loopedSlides = slides.length; + } + + const prependSlides = []; + const appendSlides = []; + slides.each((index, el) => { + const slide = $(el); + if (index < swiper.loopedSlides) appendSlides.push(el); + if (index < slides.length && index >= slides.length - swiper.loopedSlides) prependSlides.push(el); + slide.attr('data-swiper-slide-index', index); + }); + for (let i = 0; i < appendSlides.length; i += 1) { + $wrapperEl.append($(appendSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass)); + } + for (let i = prependSlides.length - 1; i >= 0; i -= 1) { + $wrapperEl.prepend($(prependSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass)); + } +} + +function loopFix () { + const swiper = this; + const { + params, activeIndex, slides, loopedSlides, allowSlidePrev, allowSlideNext, snapGrid, rtlTranslate: rtl, + } = swiper; + let newIndex; + swiper.allowSlidePrev = true; + swiper.allowSlideNext = true; + + const snapTranslate = -snapGrid[activeIndex]; + const diff = snapTranslate - swiper.getTranslate(); + + + // Fix For Negative Oversliding + if (activeIndex < loopedSlides) { + newIndex = (slides.length - (loopedSlides * 3)) + activeIndex; + newIndex += loopedSlides; + const slideChanged = swiper.slideTo(newIndex, 0, false, true); + if (slideChanged && diff !== 0) { + swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); + } + } else if ((params.slidesPerView === 'auto' && activeIndex >= loopedSlides * 2) || (activeIndex >= slides.length - loopedSlides)) { + // Fix For Positive Oversliding + newIndex = -slides.length + activeIndex + loopedSlides; + newIndex += loopedSlides; + const slideChanged = swiper.slideTo(newIndex, 0, false, true); + if (slideChanged && diff !== 0) { + swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); + } + } + swiper.allowSlidePrev = allowSlidePrev; + swiper.allowSlideNext = allowSlideNext; +} + +function loopDestroy () { + const swiper = this; + const { $wrapperEl, params, slides } = swiper; + $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass},.${params.slideClass}.${params.slideBlankClass}`).remove(); + slides.removeAttr('data-swiper-slide-index'); +} + +var loop = { + loopCreate, + loopFix, + loopDestroy, +}; + +function setGrabCursor (moving) { + const swiper = this; + if (Support.touch || !swiper.params.simulateTouch || (swiper.params.watchOverflow && swiper.isLocked)) return; + const el = swiper.el; + el.style.cursor = 'move'; + el.style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab'; + el.style.cursor = moving ? '-moz-grabbin' : '-moz-grab'; + el.style.cursor = moving ? 'grabbing' : 'grab'; +} + +function unsetGrabCursor () { + const swiper = this; + if (Support.touch || (swiper.params.watchOverflow && swiper.isLocked)) return; + swiper.el.style.cursor = ''; +} + +var grabCursor = { + setGrabCursor, + unsetGrabCursor, +}; + +function appendSlide (slides) { + const swiper = this; + const { $wrapperEl, params } = swiper; + if (params.loop) { + swiper.loopDestroy(); + } + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) $wrapperEl.append(slides[i]); + } + } else { + $wrapperEl.append(slides); + } + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } +} + +function prependSlide (slides) { + const swiper = this; + const { params, $wrapperEl, activeIndex } = swiper; + + if (params.loop) { + swiper.loopDestroy(); + } + let newActiveIndex = activeIndex + 1; + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) $wrapperEl.prepend(slides[i]); + } + newActiveIndex = activeIndex + slides.length; + } else { + $wrapperEl.prepend(slides); + } + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } + swiper.slideTo(newActiveIndex, 0, false); +} + +function addSlide (index, slides) { + const swiper = this; + const { $wrapperEl, params, activeIndex } = swiper; + let activeIndexBuffer = activeIndex; + if (params.loop) { + activeIndexBuffer -= swiper.loopedSlides; + swiper.loopDestroy(); + swiper.slides = $wrapperEl.children(`.${params.slideClass}`); + } + const baseLength = swiper.slides.length; + if (index <= 0) { + swiper.prependSlide(slides); + return; + } + if (index >= baseLength) { + swiper.appendSlide(slides); + return; + } + let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer; + + const slidesBuffer = []; + for (let i = baseLength - 1; i >= index; i -= 1) { + const currentSlide = swiper.slides.eq(i); + currentSlide.remove(); + slidesBuffer.unshift(currentSlide); + } + + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) $wrapperEl.append(slides[i]); + } + newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer; + } else { + $wrapperEl.append(slides); + } + + for (let i = 0; i < slidesBuffer.length; i += 1) { + $wrapperEl.append(slidesBuffer[i]); + } + + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } + if (params.loop) { + swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); + } else { + swiper.slideTo(newActiveIndex, 0, false); + } +} + +function removeSlide (slidesIndexes) { + const swiper = this; + const { params, $wrapperEl, activeIndex } = swiper; + + let activeIndexBuffer = activeIndex; + if (params.loop) { + activeIndexBuffer -= swiper.loopedSlides; + swiper.loopDestroy(); + swiper.slides = $wrapperEl.children(`.${params.slideClass}`); + } + let newActiveIndex = activeIndexBuffer; + let indexToRemove; + + if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) { + for (let i = 0; i < slidesIndexes.length; i += 1) { + indexToRemove = slidesIndexes[i]; + if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove(); + if (indexToRemove < newActiveIndex) newActiveIndex -= 1; + } + newActiveIndex = Math.max(newActiveIndex, 0); + } else { + indexToRemove = slidesIndexes; + if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove(); + if (indexToRemove < newActiveIndex) newActiveIndex -= 1; + newActiveIndex = Math.max(newActiveIndex, 0); + } + + if (params.loop) { + swiper.loopCreate(); + } + + if (!(params.observer && Support.observer)) { + swiper.update(); + } + if (params.loop) { + swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); + } else { + swiper.slideTo(newActiveIndex, 0, false); + } +} + +function removeAllSlides () { + const swiper = this; + + const slidesIndexes = []; + for (let i = 0; i < swiper.slides.length; i += 1) { + slidesIndexes.push(i); + } + swiper.removeSlide(slidesIndexes); +} + +var manipulation = { + appendSlide, + prependSlide, + addSlide, + removeSlide, + removeAllSlides, +}; + +const Device = (function Device() { + const ua = window.navigator.userAgent; + + const device = { + ios: false, + android: false, + androidChrome: false, + desktop: false, + windows: false, + iphone: false, + ipod: false, + ipad: false, + cordova: window.cordova || window.phonegap, + phonegap: window.cordova || window.phonegap, + }; + + const windows = ua.match(/(Windows Phone);?[\s\/]+([\d.]+)?/); // eslint-disable-line + const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line + const ipad = ua.match(/(iPad).*OS\s([\d_]+)/); + const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); + const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/); + + + // Windows + if (windows) { + device.os = 'windows'; + device.osVersion = windows[2]; + device.windows = true; + } + // Android + if (android && !windows) { + device.os = 'android'; + device.osVersion = android[2]; + device.android = true; + device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0; + } + if (ipad || iphone || ipod) { + device.os = 'ios'; + device.ios = true; + } + // iOS + if (iphone && !ipod) { + device.osVersion = iphone[2].replace(/_/g, '.'); + device.iphone = true; + } + if (ipad) { + device.osVersion = ipad[2].replace(/_/g, '.'); + device.ipad = true; + } + if (ipod) { + device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null; + device.iphone = true; + } + // iOS 8+ changed UA + if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) { + if (device.osVersion.split('.')[0] === '10') { + device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0]; + } + } + + // Desktop + device.desktop = !(device.os || device.android || device.webView); + + // Webview + device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i); + + // Minimal UI + if (device.os && device.os === 'ios') { + const osVersionArr = device.osVersion.split('.'); + const metaViewport = document.querySelector('meta[name="viewport"]'); + device.minimalUi = !device.webView + && (ipod || iphone) + && (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7) + && metaViewport && metaViewport.getAttribute('content').indexOf('minimal-ui') >= 0; + } + + // Pixel Ratio + device.pixelRatio = window.devicePixelRatio || 1; + + // Export object + return device; +}()); + +function onTouchStart (event) { + const swiper = this; + const data = swiper.touchEventsData; + const { params, touches } = swiper; + if (swiper.animating && params.preventInteractionOnTransition) { + return; + } + let e = event; + if (e.originalEvent) e = e.originalEvent; + data.isTouchEvent = e.type === 'touchstart'; + if (!data.isTouchEvent && 'which' in e && e.which === 3) return; + if (!data.isTouchEvent && 'button' in e && e.button > 0) return; + if (data.isTouched && data.isMoved) return; + if (params.noSwiping && $(e.target).closest(params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`)[0]) { + swiper.allowClick = true; + return; + } + if (params.swipeHandler) { + if (!$(e).closest(params.swipeHandler)[0]) return; + } + + touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; + touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; + const startX = touches.currentX; + const startY = touches.currentY; + + // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore + + const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection; + const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold; + if ( + edgeSwipeDetection + && ((startX <= edgeSwipeThreshold) + || (startX >= window.screen.width - edgeSwipeThreshold)) + ) { + return; + } + + Utils.extend(data, { + isTouched: true, + isMoved: false, + allowTouchCallbacks: true, + isScrolling: undefined, + startMoving: undefined, + }); + + touches.startX = startX; + touches.startY = startY; + data.touchStartTime = Utils.now(); + swiper.allowClick = true; + swiper.updateSize(); + swiper.swipeDirection = undefined; + if (params.threshold > 0) data.allowThresholdMove = false; + if (e.type !== 'touchstart') { + let preventDefault = true; + if ($(e.target).is(data.formElements)) preventDefault = false; + if ( + document.activeElement + && $(document.activeElement).is(data.formElements) + && document.activeElement !== e.target + ) { + document.activeElement.blur(); + } + + const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault; + if (params.touchStartForcePreventDefault || shouldPreventDefault) { + e.preventDefault(); + } + } + swiper.emit('touchStart', e); +} + +function onTouchMove (event) { + const swiper = this; + const data = swiper.touchEventsData; + const { params, touches, rtlTranslate: rtl } = swiper; + let e = event; + if (e.originalEvent) e = e.originalEvent; + if (!data.isTouched) { + if (data.startMoving && data.isScrolling) { + swiper.emit('touchMoveOpposite', e); + } + return; + } + if (data.isTouchEvent && e.type === 'mousemove') return; + const pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; + const pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; + if (e.preventedByNestedSwiper) { + touches.startX = pageX; + touches.startY = pageY; + return; + } + if (!swiper.allowTouchMove) { + // isMoved = true; + swiper.allowClick = false; + if (data.isTouched) { + Utils.extend(touches, { + startX: pageX, + startY: pageY, + currentX: pageX, + currentY: pageY, + }); + data.touchStartTime = Utils.now(); + } + return; + } + if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) { + if (swiper.isVertical()) { + // Vertical + if ( + (pageY < touches.startY && swiper.translate <= swiper.maxTranslate()) + || (pageY > touches.startY && swiper.translate >= swiper.minTranslate()) + ) { + data.isTouched = false; + data.isMoved = false; + return; + } + } else if ( + (pageX < touches.startX && swiper.translate <= swiper.maxTranslate()) + || (pageX > touches.startX && swiper.translate >= swiper.minTranslate()) + ) { + return; + } + } + if (data.isTouchEvent && document.activeElement) { + if (e.target === document.activeElement && $(e.target).is(data.formElements)) { + data.isMoved = true; + swiper.allowClick = false; + return; + } + } + if (data.allowTouchCallbacks) { + swiper.emit('touchMove', e); + } + if (e.targetTouches && e.targetTouches.length > 1) return; + + touches.currentX = pageX; + touches.currentY = pageY; + + const diffX = touches.currentX - touches.startX; + const diffY = touches.currentY - touches.startY; + if (swiper.params.threshold && Math.sqrt((diffX ** 2) + (diffY ** 2)) < swiper.params.threshold) return; + + if (typeof data.isScrolling === 'undefined') { + let touchAngle; + if ((swiper.isHorizontal() && touches.currentY === touches.startY) || (swiper.isVertical() && touches.currentX === touches.startX)) { + data.isScrolling = false; + } else { + // eslint-disable-next-line + if ((diffX * diffX) + (diffY * diffY) >= 25) { + touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI; + data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : (90 - touchAngle > params.touchAngle); + } + } + } + if (data.isScrolling) { + swiper.emit('touchMoveOpposite', e); + } + if (typeof data.startMoving === 'undefined') { + if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) { + data.startMoving = true; + } + } + if (data.isScrolling) { + data.isTouched = false; + return; + } + if (!data.startMoving) { + return; + } + swiper.allowClick = false; + e.preventDefault(); + if (params.touchMoveStopPropagation && !params.nested) { + e.stopPropagation(); + } + + if (!data.isMoved) { + if (params.loop) { + swiper.loopFix(); + } + data.startTranslate = swiper.getTranslate(); + swiper.setTransition(0); + if (swiper.animating) { + swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend'); + } + data.allowMomentumBounce = false; + // Grab Cursor + if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { + swiper.setGrabCursor(true); + } + swiper.emit('sliderFirstMove', e); + } + swiper.emit('sliderMove', e); + data.isMoved = true; + + let diff = swiper.isHorizontal() ? diffX : diffY; + touches.diff = diff; + + diff *= params.touchRatio; + if (rtl) diff = -diff; + + swiper.swipeDirection = diff > 0 ? 'prev' : 'next'; + data.currentTranslate = diff + data.startTranslate; + + let disableParentSwiper = true; + let resistanceRatio = params.resistanceRatio; + if (params.touchReleaseOnEdges) { + resistanceRatio = 0; + } + if ((diff > 0 && data.currentTranslate > swiper.minTranslate())) { + disableParentSwiper = false; + if (params.resistance) data.currentTranslate = (swiper.minTranslate() - 1) + ((-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio); + } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) { + disableParentSwiper = false; + if (params.resistance) data.currentTranslate = (swiper.maxTranslate() + 1) - ((swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio); + } + + if (disableParentSwiper) { + e.preventedByNestedSwiper = true; + } + + // Directions locks + if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) { + data.currentTranslate = data.startTranslate; + } + if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) { + data.currentTranslate = data.startTranslate; + } + + + // Threshold + if (params.threshold > 0) { + if (Math.abs(diff) > params.threshold || data.allowThresholdMove) { + if (!data.allowThresholdMove) { + data.allowThresholdMove = true; + touches.startX = touches.currentX; + touches.startY = touches.currentY; + data.currentTranslate = data.startTranslate; + touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY; + return; + } + } else { + data.currentTranslate = data.startTranslate; + return; + } + } + + if (!params.followFinger) return; + + // Update active index in free mode + if (params.freeMode || params.watchSlidesProgress || params.watchSlidesVisibility) { + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + if (params.freeMode) { + // Velocity + if (data.velocities.length === 0) { + data.velocities.push({ + position: touches[swiper.isHorizontal() ? 'startX' : 'startY'], + time: data.touchStartTime, + }); + } + data.velocities.push({ + position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'], + time: Utils.now(), + }); + } + // Update progress + swiper.updateProgress(data.currentTranslate); + // Update translate + swiper.setTranslate(data.currentTranslate); +} + +function onTouchEnd (event) { + const swiper = this; + const data = swiper.touchEventsData; + + const { + params, touches, rtlTranslate: rtl, $wrapperEl, slidesGrid, snapGrid, + } = swiper; + let e = event; + if (e.originalEvent) e = e.originalEvent; + if (data.allowTouchCallbacks) { + swiper.emit('touchEnd', e); + } + data.allowTouchCallbacks = false; + if (!data.isTouched) { + if (data.isMoved && params.grabCursor) { + swiper.setGrabCursor(false); + } + data.isMoved = false; + data.startMoving = false; + return; + } + // Return Grab Cursor + if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { + swiper.setGrabCursor(false); + } + + // Time diff + const touchEndTime = Utils.now(); + const timeDiff = touchEndTime - data.touchStartTime; + + // Tap, doubleTap, Click + if (swiper.allowClick) { + swiper.updateClickedSlide(e); + swiper.emit('tap', e); + if (timeDiff < 300 && (touchEndTime - data.lastClickTime) > 300) { + if (data.clickTimeout) clearTimeout(data.clickTimeout); + data.clickTimeout = Utils.nextTick(() => { + if (!swiper || swiper.destroyed) return; + swiper.emit('click', e); + }, 300); + } + if (timeDiff < 300 && (touchEndTime - data.lastClickTime) < 300) { + if (data.clickTimeout) clearTimeout(data.clickTimeout); + swiper.emit('doubleTap', e); + } + } + + data.lastClickTime = Utils.now(); + Utils.nextTick(() => { + if (!swiper.destroyed) swiper.allowClick = true; + }); + + if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) { + data.isTouched = false; + data.isMoved = false; + data.startMoving = false; + return; + } + data.isTouched = false; + data.isMoved = false; + data.startMoving = false; + + let currentPos; + if (params.followFinger) { + currentPos = rtl ? swiper.translate : -swiper.translate; + } else { + currentPos = -data.currentTranslate; + } + + if (params.freeMode) { + if (currentPos < -swiper.minTranslate()) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (currentPos > -swiper.maxTranslate()) { + if (swiper.slides.length < snapGrid.length) { + swiper.slideTo(snapGrid.length - 1); + } else { + swiper.slideTo(swiper.slides.length - 1); + } + return; + } + + if (params.freeModeMomentum) { + if (data.velocities.length > 1) { + const lastMoveEvent = data.velocities.pop(); + const velocityEvent = data.velocities.pop(); + + const distance = lastMoveEvent.position - velocityEvent.position; + const time = lastMoveEvent.time - velocityEvent.time; + swiper.velocity = distance / time; + swiper.velocity /= 2; + if (Math.abs(swiper.velocity) < params.freeModeMinimumVelocity) { + swiper.velocity = 0; + } + // this implies that the user stopped moving a finger then released. + // There would be no events with distance zero, so the last event is stale. + if (time > 150 || (Utils.now() - lastMoveEvent.time) > 300) { + swiper.velocity = 0; + } + } else { + swiper.velocity = 0; + } + swiper.velocity *= params.freeModeMomentumVelocityRatio; + + data.velocities.length = 0; + let momentumDuration = 1000 * params.freeModeMomentumRatio; + const momentumDistance = swiper.velocity * momentumDuration; + + let newPosition = swiper.translate + momentumDistance; + if (rtl) newPosition = -newPosition; + + let doBounce = false; + let afterBouncePosition; + const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeModeMomentumBounceRatio; + let needsLoopFix; + if (newPosition < swiper.maxTranslate()) { + if (params.freeModeMomentumBounce) { + if (newPosition + swiper.maxTranslate() < -bounceAmount) { + newPosition = swiper.maxTranslate() - bounceAmount; + } + afterBouncePosition = swiper.maxTranslate(); + doBounce = true; + data.allowMomentumBounce = true; + } else { + newPosition = swiper.maxTranslate(); + } + if (params.loop && params.centeredSlides) needsLoopFix = true; + } else if (newPosition > swiper.minTranslate()) { + if (params.freeModeMomentumBounce) { + if (newPosition - swiper.minTranslate() > bounceAmount) { + newPosition = swiper.minTranslate() + bounceAmount; + } + afterBouncePosition = swiper.minTranslate(); + doBounce = true; + data.allowMomentumBounce = true; + } else { + newPosition = swiper.minTranslate(); + } + if (params.loop && params.centeredSlides) needsLoopFix = true; + } else if (params.freeModeSticky) { + let nextSlide; + for (let j = 0; j < snapGrid.length; j += 1) { + if (snapGrid[j] > -newPosition) { + nextSlide = j; + break; + } + } + + if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') { + newPosition = snapGrid[nextSlide]; + } else { + newPosition = snapGrid[nextSlide - 1]; + } + newPosition = -newPosition; + } + if (needsLoopFix) { + swiper.once('transitionEnd', () => { + swiper.loopFix(); + }); + } + // Fix duration + if (swiper.velocity !== 0) { + if (rtl) { + momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity); + } else { + momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity); + } + } else if (params.freeModeSticky) { + swiper.slideToClosest(); + return; + } + + if (params.freeModeMomentumBounce && doBounce) { + swiper.updateProgress(afterBouncePosition); + swiper.setTransition(momentumDuration); + swiper.setTranslate(newPosition); + swiper.transitionStart(true, swiper.swipeDirection); + swiper.animating = true; + $wrapperEl.transitionEnd(() => { + if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return; + swiper.emit('momentumBounce'); + + swiper.setTransition(params.speed); + swiper.setTranslate(afterBouncePosition); + $wrapperEl.transitionEnd(() => { + if (!swiper || swiper.destroyed) return; + swiper.transitionEnd(); + }); + }); + } else if (swiper.velocity) { + swiper.updateProgress(newPosition); + swiper.setTransition(momentumDuration); + swiper.setTranslate(newPosition); + swiper.transitionStart(true, swiper.swipeDirection); + if (!swiper.animating) { + swiper.animating = true; + $wrapperEl.transitionEnd(() => { + if (!swiper || swiper.destroyed) return; + swiper.transitionEnd(); + }); + } + } else { + swiper.updateProgress(newPosition); + } + + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } else if (params.freeModeSticky) { + swiper.slideToClosest(); + return; + } + + if (!params.freeModeMomentum || timeDiff >= params.longSwipesMs) { + swiper.updateProgress(); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + return; + } + + // Find current slide + let stopIndex = 0; + let groupSize = swiper.slidesSizesGrid[0]; + for (let i = 0; i < slidesGrid.length; i += params.slidesPerGroup) { + if (typeof slidesGrid[i + params.slidesPerGroup] !== 'undefined') { + if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + params.slidesPerGroup]) { + stopIndex = i; + groupSize = slidesGrid[i + params.slidesPerGroup] - slidesGrid[i]; + } + } else if (currentPos >= slidesGrid[i]) { + stopIndex = i; + groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2]; + } + } + + // Find current slide size + const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize; + + if (timeDiff > params.longSwipesMs) { + // Long touches + if (!params.longSwipes) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (swiper.swipeDirection === 'next') { + if (ratio >= params.longSwipesRatio) swiper.slideTo(stopIndex + params.slidesPerGroup); + else swiper.slideTo(stopIndex); + } + if (swiper.swipeDirection === 'prev') { + if (ratio > (1 - params.longSwipesRatio)) swiper.slideTo(stopIndex + params.slidesPerGroup); + else swiper.slideTo(stopIndex); + } + } else { + // Short swipes + if (!params.shortSwipes) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (swiper.swipeDirection === 'next') { + swiper.slideTo(stopIndex + params.slidesPerGroup); + } + if (swiper.swipeDirection === 'prev') { + swiper.slideTo(stopIndex); + } + } +} + +function onResize () { + const swiper = this; + + const { params, el } = swiper; + + if (el && el.offsetWidth === 0) return; + + // Breakpoints + if (params.breakpoints) { + swiper.setBreakpoint(); + } + + // Save locks + const { allowSlideNext, allowSlidePrev, snapGrid } = swiper; + + // Disable locks on resize + swiper.allowSlideNext = true; + swiper.allowSlidePrev = true; + + swiper.updateSize(); + swiper.updateSlides(); + + if (params.freeMode) { + const newTranslate = Math.min(Math.max(swiper.translate, swiper.maxTranslate()), swiper.minTranslate()); + swiper.setTranslate(newTranslate); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + } else { + swiper.updateSlidesClasses(); + if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) { + swiper.slideTo(swiper.slides.length - 1, 0, false, true); + } else { + swiper.slideTo(swiper.activeIndex, 0, false, true); + } + } + // Return locks after resize + swiper.allowSlidePrev = allowSlidePrev; + swiper.allowSlideNext = allowSlideNext; + + if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) { + swiper.checkOverflow(); + } +} + +function onClick (e) { + const swiper = this; + if (!swiper.allowClick) { + if (swiper.params.preventClicks) e.preventDefault(); + if (swiper.params.preventClicksPropagation && swiper.animating) { + e.stopPropagation(); + e.stopImmediatePropagation(); + } + } +} + +function attachEvents() { + const swiper = this; + const { + params, touchEvents, el, wrapperEl, + } = swiper; + + { + swiper.onTouchStart = onTouchStart.bind(swiper); + swiper.onTouchMove = onTouchMove.bind(swiper); + swiper.onTouchEnd = onTouchEnd.bind(swiper); + } + + swiper.onClick = onClick.bind(swiper); + + const target = params.touchEventsTarget === 'container' ? el : wrapperEl; + const capture = !!params.nested; + + // Touch Events + { + if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) { + target.addEventListener(touchEvents.start, swiper.onTouchStart, false); + document.addEventListener(touchEvents.move, swiper.onTouchMove, capture); + document.addEventListener(touchEvents.end, swiper.onTouchEnd, false); + } else { + if (Support.touch) { + const passiveListener = touchEvents.start === 'touchstart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + target.addEventListener(touchEvents.start, swiper.onTouchStart, passiveListener); + target.addEventListener(touchEvents.move, swiper.onTouchMove, Support.passiveListener ? { passive: false, capture } : capture); + target.addEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener); + } + if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) { + target.addEventListener('mousedown', swiper.onTouchStart, false); + document.addEventListener('mousemove', swiper.onTouchMove, capture); + document.addEventListener('mouseup', swiper.onTouchEnd, false); + } + } + // Prevent Links Clicks + if (params.preventClicks || params.preventClicksPropagation) { + target.addEventListener('click', swiper.onClick, true); + } + } + + // Resize handler + swiper.on((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize, true); +} + +function detachEvents() { + const swiper = this; + + const { + params, touchEvents, el, wrapperEl, + } = swiper; + + const target = params.touchEventsTarget === 'container' ? el : wrapperEl; + const capture = !!params.nested; + + // Touch Events + { + if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) { + target.removeEventListener(touchEvents.start, swiper.onTouchStart, false); + document.removeEventListener(touchEvents.move, swiper.onTouchMove, capture); + document.removeEventListener(touchEvents.end, swiper.onTouchEnd, false); + } else { + if (Support.touch) { + const passiveListener = touchEvents.start === 'onTouchStart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + target.removeEventListener(touchEvents.start, swiper.onTouchStart, passiveListener); + target.removeEventListener(touchEvents.move, swiper.onTouchMove, capture); + target.removeEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener); + } + if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) { + target.removeEventListener('mousedown', swiper.onTouchStart, false); + document.removeEventListener('mousemove', swiper.onTouchMove, capture); + document.removeEventListener('mouseup', swiper.onTouchEnd, false); + } + } + // Prevent Links Clicks + if (params.preventClicks || params.preventClicksPropagation) { + target.removeEventListener('click', swiper.onClick, true); + } + } + + // Resize handler + swiper.off((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize); +} + +var events = { + attachEvents, + detachEvents, +}; + +function setBreakpoint () { + const swiper = this; + const { + activeIndex, initialized, loopedSlides = 0, params, + } = swiper; + const breakpoints = params.breakpoints; + if (!breakpoints || (breakpoints && Object.keys(breakpoints).length === 0)) return; + + // Set breakpoint for window width and update parameters + const breakpoint = swiper.getBreakpoint(breakpoints); + + if (breakpoint && swiper.currentBreakpoint !== breakpoint) { + const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined; + if (breakpointOnlyParams) { + ['slidesPerView', 'spaceBetween', 'slidesPerGroup'].forEach((param) => { + const paramValue = breakpointOnlyParams[param]; + if (typeof paramValue === 'undefined') return; + if (param === 'slidesPerView' && (paramValue === 'AUTO' || paramValue === 'auto')) { + breakpointOnlyParams[param] = 'auto'; + } else if (param === 'slidesPerView') { + breakpointOnlyParams[param] = parseFloat(paramValue); + } else { + breakpointOnlyParams[param] = parseInt(paramValue, 10); + } + }); + } + + const breakpointParams = breakpointOnlyParams || swiper.originalParams; + const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction; + const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged); + + if (directionChanged && initialized) { + swiper.changeDirection(); + } + + Utils.extend(swiper.params, breakpointParams); + + Utils.extend(swiper, { + allowTouchMove: swiper.params.allowTouchMove, + allowSlideNext: swiper.params.allowSlideNext, + allowSlidePrev: swiper.params.allowSlidePrev, + }); + + swiper.currentBreakpoint = breakpoint; + + if (needsReLoop && initialized) { + swiper.loopDestroy(); + swiper.loopCreate(); + swiper.updateSlides(); + swiper.slideTo((activeIndex - loopedSlides) + swiper.loopedSlides, 0, false); + } + + swiper.emit('breakpoint', breakpointParams); + } +} + +function getBreakpoint (breakpoints) { + const swiper = this; + // Get breakpoint for window width + if (!breakpoints) return undefined; + let breakpoint = false; + const points = []; + Object.keys(breakpoints).forEach((point) => { + points.push(point); + }); + points.sort((a, b) => parseInt(a, 10) - parseInt(b, 10)); + for (let i = 0; i < points.length; i += 1) { + const point = points[i]; + if (swiper.params.breakpointsInverse) { + if (point <= window.innerWidth) { + breakpoint = point; + } + } else if (point >= window.innerWidth && !breakpoint) { + breakpoint = point; + } + } + return breakpoint || 'max'; +} + +var breakpoints = { setBreakpoint, getBreakpoint }; + +function addClasses () { + const swiper = this; + const { + classNames, params, rtl, $el, + } = swiper; + const suffixes = []; + + suffixes.push('initialized'); + suffixes.push(params.direction); + + if (params.freeMode) { + suffixes.push('free-mode'); + } + if (!Support.flexbox) { + suffixes.push('no-flexbox'); + } + if (params.autoHeight) { + suffixes.push('autoheight'); + } + if (rtl) { + suffixes.push('rtl'); + } + if (params.slidesPerColumn > 1) { + suffixes.push('multirow'); + } + if (Device.android) { + suffixes.push('android'); + } + if (Device.ios) { + suffixes.push('ios'); + } + // WP8 Touch Events Fix + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + suffixes.push(`wp8-${params.direction}`); + } + + suffixes.forEach((suffix) => { + classNames.push(params.containerModifierClass + suffix); + }); + + $el.addClass(classNames.join(' ')); +} + +function removeClasses () { + const swiper = this; + const { $el, classNames } = swiper; + + $el.removeClass(classNames.join(' ')); +} + +var classes = { addClasses, removeClasses }; + +function loadImage (imageEl, src, srcset, sizes, checkForComplete, callback) { + let image; + function onReady() { + if (callback) callback(); + } + if (!imageEl.complete || !checkForComplete) { + if (src) { + image = new window.Image(); + image.onload = onReady; + image.onerror = onReady; + if (sizes) { + image.sizes = sizes; + } + if (srcset) { + image.srcset = srcset; + } + if (src) { + image.src = src; + } + } else { + onReady(); + } + } else { + // image already loaded... + onReady(); + } +} + +function preloadImages () { + const swiper = this; + swiper.imagesToLoad = swiper.$el.find('img'); + function onReady() { + if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) return; + if (swiper.imagesLoaded !== undefined) swiper.imagesLoaded += 1; + if (swiper.imagesLoaded === swiper.imagesToLoad.length) { + if (swiper.params.updateOnImagesReady) swiper.update(); + swiper.emit('imagesReady'); + } + } + for (let i = 0; i < swiper.imagesToLoad.length; i += 1) { + const imageEl = swiper.imagesToLoad[i]; + swiper.loadImage( + imageEl, + imageEl.currentSrc || imageEl.getAttribute('src'), + imageEl.srcset || imageEl.getAttribute('srcset'), + imageEl.sizes || imageEl.getAttribute('sizes'), + true, + onReady + ); + } +} + +var images = { + loadImage, + preloadImages, +}; + +function checkOverflow() { + const swiper = this; + const wasLocked = swiper.isLocked; + + swiper.isLocked = swiper.snapGrid.length === 1; + swiper.allowSlideNext = !swiper.isLocked; + swiper.allowSlidePrev = !swiper.isLocked; + + // events + if (wasLocked !== swiper.isLocked) swiper.emit(swiper.isLocked ? 'lock' : 'unlock'); + + if (wasLocked && wasLocked !== swiper.isLocked) { + swiper.isEnd = false; + swiper.navigation.update(); + } +} + +var checkOverflow$1 = { checkOverflow }; + +var defaults = { + init: true, + direction: 'horizontal', + touchEventsTarget: 'container', + initialSlide: 0, + speed: 300, + // + preventInteractionOnTransition: false, + + // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView). + edgeSwipeDetection: false, + edgeSwipeThreshold: 20, + + // Free mode + freeMode: false, + freeModeMomentum: true, + freeModeMomentumRatio: 1, + freeModeMomentumBounce: true, + freeModeMomentumBounceRatio: 1, + freeModeMomentumVelocityRatio: 1, + freeModeSticky: false, + freeModeMinimumVelocity: 0.02, + + // Autoheight + autoHeight: false, + + // Set wrapper width + setWrapperSize: false, + + // Virtual Translate + virtualTranslate: false, + + // Effects + effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip' + + // Breakpoints + breakpoints: undefined, + breakpointsInverse: false, + + // Slides grid + spaceBetween: 0, + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerColumnFill: 'column', + slidesPerGroup: 1, + centeredSlides: false, + slidesOffsetBefore: 0, // in px + slidesOffsetAfter: 0, // in px + normalizeSlideIndex: true, + centerInsufficientSlides: false, + + // Disable swiper and hide navigation when container not overflow + watchOverflow: false, + + // Round length + roundLengths: false, + + // Touches + touchRatio: 1, + touchAngle: 45, + simulateTouch: true, + shortSwipes: true, + longSwipes: true, + longSwipesRatio: 0.5, + longSwipesMs: 300, + followFinger: true, + allowTouchMove: true, + threshold: 0, + touchMoveStopPropagation: true, + touchStartPreventDefault: true, + touchStartForcePreventDefault: false, + touchReleaseOnEdges: false, + + // Unique Navigation Elements + uniqueNavElements: true, + + // Resistance + resistance: true, + resistanceRatio: 0.85, + + // Progress + watchSlidesProgress: false, + watchSlidesVisibility: false, + + // Cursor + grabCursor: false, + + // Clicks + preventClicks: true, + preventClicksPropagation: true, + slideToClickedSlide: false, + + // Images + preloadImages: true, + updateOnImagesReady: true, + + // loop + loop: false, + loopAdditionalSlides: 0, + loopedSlides: null, + loopFillGroupWithBlank: false, + + // Swiping/no swiping + allowSlidePrev: true, + allowSlideNext: true, + swipeHandler: null, // '.swipe-handler', + noSwiping: true, + noSwipingClass: 'swiper-no-swiping', + noSwipingSelector: null, + + // Passive Listeners + passiveListeners: true, + + // NS + containerModifierClass: 'swiper-container-', // NEW + slideClass: 'swiper-slide', + slideBlankClass: 'swiper-slide-invisible-blank', + slideActiveClass: 'swiper-slide-active', + slideDuplicateActiveClass: 'swiper-slide-duplicate-active', + slideVisibleClass: 'swiper-slide-visible', + slideDuplicateClass: 'swiper-slide-duplicate', + slideNextClass: 'swiper-slide-next', + slideDuplicateNextClass: 'swiper-slide-duplicate-next', + slidePrevClass: 'swiper-slide-prev', + slideDuplicatePrevClass: 'swiper-slide-duplicate-prev', + wrapperClass: 'swiper-wrapper', + + // Callbacks + runCallbacksOnInit: true, +}; + +/* eslint no-param-reassign: "off" */ + +const prototypes = { + update, + translate, + transition, + slide, + loop, + grabCursor, + manipulation, + events, + breakpoints, + checkOverflow: checkOverflow$1, + classes, + images, +}; + +const extendedDefaults = {}; + +class Swiper extends SwiperClass { + constructor(...args) { + let el; + let params; + if (args.length === 1 && args[0].constructor && args[0].constructor === Object) { + params = args[0]; + } else { + [el, params] = args; + } + if (!params) params = {}; + + params = Utils.extend({}, params); + if (el && !params.el) params.el = el; + + super(params); + + Object.keys(prototypes).forEach((prototypeGroup) => { + Object.keys(prototypes[prototypeGroup]).forEach((protoMethod) => { + if (!Swiper.prototype[protoMethod]) { + Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod]; + } + }); + }); + + // Swiper Instance + const swiper = this; + if (typeof swiper.modules === 'undefined') { + swiper.modules = {}; + } + Object.keys(swiper.modules).forEach((moduleName) => { + const module = swiper.modules[moduleName]; + if (module.params) { + const moduleParamName = Object.keys(module.params)[0]; + const moduleParams = module.params[moduleParamName]; + if (typeof moduleParams !== 'object' || moduleParams === null) return; + if (!(moduleParamName in params && 'enabled' in moduleParams)) return; + if (params[moduleParamName] === true) { + params[moduleParamName] = { enabled: true }; + } + if ( + typeof params[moduleParamName] === 'object' + && !('enabled' in params[moduleParamName]) + ) { + params[moduleParamName].enabled = true; + } + if (!params[moduleParamName]) params[moduleParamName] = { enabled: false }; + } + }); + + // Extend defaults with modules params + const swiperParams = Utils.extend({}, defaults); + swiper.useModulesParams(swiperParams); + + // Extend defaults with passed params + swiper.params = Utils.extend({}, swiperParams, extendedDefaults, params); + swiper.originalParams = Utils.extend({}, swiper.params); + swiper.passedParams = Utils.extend({}, params); + + // Save Dom lib + swiper.$ = $; + + // Find el + const $el = $(swiper.params.el); + el = $el[0]; + + if (!el) { + return undefined; + } + + if ($el.length > 1) { + const swipers = []; + $el.each((index, containerEl) => { + const newParams = Utils.extend({}, params, { el: containerEl }); + swipers.push(new Swiper(newParams)); + }); + return swipers; + } + + el.swiper = swiper; + $el.data('swiper', swiper); + + // Find Wrapper + const $wrapperEl = $el.children(`.${swiper.params.wrapperClass}`); + + // Extend Swiper + Utils.extend(swiper, { + $el, + el, + $wrapperEl, + wrapperEl: $wrapperEl[0], + + // Classes + classNames: [], + + // Slides + slides: $(), + slidesGrid: [], + snapGrid: [], + slidesSizesGrid: [], + + // isDirection + isHorizontal() { + return swiper.params.direction === 'horizontal'; + }, + isVertical() { + return swiper.params.direction === 'vertical'; + }, + // RTL + rtl: (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'), + rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'), + wrongRTL: $wrapperEl.css('display') === '-webkit-box', + + // Indexes + activeIndex: 0, + realIndex: 0, + + // + isBeginning: true, + isEnd: false, + + // Props + translate: 0, + previousTranslate: 0, + progress: 0, + velocity: 0, + animating: false, + + // Locks + allowSlideNext: swiper.params.allowSlideNext, + allowSlidePrev: swiper.params.allowSlidePrev, + + // Touch Events + touchEvents: (function touchEvents() { + const touch = ['touchstart', 'touchmove', 'touchend']; + let desktop = ['mousedown', 'mousemove', 'mouseup']; + if (Support.pointerEvents) { + desktop = ['pointerdown', 'pointermove', 'pointerup']; + } else if (Support.prefixedPointerEvents) { + desktop = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp']; + } + swiper.touchEventsTouch = { + start: touch[0], + move: touch[1], + end: touch[2], + }; + swiper.touchEventsDesktop = { + start: desktop[0], + move: desktop[1], + end: desktop[2], + }; + return Support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop; + }()), + touchEventsData: { + isTouched: undefined, + isMoved: undefined, + allowTouchCallbacks: undefined, + touchStartTime: undefined, + isScrolling: undefined, + currentTranslate: undefined, + startTranslate: undefined, + allowThresholdMove: undefined, + // Form elements to match + formElements: 'input, select, option, textarea, button, video', + // Last click time + lastClickTime: Utils.now(), + clickTimeout: undefined, + // Velocities + velocities: [], + allowMomentumBounce: undefined, + isTouchEvent: undefined, + startMoving: undefined, + }, + + // Clicks + allowClick: true, + + // Touches + allowTouchMove: swiper.params.allowTouchMove, + + touches: { + startX: 0, + startY: 0, + currentX: 0, + currentY: 0, + diff: 0, + }, + + // Images + imagesToLoad: [], + imagesLoaded: 0, + + }); + + // Install Modules + swiper.useModules(); + + // Init + if (swiper.params.init) { + swiper.init(); + } + + // Return app instance + return swiper; + } + + slidesPerViewDynamic() { + const swiper = this; + const { + params, slides, slidesGrid, size: swiperSize, activeIndex, + } = swiper; + let spv = 1; + if (params.centeredSlides) { + let slideSize = slides[activeIndex].swiperSlideSize; + let breakLoop; + for (let i = activeIndex + 1; i < slides.length; i += 1) { + if (slides[i] && !breakLoop) { + slideSize += slides[i].swiperSlideSize; + spv += 1; + if (slideSize > swiperSize) breakLoop = true; + } + } + for (let i = activeIndex - 1; i >= 0; i -= 1) { + if (slides[i] && !breakLoop) { + slideSize += slides[i].swiperSlideSize; + spv += 1; + if (slideSize > swiperSize) breakLoop = true; + } + } + } else { + for (let i = activeIndex + 1; i < slides.length; i += 1) { + if (slidesGrid[i] - slidesGrid[activeIndex] < swiperSize) { + spv += 1; + } + } + } + return spv; + } + + update() { + const swiper = this; + if (!swiper || swiper.destroyed) return; + const { snapGrid, params } = swiper; + // Breakpoints + if (params.breakpoints) { + swiper.setBreakpoint(); + } + swiper.updateSize(); + swiper.updateSlides(); + swiper.updateProgress(); + swiper.updateSlidesClasses(); + + function setTranslate() { + const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate; + const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate()); + swiper.setTranslate(newTranslate); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + let translated; + if (swiper.params.freeMode) { + setTranslate(); + if (swiper.params.autoHeight) { + swiper.updateAutoHeight(); + } + } else { + if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) { + translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true); + } else { + translated = swiper.slideTo(swiper.activeIndex, 0, false, true); + } + if (!translated) { + setTranslate(); + } + } + if (params.watchOverflow && snapGrid !== swiper.snapGrid) { + swiper.checkOverflow(); + } + swiper.emit('update'); + } + + changeDirection(newDirection, needUpdate = true) { + const swiper = this; + const currentDirection = swiper.params.direction; + if (!newDirection) { + // eslint-disable-next-line + newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal'; + } + if ((newDirection === currentDirection) || (newDirection !== 'horizontal' && newDirection !== 'vertical')) { + return swiper; + } + + if (currentDirection === 'vertical') { + swiper.$el + .removeClass(`${swiper.params.containerModifierClass}vertical wp8-vertical`) + .addClass(`${swiper.params.containerModifierClass}${newDirection}`); + + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + swiper.$el.addClass(`${swiper.params.containerModifierClass}wp8-${newDirection}`); + } + } + if (currentDirection === 'horizontal') { + swiper.$el + .removeClass(`${swiper.params.containerModifierClass}horizontal wp8-horizontal`) + .addClass(`${swiper.params.containerModifierClass}${newDirection}`); + + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + swiper.$el.addClass(`${swiper.params.containerModifierClass}wp8-${newDirection}`); + } + } + + swiper.params.direction = newDirection; + + swiper.slides.each((slideIndex, slideEl) => { + if (newDirection === 'vertical') { + slideEl.style.width = ''; + } else { + slideEl.style.height = ''; + } + }); + + swiper.emit('changeDirection'); + if (needUpdate) swiper.update(); + + return swiper; + } + + init() { + const swiper = this; + if (swiper.initialized) return; + + swiper.emit('beforeInit'); + + // Set breakpoint + if (swiper.params.breakpoints) { + swiper.setBreakpoint(); + } + + // Add Classes + swiper.addClasses(); + + // Create loop + if (swiper.params.loop) { + swiper.loopCreate(); + } + + // Update size + swiper.updateSize(); + + // Update slides + swiper.updateSlides(); + + if (swiper.params.watchOverflow) { + swiper.checkOverflow(); + } + + // Set Grab Cursor + if (swiper.params.grabCursor) { + swiper.setGrabCursor(); + } + + if (swiper.params.preloadImages) { + swiper.preloadImages(); + } + + // Slide To Initial Slide + if (swiper.params.loop) { + swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit); + } else { + swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit); + } + + // Attach events + swiper.attachEvents(); + + // Init Flag + swiper.initialized = true; + + // Emit + swiper.emit('init'); + } + + destroy(deleteInstance = true, cleanStyles = true) { + const swiper = this; + const { + params, $el, $wrapperEl, slides, + } = swiper; + + if (typeof swiper.params === 'undefined' || swiper.destroyed) { + return null; + } + + swiper.emit('beforeDestroy'); + + // Init Flag + swiper.initialized = false; + + // Detach events + swiper.detachEvents(); + + // Destroy loop + if (params.loop) { + swiper.loopDestroy(); + } + + // Cleanup styles + if (cleanStyles) { + swiper.removeClasses(); + $el.removeAttr('style'); + $wrapperEl.removeAttr('style'); + if (slides && slides.length) { + slides + .removeClass([ + params.slideVisibleClass, + params.slideActiveClass, + params.slideNextClass, + params.slidePrevClass, + ].join(' ')) + .removeAttr('style') + .removeAttr('data-swiper-slide-index') + .removeAttr('data-swiper-column') + .removeAttr('data-swiper-row'); + } + } + + swiper.emit('destroy'); + + // Detach emitter events + Object.keys(swiper.eventsListeners).forEach((eventName) => { + swiper.off(eventName); + }); + + if (deleteInstance !== false) { + swiper.$el[0].swiper = null; + swiper.$el.data('swiper', null); + Utils.deleteProps(swiper); + } + swiper.destroyed = true; + + return null; + } + + static extendDefaults(newDefaults) { + Utils.extend(extendedDefaults, newDefaults); + } + + static get extendedDefaults() { + return extendedDefaults; + } + + static get defaults() { + return defaults; + } + + static get Class() { + return SwiperClass; + } + + static get $() { + return $; + } +} + +var Device$1 = { + name: 'device', + proto: { + device: Device, + }, + static: { + device: Device, + }, +}; + +var Support$1 = { + name: 'support', + proto: { + support: Support, + }, + static: { + support: Support, + }, +}; + +var Browser$1 = { + name: 'browser', + proto: { + browser: Browser, + }, + static: { + browser: Browser, + }, +}; + +var Resize = { + name: 'resize', + create() { + const swiper = this; + Utils.extend(swiper, { + resize: { + resizeHandler() { + if (!swiper || swiper.destroyed || !swiper.initialized) return; + swiper.emit('beforeResize'); + swiper.emit('resize'); + }, + orientationChangeHandler() { + if (!swiper || swiper.destroyed || !swiper.initialized) return; + swiper.emit('orientationchange'); + }, + }, + }); + }, + on: { + init() { + const swiper = this; + // Emit resize + window.addEventListener('resize', swiper.resize.resizeHandler); + + // Emit orientationchange + window.addEventListener('orientationchange', swiper.resize.orientationChangeHandler); + }, + destroy() { + const swiper = this; + window.removeEventListener('resize', swiper.resize.resizeHandler); + window.removeEventListener('orientationchange', swiper.resize.orientationChangeHandler); + }, + }, +}; + +const Observer = { + func: window.MutationObserver || window.WebkitMutationObserver, + attach(target, options = {}) { + const swiper = this; + + const ObserverFunc = Observer.func; + const observer = new ObserverFunc((mutations) => { + // The observerUpdate event should only be triggered + // once despite the number of mutations. Additional + // triggers are redundant and are very costly + if (mutations.length === 1) { + swiper.emit('observerUpdate', mutations[0]); + return; + } + const observerUpdate = function observerUpdate() { + swiper.emit('observerUpdate', mutations[0]); + }; + + if (window.requestAnimationFrame) { + window.requestAnimationFrame(observerUpdate); + } else { + window.setTimeout(observerUpdate, 0); + } + }); + + observer.observe(target, { + attributes: typeof options.attributes === 'undefined' ? true : options.attributes, + childList: typeof options.childList === 'undefined' ? true : options.childList, + characterData: typeof options.characterData === 'undefined' ? true : options.characterData, + }); + + swiper.observer.observers.push(observer); + }, + init() { + const swiper = this; + if (!Support.observer || !swiper.params.observer) return; + if (swiper.params.observeParents) { + const containerParents = swiper.$el.parents(); + for (let i = 0; i < containerParents.length; i += 1) { + swiper.observer.attach(containerParents[i]); + } + } + // Observe container + swiper.observer.attach(swiper.$el[0], { childList: swiper.params.observeSlideChildren }); + + // Observe wrapper + swiper.observer.attach(swiper.$wrapperEl[0], { attributes: false }); + }, + destroy() { + const swiper = this; + swiper.observer.observers.forEach((observer) => { + observer.disconnect(); + }); + swiper.observer.observers = []; + }, +}; + +var Observer$1 = { + name: 'observer', + params: { + observer: false, + observeParents: false, + observeSlideChildren: false, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + observer: { + init: Observer.init.bind(swiper), + attach: Observer.attach.bind(swiper), + destroy: Observer.destroy.bind(swiper), + observers: [], + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.observer.init(); + }, + destroy() { + const swiper = this; + swiper.observer.destroy(); + }, + }, +}; + +const Virtual = { + update(force) { + const swiper = this; + const { slidesPerView, slidesPerGroup, centeredSlides } = swiper.params; + const { addSlidesBefore, addSlidesAfter } = swiper.params.virtual; + const { + from: previousFrom, + to: previousTo, + slides, + slidesGrid: previousSlidesGrid, + renderSlide, + offset: previousOffset, + } = swiper.virtual; + swiper.updateActiveIndex(); + const activeIndex = swiper.activeIndex || 0; + + let offsetProp; + if (swiper.rtlTranslate) offsetProp = 'right'; + else offsetProp = swiper.isHorizontal() ? 'left' : 'top'; + + let slidesAfter; + let slidesBefore; + if (centeredSlides) { + slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore; + slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter; + } else { + slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesBefore; + slidesBefore = slidesPerGroup + addSlidesAfter; + } + const from = Math.max((activeIndex || 0) - slidesBefore, 0); + const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1); + const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0); + + Utils.extend(swiper.virtual, { + from, + to, + offset, + slidesGrid: swiper.slidesGrid, + }); + + function onRendered() { + swiper.updateSlides(); + swiper.updateProgress(); + swiper.updateSlidesClasses(); + if (swiper.lazy && swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + } + + if (previousFrom === from && previousTo === to && !force) { + if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) { + swiper.slides.css(offsetProp, `${offset}px`); + } + swiper.updateProgress(); + return; + } + if (swiper.params.virtual.renderExternal) { + swiper.params.virtual.renderExternal.call(swiper, { + offset, + from, + to, + slides: (function getSlides() { + const slidesToRender = []; + for (let i = from; i <= to; i += 1) { + slidesToRender.push(slides[i]); + } + return slidesToRender; + }()), + }); + onRendered(); + return; + } + const prependIndexes = []; + const appendIndexes = []; + if (force) { + swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove(); + } else { + for (let i = previousFrom; i <= previousTo; i += 1) { + if (i < from || i > to) { + swiper.$wrapperEl.find(`.${swiper.params.slideClass}[data-swiper-slide-index="${i}"]`).remove(); + } + } + } + for (let i = 0; i < slides.length; i += 1) { + if (i >= from && i <= to) { + if (typeof previousTo === 'undefined' || force) { + appendIndexes.push(i); + } else { + if (i > previousTo) appendIndexes.push(i); + if (i < previousFrom) prependIndexes.push(i); + } + } + } + appendIndexes.forEach((index) => { + swiper.$wrapperEl.append(renderSlide(slides[index], index)); + }); + prependIndexes.sort((a, b) => b - a).forEach((index) => { + swiper.$wrapperEl.prepend(renderSlide(slides[index], index)); + }); + swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, `${offset}px`); + onRendered(); + }, + renderSlide(slide, index) { + const swiper = this; + const params = swiper.params.virtual; + if (params.cache && swiper.virtual.cache[index]) { + return swiper.virtual.cache[index]; + } + const $slideEl = params.renderSlide + ? $(params.renderSlide.call(swiper, slide, index)) + : $(`
            ${slide}
            `); + if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index); + if (params.cache) swiper.virtual.cache[index] = $slideEl; + return $slideEl; + }, + appendSlide(slides) { + const swiper = this; + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) swiper.virtual.slides.push(slides[i]); + } + } else { + swiper.virtual.slides.push(slides); + } + swiper.virtual.update(true); + }, + prependSlide(slides) { + const swiper = this; + const activeIndex = swiper.activeIndex; + let newActiveIndex = activeIndex + 1; + let numberOfNewSlides = 1; + + if (Array.isArray(slides)) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) swiper.virtual.slides.unshift(slides[i]); + } + newActiveIndex = activeIndex + slides.length; + numberOfNewSlides = slides.length; + } else { + swiper.virtual.slides.unshift(slides); + } + if (swiper.params.virtual.cache) { + const cache = swiper.virtual.cache; + const newCache = {}; + Object.keys(cache).forEach((cachedIndex) => { + newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cache[cachedIndex]; + }); + swiper.virtual.cache = newCache; + } + swiper.virtual.update(true); + swiper.slideTo(newActiveIndex, 0); + }, + removeSlide(slidesIndexes) { + const swiper = this; + if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return; + let activeIndex = swiper.activeIndex; + if (Array.isArray(slidesIndexes)) { + for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) { + swiper.virtual.slides.splice(slidesIndexes[i], 1); + if (swiper.params.virtual.cache) { + delete swiper.virtual.cache[slidesIndexes[i]]; + } + if (slidesIndexes[i] < activeIndex) activeIndex -= 1; + activeIndex = Math.max(activeIndex, 0); + } + } else { + swiper.virtual.slides.splice(slidesIndexes, 1); + if (swiper.params.virtual.cache) { + delete swiper.virtual.cache[slidesIndexes]; + } + if (slidesIndexes < activeIndex) activeIndex -= 1; + activeIndex = Math.max(activeIndex, 0); + } + swiper.virtual.update(true); + swiper.slideTo(activeIndex, 0); + }, + removeAllSlides() { + const swiper = this; + swiper.virtual.slides = []; + if (swiper.params.virtual.cache) { + swiper.virtual.cache = {}; + } + swiper.virtual.update(true); + swiper.slideTo(0, 0); + }, +}; + +var Virtual$1 = { + name: 'virtual', + params: { + virtual: { + enabled: false, + slides: [], + cache: true, + renderSlide: null, + renderExternal: null, + addSlidesBefore: 0, + addSlidesAfter: 0, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + virtual: { + update: Virtual.update.bind(swiper), + appendSlide: Virtual.appendSlide.bind(swiper), + prependSlide: Virtual.prependSlide.bind(swiper), + removeSlide: Virtual.removeSlide.bind(swiper), + removeAllSlides: Virtual.removeAllSlides.bind(swiper), + renderSlide: Virtual.renderSlide.bind(swiper), + slides: swiper.params.virtual.slides, + cache: {}, + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (!swiper.params.virtual.enabled) return; + swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`); + const overwriteParams = { + watchSlidesProgress: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + + if (!swiper.params.initialSlide) { + swiper.virtual.update(); + } + }, + setTranslate() { + const swiper = this; + if (!swiper.params.virtual.enabled) return; + swiper.virtual.update(); + }, + }, +}; + +const Keyboard = { + handle(event) { + const swiper = this; + const { rtlTranslate: rtl } = swiper; + let e = event; + if (e.originalEvent) e = e.originalEvent; // jquery fix + const kc = e.keyCode || e.charCode; + // Directions locks + if (!swiper.allowSlideNext && ((swiper.isHorizontal() && kc === 39) || (swiper.isVertical() && kc === 40))) { + return false; + } + if (!swiper.allowSlidePrev && ((swiper.isHorizontal() && kc === 37) || (swiper.isVertical() && kc === 38))) { + return false; + } + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { + return undefined; + } + if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) { + return undefined; + } + if (swiper.params.keyboard.onlyInViewport && (kc === 37 || kc === 39 || kc === 38 || kc === 40)) { + let inView = false; + // Check that swiper should be inside of visible area of window + if (swiper.$el.parents(`.${swiper.params.slideClass}`).length > 0 && swiper.$el.parents(`.${swiper.params.slideActiveClass}`).length === 0) { + return undefined; + } + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + const swiperOffset = swiper.$el.offset(); + if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft; + const swiperCoord = [ + [swiperOffset.left, swiperOffset.top], + [swiperOffset.left + swiper.width, swiperOffset.top], + [swiperOffset.left, swiperOffset.top + swiper.height], + [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height], + ]; + for (let i = 0; i < swiperCoord.length; i += 1) { + const point = swiperCoord[i]; + if ( + point[0] >= 0 && point[0] <= windowWidth + && point[1] >= 0 && point[1] <= windowHeight + ) { + inView = true; + } + } + if (!inView) return undefined; + } + if (swiper.isHorizontal()) { + if (kc === 37 || kc === 39) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + } + if ((kc === 39 && !rtl) || (kc === 37 && rtl)) swiper.slideNext(); + if ((kc === 37 && !rtl) || (kc === 39 && rtl)) swiper.slidePrev(); + } else { + if (kc === 38 || kc === 40) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + } + if (kc === 40) swiper.slideNext(); + if (kc === 38) swiper.slidePrev(); + } + swiper.emit('keyPress', kc); + return undefined; + }, + enable() { + const swiper = this; + if (swiper.keyboard.enabled) return; + $(document).on('keydown', swiper.keyboard.handle); + swiper.keyboard.enabled = true; + }, + disable() { + const swiper = this; + if (!swiper.keyboard.enabled) return; + $(document).off('keydown', swiper.keyboard.handle); + swiper.keyboard.enabled = false; + }, +}; + +var Keyboard$1 = { + name: 'keyboard', + params: { + keyboard: { + enabled: false, + onlyInViewport: true, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + keyboard: { + enabled: false, + enable: Keyboard.enable.bind(swiper), + disable: Keyboard.disable.bind(swiper), + handle: Keyboard.handle.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.keyboard.enabled) { + swiper.keyboard.enable(); + } + }, + destroy() { + const swiper = this; + if (swiper.keyboard.enabled) { + swiper.keyboard.disable(); + } + }, + }, +}; + +function isEventSupported() { + const eventName = 'onwheel'; + let isSupported = eventName in document; + + if (!isSupported) { + const element = document.createElement('div'); + element.setAttribute(eventName, 'return;'); + isSupported = typeof element[eventName] === 'function'; + } + + if (!isSupported + && document.implementation + && document.implementation.hasFeature + // always returns true in newer browsers as per the standard. + // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature + && document.implementation.hasFeature('', '') !== true + ) { + // This is the only way to test support for the `wheel` event in IE9+. + isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); + } + + return isSupported; +} +const Mousewheel = { + lastScrollTime: Utils.now(), + event: (function getEvent() { + if (window.navigator.userAgent.indexOf('firefox') > -1) return 'DOMMouseScroll'; + return isEventSupported() ? 'wheel' : 'mousewheel'; + }()), + normalize(e) { + // Reasonable defaults + const PIXEL_STEP = 10; + const LINE_HEIGHT = 40; + const PAGE_HEIGHT = 800; + + let sX = 0; + let sY = 0; // spinX, spinY + let pX = 0; + let pY = 0; // pixelX, pixelY + + // Legacy + if ('detail' in e) { + sY = e.detail; + } + if ('wheelDelta' in e) { + sY = -e.wheelDelta / 120; + } + if ('wheelDeltaY' in e) { + sY = -e.wheelDeltaY / 120; + } + if ('wheelDeltaX' in e) { + sX = -e.wheelDeltaX / 120; + } + + // side scrolling on FF with DOMMouseScroll + if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) { + sX = sY; + sY = 0; + } + + pX = sX * PIXEL_STEP; + pY = sY * PIXEL_STEP; + + if ('deltaY' in e) { + pY = e.deltaY; + } + if ('deltaX' in e) { + pX = e.deltaX; + } + + if ((pX || pY) && e.deltaMode) { + if (e.deltaMode === 1) { // delta in LINE units + pX *= LINE_HEIGHT; + pY *= LINE_HEIGHT; + } else { // delta in PAGE units + pX *= PAGE_HEIGHT; + pY *= PAGE_HEIGHT; + } + } + + // Fall-back if spin cannot be determined + if (pX && !sX) { + sX = (pX < 1) ? -1 : 1; + } + if (pY && !sY) { + sY = (pY < 1) ? -1 : 1; + } + + return { + spinX: sX, + spinY: sY, + pixelX: pX, + pixelY: pY, + }; + }, + handleMouseEnter() { + const swiper = this; + swiper.mouseEntered = true; + }, + handleMouseLeave() { + const swiper = this; + swiper.mouseEntered = false; + }, + handle(event) { + let e = event; + const swiper = this; + const params = swiper.params.mousewheel; + + if (!swiper.mouseEntered && !params.releaseOnEdges) return true; + + if (e.originalEvent) e = e.originalEvent; // jquery fix + let delta = 0; + const rtlFactor = swiper.rtlTranslate ? -1 : 1; + + const data = Mousewheel.normalize(e); + + if (params.forceToAxis) { + if (swiper.isHorizontal()) { + if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor; + else return true; + } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY; + else return true; + } else { + delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY; + } + + if (delta === 0) return true; + + if (params.invert) delta = -delta; + + if (!swiper.params.freeMode) { + if (Utils.now() - swiper.mousewheel.lastScrollTime > 60) { + if (delta < 0) { + if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) { + swiper.slideNext(); + swiper.emit('scroll', e); + } else if (params.releaseOnEdges) return true; + } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) { + swiper.slidePrev(); + swiper.emit('scroll', e); + } else if (params.releaseOnEdges) return true; + } + swiper.mousewheel.lastScrollTime = (new window.Date()).getTime(); + } else { + // Freemode or scrollContainer: + if (swiper.params.loop) { + swiper.loopFix(); + } + let position = swiper.getTranslate() + (delta * params.sensitivity); + const wasBeginning = swiper.isBeginning; + const wasEnd = swiper.isEnd; + + if (position >= swiper.minTranslate()) position = swiper.minTranslate(); + if (position <= swiper.maxTranslate()) position = swiper.maxTranslate(); + + swiper.setTransition(0); + swiper.setTranslate(position); + swiper.updateProgress(); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + + if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) { + swiper.updateSlidesClasses(); + } + + if (swiper.params.freeModeSticky) { + clearTimeout(swiper.mousewheel.timeout); + swiper.mousewheel.timeout = Utils.nextTick(() => { + swiper.slideToClosest(); + }, 300); + } + // Emit event + swiper.emit('scroll', e); + + // Stop autoplay + if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop(); + // Return page scroll on edge positions + if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true; + } + + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + return false; + }, + enable() { + const swiper = this; + if (!Mousewheel.event) return false; + if (swiper.mousewheel.enabled) return false; + let target = swiper.$el; + if (swiper.params.mousewheel.eventsTarged !== 'container') { + target = $(swiper.params.mousewheel.eventsTarged); + } + target.on('mouseenter', swiper.mousewheel.handleMouseEnter); + target.on('mouseleave', swiper.mousewheel.handleMouseLeave); + target.on(Mousewheel.event, swiper.mousewheel.handle); + swiper.mousewheel.enabled = true; + return true; + }, + disable() { + const swiper = this; + if (!Mousewheel.event) return false; + if (!swiper.mousewheel.enabled) return false; + let target = swiper.$el; + if (swiper.params.mousewheel.eventsTarged !== 'container') { + target = $(swiper.params.mousewheel.eventsTarged); + } + target.off(Mousewheel.event, swiper.mousewheel.handle); + swiper.mousewheel.enabled = false; + return true; + }, +}; + +var Mousewheel$1 = { + name: 'mousewheel', + params: { + mousewheel: { + enabled: false, + releaseOnEdges: false, + invert: false, + forceToAxis: false, + sensitivity: 1, + eventsTarged: 'container', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + mousewheel: { + enabled: false, + enable: Mousewheel.enable.bind(swiper), + disable: Mousewheel.disable.bind(swiper), + handle: Mousewheel.handle.bind(swiper), + handleMouseEnter: Mousewheel.handleMouseEnter.bind(swiper), + handleMouseLeave: Mousewheel.handleMouseLeave.bind(swiper), + lastScrollTime: Utils.now(), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.mousewheel.enabled) swiper.mousewheel.enable(); + }, + destroy() { + const swiper = this; + if (swiper.mousewheel.enabled) swiper.mousewheel.disable(); + }, + }, +}; + +const Navigation = { + update() { + // Update Navigation Buttons + const swiper = this; + const params = swiper.params.navigation; + + if (swiper.params.loop) return; + const { $nextEl, $prevEl } = swiper.navigation; + + if ($prevEl && $prevEl.length > 0) { + if (swiper.isBeginning) { + $prevEl.addClass(params.disabledClass); + } else { + $prevEl.removeClass(params.disabledClass); + } + $prevEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + } + if ($nextEl && $nextEl.length > 0) { + if (swiper.isEnd) { + $nextEl.addClass(params.disabledClass); + } else { + $nextEl.removeClass(params.disabledClass); + } + $nextEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + } + }, + onPrevClick(e) { + const swiper = this; + e.preventDefault(); + if (swiper.isBeginning && !swiper.params.loop) return; + swiper.slidePrev(); + }, + onNextClick(e) { + const swiper = this; + e.preventDefault(); + if (swiper.isEnd && !swiper.params.loop) return; + swiper.slideNext(); + }, + init() { + const swiper = this; + const params = swiper.params.navigation; + if (!(params.nextEl || params.prevEl)) return; + + let $nextEl; + let $prevEl; + if (params.nextEl) { + $nextEl = $(params.nextEl); + if ( + swiper.params.uniqueNavElements + && typeof params.nextEl === 'string' + && $nextEl.length > 1 + && swiper.$el.find(params.nextEl).length === 1 + ) { + $nextEl = swiper.$el.find(params.nextEl); + } + } + if (params.prevEl) { + $prevEl = $(params.prevEl); + if ( + swiper.params.uniqueNavElements + && typeof params.prevEl === 'string' + && $prevEl.length > 1 + && swiper.$el.find(params.prevEl).length === 1 + ) { + $prevEl = swiper.$el.find(params.prevEl); + } + } + + if ($nextEl && $nextEl.length > 0) { + $nextEl.on('click', swiper.navigation.onNextClick); + } + if ($prevEl && $prevEl.length > 0) { + $prevEl.on('click', swiper.navigation.onPrevClick); + } + + Utils.extend(swiper.navigation, { + $nextEl, + nextEl: $nextEl && $nextEl[0], + $prevEl, + prevEl: $prevEl && $prevEl[0], + }); + }, + destroy() { + const swiper = this; + const { $nextEl, $prevEl } = swiper.navigation; + if ($nextEl && $nextEl.length) { + $nextEl.off('click', swiper.navigation.onNextClick); + $nextEl.removeClass(swiper.params.navigation.disabledClass); + } + if ($prevEl && $prevEl.length) { + $prevEl.off('click', swiper.navigation.onPrevClick); + $prevEl.removeClass(swiper.params.navigation.disabledClass); + } + }, +}; + +var Navigation$1 = { + name: 'navigation', + params: { + navigation: { + nextEl: null, + prevEl: null, + + hideOnClick: false, + disabledClass: 'swiper-button-disabled', + hiddenClass: 'swiper-button-hidden', + lockClass: 'swiper-button-lock', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + navigation: { + init: Navigation.init.bind(swiper), + update: Navigation.update.bind(swiper), + destroy: Navigation.destroy.bind(swiper), + onNextClick: Navigation.onNextClick.bind(swiper), + onPrevClick: Navigation.onPrevClick.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.navigation.init(); + swiper.navigation.update(); + }, + toEdge() { + const swiper = this; + swiper.navigation.update(); + }, + fromEdge() { + const swiper = this; + swiper.navigation.update(); + }, + destroy() { + const swiper = this; + swiper.navigation.destroy(); + }, + click(e) { + const swiper = this; + const { $nextEl, $prevEl } = swiper.navigation; + if ( + swiper.params.navigation.hideOnClick + && !$(e.target).is($prevEl) + && !$(e.target).is($nextEl) + ) { + let isHidden; + if ($nextEl) { + isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass); + } else if ($prevEl) { + isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass); + } + if (isHidden === true) { + swiper.emit('navigationShow', swiper); + } else { + swiper.emit('navigationHide', swiper); + } + if ($nextEl) { + $nextEl.toggleClass(swiper.params.navigation.hiddenClass); + } + if ($prevEl) { + $prevEl.toggleClass(swiper.params.navigation.hiddenClass); + } + } + }, + }, +}; + +const Pagination = { + update() { + // Render || Update Pagination bullets/items + const swiper = this; + const rtl = swiper.rtl; + const params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return; + const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; + const $el = swiper.pagination.$el; + // Current/Total + let current; + const total = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; + if (swiper.params.loop) { + current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup); + if (current > slidesLength - 1 - (swiper.loopedSlides * 2)) { + current -= (slidesLength - (swiper.loopedSlides * 2)); + } + if (current > total - 1) current -= total; + if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current; + } else if (typeof swiper.snapIndex !== 'undefined') { + current = swiper.snapIndex; + } else { + current = swiper.activeIndex || 0; + } + // Types + if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) { + const bullets = swiper.pagination.bullets; + let firstIndex; + let lastIndex; + let midIndex; + if (params.dynamicBullets) { + swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true); + $el.css(swiper.isHorizontal() ? 'width' : 'height', `${swiper.pagination.bulletSize * (params.dynamicMainBullets + 4)}px`); + if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) { + swiper.pagination.dynamicBulletIndex += (current - swiper.previousIndex); + if (swiper.pagination.dynamicBulletIndex > (params.dynamicMainBullets - 1)) { + swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1; + } else if (swiper.pagination.dynamicBulletIndex < 0) { + swiper.pagination.dynamicBulletIndex = 0; + } + } + firstIndex = current - swiper.pagination.dynamicBulletIndex; + lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1); + midIndex = (lastIndex + firstIndex) / 2; + } + bullets.removeClass(`${params.bulletActiveClass} ${params.bulletActiveClass}-next ${params.bulletActiveClass}-next-next ${params.bulletActiveClass}-prev ${params.bulletActiveClass}-prev-prev ${params.bulletActiveClass}-main`); + if ($el.length > 1) { + bullets.each((index, bullet) => { + const $bullet = $(bullet); + const bulletIndex = $bullet.index(); + if (bulletIndex === current) { + $bullet.addClass(params.bulletActiveClass); + } + if (params.dynamicBullets) { + if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) { + $bullet.addClass(`${params.bulletActiveClass}-main`); + } + if (bulletIndex === firstIndex) { + $bullet + .prev() + .addClass(`${params.bulletActiveClass}-prev`) + .prev() + .addClass(`${params.bulletActiveClass}-prev-prev`); + } + if (bulletIndex === lastIndex) { + $bullet + .next() + .addClass(`${params.bulletActiveClass}-next`) + .next() + .addClass(`${params.bulletActiveClass}-next-next`); + } + } + }); + } else { + const $bullet = bullets.eq(current); + $bullet.addClass(params.bulletActiveClass); + if (params.dynamicBullets) { + const $firstDisplayedBullet = bullets.eq(firstIndex); + const $lastDisplayedBullet = bullets.eq(lastIndex); + for (let i = firstIndex; i <= lastIndex; i += 1) { + bullets.eq(i).addClass(`${params.bulletActiveClass}-main`); + } + $firstDisplayedBullet + .prev() + .addClass(`${params.bulletActiveClass}-prev`) + .prev() + .addClass(`${params.bulletActiveClass}-prev-prev`); + $lastDisplayedBullet + .next() + .addClass(`${params.bulletActiveClass}-next`) + .next() + .addClass(`${params.bulletActiveClass}-next-next`); + } + } + if (params.dynamicBullets) { + const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4); + const bulletsOffset = (((swiper.pagination.bulletSize * dynamicBulletsLength) - (swiper.pagination.bulletSize)) / 2) - (midIndex * swiper.pagination.bulletSize); + const offsetProp = rtl ? 'right' : 'left'; + bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`); + } + } + if (params.type === 'fraction') { + $el.find(`.${params.currentClass}`).text(params.formatFractionCurrent(current + 1)); + $el.find(`.${params.totalClass}`).text(params.formatFractionTotal(total)); + } + if (params.type === 'progressbar') { + let progressbarDirection; + if (params.progressbarOpposite) { + progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal'; + } else { + progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical'; + } + const scale = (current + 1) / total; + let scaleX = 1; + let scaleY = 1; + if (progressbarDirection === 'horizontal') { + scaleX = scale; + } else { + scaleY = scale; + } + $el.find(`.${params.progressbarFillClass}`).transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`).transition(swiper.params.speed); + } + if (params.type === 'custom' && params.renderCustom) { + $el.html(params.renderCustom(swiper, current + 1, total)); + swiper.emit('paginationRender', swiper, $el[0]); + } else { + swiper.emit('paginationUpdate', swiper, $el[0]); + } + $el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + }, + render() { + // Render Container + const swiper = this; + const params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return; + const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; + + const $el = swiper.pagination.$el; + let paginationHTML = ''; + if (params.type === 'bullets') { + const numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; + for (let i = 0; i < numberOfBullets; i += 1) { + if (params.renderBullet) { + paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass); + } else { + paginationHTML += `<${params.bulletElement} class="${params.bulletClass}">`; + } + } + $el.html(paginationHTML); + swiper.pagination.bullets = $el.find(`.${params.bulletClass}`); + } + if (params.type === 'fraction') { + if (params.renderFraction) { + paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass); + } else { + paginationHTML = `` + + ' / ' + + ``; + } + $el.html(paginationHTML); + } + if (params.type === 'progressbar') { + if (params.renderProgressbar) { + paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass); + } else { + paginationHTML = ``; + } + $el.html(paginationHTML); + } + if (params.type !== 'custom') { + swiper.emit('paginationRender', swiper.pagination.$el[0]); + } + }, + init() { + const swiper = this; + const params = swiper.params.pagination; + if (!params.el) return; + + let $el = $(params.el); + if ($el.length === 0) return; + + if ( + swiper.params.uniqueNavElements + && typeof params.el === 'string' + && $el.length > 1 + && swiper.$el.find(params.el).length === 1 + ) { + $el = swiper.$el.find(params.el); + } + + if (params.type === 'bullets' && params.clickable) { + $el.addClass(params.clickableClass); + } + + $el.addClass(params.modifierClass + params.type); + + if (params.type === 'bullets' && params.dynamicBullets) { + $el.addClass(`${params.modifierClass}${params.type}-dynamic`); + swiper.pagination.dynamicBulletIndex = 0; + if (params.dynamicMainBullets < 1) { + params.dynamicMainBullets = 1; + } + } + if (params.type === 'progressbar' && params.progressbarOpposite) { + $el.addClass(params.progressbarOppositeClass); + } + + if (params.clickable) { + $el.on('click', `.${params.bulletClass}`, function onClick(e) { + e.preventDefault(); + let index = $(this).index() * swiper.params.slidesPerGroup; + if (swiper.params.loop) index += swiper.loopedSlides; + swiper.slideTo(index); + }); + } + + Utils.extend(swiper.pagination, { + $el, + el: $el[0], + }); + }, + destroy() { + const swiper = this; + const params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return; + const $el = swiper.pagination.$el; + + $el.removeClass(params.hiddenClass); + $el.removeClass(params.modifierClass + params.type); + if (swiper.pagination.bullets) swiper.pagination.bullets.removeClass(params.bulletActiveClass); + if (params.clickable) { + $el.off('click', `.${params.bulletClass}`); + } + }, +}; + +var Pagination$1 = { + name: 'pagination', + params: { + pagination: { + el: null, + bulletElement: 'span', + clickable: false, + hideOnClick: false, + renderBullet: null, + renderProgressbar: null, + renderFraction: null, + renderCustom: null, + progressbarOpposite: false, + type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom' + dynamicBullets: false, + dynamicMainBullets: 1, + formatFractionCurrent: number => number, + formatFractionTotal: number => number, + bulletClass: 'swiper-pagination-bullet', + bulletActiveClass: 'swiper-pagination-bullet-active', + modifierClass: 'swiper-pagination-', // NEW + currentClass: 'swiper-pagination-current', + totalClass: 'swiper-pagination-total', + hiddenClass: 'swiper-pagination-hidden', + progressbarFillClass: 'swiper-pagination-progressbar-fill', + progressbarOppositeClass: 'swiper-pagination-progressbar-opposite', + clickableClass: 'swiper-pagination-clickable', // NEW + lockClass: 'swiper-pagination-lock', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + pagination: { + init: Pagination.init.bind(swiper), + render: Pagination.render.bind(swiper), + update: Pagination.update.bind(swiper), + destroy: Pagination.destroy.bind(swiper), + dynamicBulletIndex: 0, + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.pagination.init(); + swiper.pagination.render(); + swiper.pagination.update(); + }, + activeIndexChange() { + const swiper = this; + if (swiper.params.loop) { + swiper.pagination.update(); + } else if (typeof swiper.snapIndex === 'undefined') { + swiper.pagination.update(); + } + }, + snapIndexChange() { + const swiper = this; + if (!swiper.params.loop) { + swiper.pagination.update(); + } + }, + slidesLengthChange() { + const swiper = this; + if (swiper.params.loop) { + swiper.pagination.render(); + swiper.pagination.update(); + } + }, + snapGridLengthChange() { + const swiper = this; + if (!swiper.params.loop) { + swiper.pagination.render(); + swiper.pagination.update(); + } + }, + destroy() { + const swiper = this; + swiper.pagination.destroy(); + }, + click(e) { + const swiper = this; + if ( + swiper.params.pagination.el + && swiper.params.pagination.hideOnClick + && swiper.pagination.$el.length > 0 + && !$(e.target).hasClass(swiper.params.pagination.bulletClass) + ) { + const isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass); + if (isHidden === true) { + swiper.emit('paginationShow', swiper); + } else { + swiper.emit('paginationHide', swiper); + } + swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass); + } + }, + }, +}; + +const Scrollbar = { + setTranslate() { + const swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; + const { scrollbar, rtlTranslate: rtl, progress } = swiper; + const { + dragSize, trackSize, $dragEl, $el, + } = scrollbar; + const params = swiper.params.scrollbar; + + let newSize = dragSize; + let newPos = (trackSize - dragSize) * progress; + if (rtl) { + newPos = -newPos; + if (newPos > 0) { + newSize = dragSize - newPos; + newPos = 0; + } else if (-newPos + dragSize > trackSize) { + newSize = trackSize + newPos; + } + } else if (newPos < 0) { + newSize = dragSize + newPos; + newPos = 0; + } else if (newPos + dragSize > trackSize) { + newSize = trackSize - newPos; + } + if (swiper.isHorizontal()) { + if (Support.transforms3d) { + $dragEl.transform(`translate3d(${newPos}px, 0, 0)`); + } else { + $dragEl.transform(`translateX(${newPos}px)`); + } + $dragEl[0].style.width = `${newSize}px`; + } else { + if (Support.transforms3d) { + $dragEl.transform(`translate3d(0px, ${newPos}px, 0)`); + } else { + $dragEl.transform(`translateY(${newPos}px)`); + } + $dragEl[0].style.height = `${newSize}px`; + } + if (params.hide) { + clearTimeout(swiper.scrollbar.timeout); + $el[0].style.opacity = 1; + swiper.scrollbar.timeout = setTimeout(() => { + $el[0].style.opacity = 0; + $el.transition(400); + }, 1000); + } + }, + setTransition(duration) { + const swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; + swiper.scrollbar.$dragEl.transition(duration); + }, + updateSize() { + const swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; + + const { scrollbar } = swiper; + const { $dragEl, $el } = scrollbar; + + $dragEl[0].style.width = ''; + $dragEl[0].style.height = ''; + const trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight; + + const divider = swiper.size / swiper.virtualSize; + const moveDivider = divider * (trackSize / swiper.size); + let dragSize; + if (swiper.params.scrollbar.dragSize === 'auto') { + dragSize = trackSize * divider; + } else { + dragSize = parseInt(swiper.params.scrollbar.dragSize, 10); + } + + if (swiper.isHorizontal()) { + $dragEl[0].style.width = `${dragSize}px`; + } else { + $dragEl[0].style.height = `${dragSize}px`; + } + + if (divider >= 1) { + $el[0].style.display = 'none'; + } else { + $el[0].style.display = ''; + } + if (swiper.params.scrollbar.hide) { + $el[0].style.opacity = 0; + } + Utils.extend(scrollbar, { + trackSize, + divider, + moveDivider, + dragSize, + }); + scrollbar.$el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass); + }, + setDragPosition(e) { + const swiper = this; + const { scrollbar, rtlTranslate: rtl } = swiper; + const { $el, dragSize, trackSize } = scrollbar; + + let pointerPosition; + if (swiper.isHorizontal()) { + pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX); + } else { + pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY); + } + let positionRatio; + positionRatio = ((pointerPosition) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragSize / 2)) / (trackSize - dragSize); + positionRatio = Math.max(Math.min(positionRatio, 1), 0); + if (rtl) { + positionRatio = 1 - positionRatio; + } + + const position = swiper.minTranslate() + ((swiper.maxTranslate() - swiper.minTranslate()) * positionRatio); + + swiper.updateProgress(position); + swiper.setTranslate(position); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + }, + onDragStart(e) { + const swiper = this; + const params = swiper.params.scrollbar; + const { scrollbar, $wrapperEl } = swiper; + const { $el, $dragEl } = scrollbar; + swiper.scrollbar.isTouched = true; + e.preventDefault(); + e.stopPropagation(); + + $wrapperEl.transition(100); + $dragEl.transition(100); + scrollbar.setDragPosition(e); + + clearTimeout(swiper.scrollbar.dragTimeout); + + $el.transition(0); + if (params.hide) { + $el.css('opacity', 1); + } + swiper.emit('scrollbarDragStart', e); + }, + onDragMove(e) { + const swiper = this; + const { scrollbar, $wrapperEl } = swiper; + const { $el, $dragEl } = scrollbar; + + if (!swiper.scrollbar.isTouched) return; + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + scrollbar.setDragPosition(e); + $wrapperEl.transition(0); + $el.transition(0); + $dragEl.transition(0); + swiper.emit('scrollbarDragMove', e); + }, + onDragEnd(e) { + const swiper = this; + + const params = swiper.params.scrollbar; + const { scrollbar } = swiper; + const { $el } = scrollbar; + + if (!swiper.scrollbar.isTouched) return; + swiper.scrollbar.isTouched = false; + if (params.hide) { + clearTimeout(swiper.scrollbar.dragTimeout); + swiper.scrollbar.dragTimeout = Utils.nextTick(() => { + $el.css('opacity', 0); + $el.transition(400); + }, 1000); + } + swiper.emit('scrollbarDragEnd', e); + if (params.snapOnRelease) { + swiper.slideToClosest(); + } + }, + enableDraggable() { + const swiper = this; + if (!swiper.params.scrollbar.el) return; + const { + scrollbar, touchEventsTouch, touchEventsDesktop, params, + } = swiper; + const $el = scrollbar.$el; + const target = $el[0]; + const activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false; + const passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + if (!Support.touch) { + target.addEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener); + document.addEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener); + document.addEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener); + } else { + target.addEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener); + target.addEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener); + target.addEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener); + } + }, + disableDraggable() { + const swiper = this; + if (!swiper.params.scrollbar.el) return; + const { + scrollbar, touchEventsTouch, touchEventsDesktop, params, + } = swiper; + const $el = scrollbar.$el; + const target = $el[0]; + const activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false; + const passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + if (!Support.touch) { + target.removeEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener); + document.removeEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener); + document.removeEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener); + } else { + target.removeEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener); + target.removeEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener); + target.removeEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener); + } + }, + init() { + const swiper = this; + if (!swiper.params.scrollbar.el) return; + const { scrollbar, $el: $swiperEl } = swiper; + const params = swiper.params.scrollbar; + + let $el = $(params.el); + if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) { + $el = $swiperEl.find(params.el); + } + + let $dragEl = $el.find(`.${swiper.params.scrollbar.dragClass}`); + if ($dragEl.length === 0) { + $dragEl = $(`
            `); + $el.append($dragEl); + } + + Utils.extend(scrollbar, { + $el, + el: $el[0], + $dragEl, + dragEl: $dragEl[0], + }); + + if (params.draggable) { + scrollbar.enableDraggable(); + } + }, + destroy() { + const swiper = this; + swiper.scrollbar.disableDraggable(); + }, +}; + +var Scrollbar$1 = { + name: 'scrollbar', + params: { + scrollbar: { + el: null, + dragSize: 'auto', + hide: false, + draggable: false, + snapOnRelease: true, + lockClass: 'swiper-scrollbar-lock', + dragClass: 'swiper-scrollbar-drag', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + scrollbar: { + init: Scrollbar.init.bind(swiper), + destroy: Scrollbar.destroy.bind(swiper), + updateSize: Scrollbar.updateSize.bind(swiper), + setTranslate: Scrollbar.setTranslate.bind(swiper), + setTransition: Scrollbar.setTransition.bind(swiper), + enableDraggable: Scrollbar.enableDraggable.bind(swiper), + disableDraggable: Scrollbar.disableDraggable.bind(swiper), + setDragPosition: Scrollbar.setDragPosition.bind(swiper), + onDragStart: Scrollbar.onDragStart.bind(swiper), + onDragMove: Scrollbar.onDragMove.bind(swiper), + onDragEnd: Scrollbar.onDragEnd.bind(swiper), + isTouched: false, + timeout: null, + dragTimeout: null, + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.scrollbar.init(); + swiper.scrollbar.updateSize(); + swiper.scrollbar.setTranslate(); + }, + update() { + const swiper = this; + swiper.scrollbar.updateSize(); + }, + resize() { + const swiper = this; + swiper.scrollbar.updateSize(); + }, + observerUpdate() { + const swiper = this; + swiper.scrollbar.updateSize(); + }, + setTranslate() { + const swiper = this; + swiper.scrollbar.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + swiper.scrollbar.setTransition(duration); + }, + destroy() { + const swiper = this; + swiper.scrollbar.destroy(); + }, + }, +}; + +const Parallax = { + setTransform(el, progress) { + const swiper = this; + const { rtl } = swiper; + + const $el = $(el); + const rtlFactor = rtl ? -1 : 1; + + const p = $el.attr('data-swiper-parallax') || '0'; + let x = $el.attr('data-swiper-parallax-x'); + let y = $el.attr('data-swiper-parallax-y'); + const scale = $el.attr('data-swiper-parallax-scale'); + const opacity = $el.attr('data-swiper-parallax-opacity'); + + if (x || y) { + x = x || '0'; + y = y || '0'; + } else if (swiper.isHorizontal()) { + x = p; + y = '0'; + } else { + y = p; + x = '0'; + } + + if ((x).indexOf('%') >= 0) { + x = `${parseInt(x, 10) * progress * rtlFactor}%`; + } else { + x = `${x * progress * rtlFactor}px`; + } + if ((y).indexOf('%') >= 0) { + y = `${parseInt(y, 10) * progress}%`; + } else { + y = `${y * progress}px`; + } + + if (typeof opacity !== 'undefined' && opacity !== null) { + const currentOpacity = opacity - ((opacity - 1) * (1 - Math.abs(progress))); + $el[0].style.opacity = currentOpacity; + } + if (typeof scale === 'undefined' || scale === null) { + $el.transform(`translate3d(${x}, ${y}, 0px)`); + } else { + const currentScale = scale - ((scale - 1) * (1 - Math.abs(progress))); + $el.transform(`translate3d(${x}, ${y}, 0px) scale(${currentScale})`); + } + }, + setTranslate() { + const swiper = this; + const { + $el, slides, progress, snapGrid, + } = swiper; + $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each((index, el) => { + swiper.parallax.setTransform(el, progress); + }); + slides.each((slideIndex, slideEl) => { + let slideProgress = slideEl.progress; + if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') { + slideProgress += Math.ceil(slideIndex / 2) - (progress * (snapGrid.length - 1)); + } + slideProgress = Math.min(Math.max(slideProgress, -1), 1); + $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each((index, el) => { + swiper.parallax.setTransform(el, slideProgress); + }); + }); + }, + setTransition(duration = this.params.speed) { + const swiper = this; + const { $el } = swiper; + $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each((index, parallaxEl) => { + const $parallaxEl = $(parallaxEl); + let parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration; + if (duration === 0) parallaxDuration = 0; + $parallaxEl.transition(parallaxDuration); + }); + }, +}; + +var Parallax$1 = { + name: 'parallax', + params: { + parallax: { + enabled: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + parallax: { + setTransform: Parallax.setTransform.bind(swiper), + setTranslate: Parallax.setTranslate.bind(swiper), + setTransition: Parallax.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.params.watchSlidesProgress = true; + swiper.originalParams.watchSlidesProgress = true; + }, + init() { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.parallax.setTranslate(); + }, + setTranslate() { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.parallax.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.parallax.setTransition(duration); + }, + }, +}; + +const Zoom = { + // Calc Scale From Multi-touches + getDistanceBetweenTouches(e) { + if (e.targetTouches.length < 2) return 1; + const x1 = e.targetTouches[0].pageX; + const y1 = e.targetTouches[0].pageY; + const x2 = e.targetTouches[1].pageX; + const y2 = e.targetTouches[1].pageY; + const distance = Math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2)); + return distance; + }, + // Events + onGestureStart(e) { + const swiper = this; + const params = swiper.params.zoom; + const zoom = swiper.zoom; + const { gesture } = zoom; + zoom.fakeGestureTouched = false; + zoom.fakeGestureMoved = false; + if (!Support.gestures) { + if (e.type !== 'touchstart' || (e.type === 'touchstart' && e.targetTouches.length < 2)) { + return; + } + zoom.fakeGestureTouched = true; + gesture.scaleStart = Zoom.getDistanceBetweenTouches(e); + } + if (!gesture.$slideEl || !gesture.$slideEl.length) { + gesture.$slideEl = $(e.target).closest('.swiper-slide'); + if (gesture.$slideEl.length === 0) gesture.$slideEl = swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); + gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + if (gesture.$imageWrapEl.length === 0) { + gesture.$imageEl = undefined; + return; + } + } + gesture.$imageEl.transition(0); + swiper.zoom.isScaling = true; + }, + onGestureChange(e) { + const swiper = this; + const params = swiper.params.zoom; + const zoom = swiper.zoom; + const { gesture } = zoom; + if (!Support.gestures) { + if (e.type !== 'touchmove' || (e.type === 'touchmove' && e.targetTouches.length < 2)) { + return; + } + zoom.fakeGestureMoved = true; + gesture.scaleMove = Zoom.getDistanceBetweenTouches(e); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + if (Support.gestures) { + zoom.scale = e.scale * zoom.currentScale; + } else { + zoom.scale = (gesture.scaleMove / gesture.scaleStart) * zoom.currentScale; + } + if (zoom.scale > gesture.maxRatio) { + zoom.scale = (gesture.maxRatio - 1) + (((zoom.scale - gesture.maxRatio) + 1) ** 0.5); + } + if (zoom.scale < params.minRatio) { + zoom.scale = (params.minRatio + 1) - (((params.minRatio - zoom.scale) + 1) ** 0.5); + } + gesture.$imageEl.transform(`translate3d(0,0,0) scale(${zoom.scale})`); + }, + onGestureEnd(e) { + const swiper = this; + const params = swiper.params.zoom; + const zoom = swiper.zoom; + const { gesture } = zoom; + if (!Support.gestures) { + if (!zoom.fakeGestureTouched || !zoom.fakeGestureMoved) { + return; + } + if (e.type !== 'touchend' || (e.type === 'touchend' && e.changedTouches.length < 2 && !Device.android)) { + return; + } + zoom.fakeGestureTouched = false; + zoom.fakeGestureMoved = false; + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio); + gesture.$imageEl.transition(swiper.params.speed).transform(`translate3d(0,0,0) scale(${zoom.scale})`); + zoom.currentScale = zoom.scale; + zoom.isScaling = false; + if (zoom.scale === 1) gesture.$slideEl = undefined; + }, + onTouchStart(e) { + const swiper = this; + const zoom = swiper.zoom; + const { gesture, image } = zoom; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + if (image.isTouched) return; + if (Device.android) e.preventDefault(); + image.isTouched = true; + image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; + image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; + }, + onTouchMove(e) { + const swiper = this; + const zoom = swiper.zoom; + const { gesture, image, velocity } = zoom; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + swiper.allowClick = false; + if (!image.isTouched || !gesture.$slideEl) return; + + if (!image.isMoved) { + image.width = gesture.$imageEl[0].offsetWidth; + image.height = gesture.$imageEl[0].offsetHeight; + image.startX = Utils.getTranslate(gesture.$imageWrapEl[0], 'x') || 0; + image.startY = Utils.getTranslate(gesture.$imageWrapEl[0], 'y') || 0; + gesture.slideWidth = gesture.$slideEl[0].offsetWidth; + gesture.slideHeight = gesture.$slideEl[0].offsetHeight; + gesture.$imageWrapEl.transition(0); + if (swiper.rtl) { + image.startX = -image.startX; + image.startY = -image.startY; + } + } + // Define if we need image drag + const scaledWidth = image.width * zoom.scale; + const scaledHeight = image.height * zoom.scale; + + if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return; + + image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0); + image.maxX = -image.minX; + image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0); + image.maxY = -image.minY; + + image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; + image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; + + if (!image.isMoved && !zoom.isScaling) { + if ( + swiper.isHorizontal() + && ( + (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x) + || (Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x) + ) + ) { + image.isTouched = false; + return; + } if ( + !swiper.isHorizontal() + && ( + (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y) + || (Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y) + ) + ) { + image.isTouched = false; + return; + } + } + e.preventDefault(); + e.stopPropagation(); + + image.isMoved = true; + image.currentX = (image.touchesCurrent.x - image.touchesStart.x) + image.startX; + image.currentY = (image.touchesCurrent.y - image.touchesStart.y) + image.startY; + + if (image.currentX < image.minX) { + image.currentX = (image.minX + 1) - (((image.minX - image.currentX) + 1) ** 0.8); + } + if (image.currentX > image.maxX) { + image.currentX = (image.maxX - 1) + (((image.currentX - image.maxX) + 1) ** 0.8); + } + + if (image.currentY < image.minY) { + image.currentY = (image.minY + 1) - (((image.minY - image.currentY) + 1) ** 0.8); + } + if (image.currentY > image.maxY) { + image.currentY = (image.maxY - 1) + (((image.currentY - image.maxY) + 1) ** 0.8); + } + + // Velocity + if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x; + if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y; + if (!velocity.prevTime) velocity.prevTime = Date.now(); + velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2; + velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2; + if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0; + if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0; + velocity.prevPositionX = image.touchesCurrent.x; + velocity.prevPositionY = image.touchesCurrent.y; + velocity.prevTime = Date.now(); + + gesture.$imageWrapEl.transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`); + }, + onTouchEnd() { + const swiper = this; + const zoom = swiper.zoom; + const { gesture, image, velocity } = zoom; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + if (!image.isTouched || !image.isMoved) { + image.isTouched = false; + image.isMoved = false; + return; + } + image.isTouched = false; + image.isMoved = false; + let momentumDurationX = 300; + let momentumDurationY = 300; + const momentumDistanceX = velocity.x * momentumDurationX; + const newPositionX = image.currentX + momentumDistanceX; + const momentumDistanceY = velocity.y * momentumDurationY; + const newPositionY = image.currentY + momentumDistanceY; + + // Fix duration + if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x); + if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y); + const momentumDuration = Math.max(momentumDurationX, momentumDurationY); + + image.currentX = newPositionX; + image.currentY = newPositionY; + + // Define if we need image drag + const scaledWidth = image.width * zoom.scale; + const scaledHeight = image.height * zoom.scale; + image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0); + image.maxX = -image.minX; + image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0); + image.maxY = -image.minY; + image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX); + image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY); + + gesture.$imageWrapEl.transition(momentumDuration).transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`); + }, + onTransitionEnd() { + const swiper = this; + const zoom = swiper.zoom; + const { gesture } = zoom; + if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) { + gesture.$imageEl.transform('translate3d(0,0,0) scale(1)'); + gesture.$imageWrapEl.transform('translate3d(0,0,0)'); + + zoom.scale = 1; + zoom.currentScale = 1; + + gesture.$slideEl = undefined; + gesture.$imageEl = undefined; + gesture.$imageWrapEl = undefined; + } + }, + // Toggle Zoom + toggle(e) { + const swiper = this; + const zoom = swiper.zoom; + + if (zoom.scale && zoom.scale !== 1) { + // Zoom Out + zoom.out(); + } else { + // Zoom In + zoom.in(e); + } + }, + in(e) { + const swiper = this; + + const zoom = swiper.zoom; + const params = swiper.params.zoom; + const { gesture, image } = zoom; + + if (!gesture.$slideEl) { + gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + + gesture.$slideEl.addClass(`${params.zoomedSlideClass}`); + + let touchX; + let touchY; + let offsetX; + let offsetY; + let diffX; + let diffY; + let translateX; + let translateY; + let imageWidth; + let imageHeight; + let scaledWidth; + let scaledHeight; + let translateMinX; + let translateMinY; + let translateMaxX; + let translateMaxY; + let slideWidth; + let slideHeight; + + if (typeof image.touchesStart.x === 'undefined' && e) { + touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX; + touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY; + } else { + touchX = image.touchesStart.x; + touchY = image.touchesStart.y; + } + + zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + zoom.currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + if (e) { + slideWidth = gesture.$slideEl[0].offsetWidth; + slideHeight = gesture.$slideEl[0].offsetHeight; + offsetX = gesture.$slideEl.offset().left; + offsetY = gesture.$slideEl.offset().top; + diffX = (offsetX + (slideWidth / 2)) - touchX; + diffY = (offsetY + (slideHeight / 2)) - touchY; + + imageWidth = gesture.$imageEl[0].offsetWidth; + imageHeight = gesture.$imageEl[0].offsetHeight; + scaledWidth = imageWidth * zoom.scale; + scaledHeight = imageHeight * zoom.scale; + + translateMinX = Math.min(((slideWidth / 2) - (scaledWidth / 2)), 0); + translateMinY = Math.min(((slideHeight / 2) - (scaledHeight / 2)), 0); + translateMaxX = -translateMinX; + translateMaxY = -translateMinY; + + translateX = diffX * zoom.scale; + translateY = diffY * zoom.scale; + + if (translateX < translateMinX) { + translateX = translateMinX; + } + if (translateX > translateMaxX) { + translateX = translateMaxX; + } + + if (translateY < translateMinY) { + translateY = translateMinY; + } + if (translateY > translateMaxY) { + translateY = translateMaxY; + } + } else { + translateX = 0; + translateY = 0; + } + gesture.$imageWrapEl.transition(300).transform(`translate3d(${translateX}px, ${translateY}px,0)`); + gesture.$imageEl.transition(300).transform(`translate3d(0,0,0) scale(${zoom.scale})`); + }, + out() { + const swiper = this; + + const zoom = swiper.zoom; + const params = swiper.params.zoom; + const { gesture } = zoom; + + if (!gesture.$slideEl) { + gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + + zoom.scale = 1; + zoom.currentScale = 1; + gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)'); + gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)'); + gesture.$slideEl.removeClass(`${params.zoomedSlideClass}`); + gesture.$slideEl = undefined; + }, + // Attach/Detach Events + enable() { + const swiper = this; + const zoom = swiper.zoom; + if (zoom.enabled) return; + zoom.enabled = true; + + const passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false; + + // Scale image + if (Support.gestures) { + swiper.$wrapperEl.on('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.on('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.on('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener); + } else if (swiper.touchEvents.start === 'touchstart') { + swiper.$wrapperEl.on(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.on(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.on(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener); + } + + // Move image + swiper.$wrapperEl.on(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, zoom.onTouchMove); + }, + disable() { + const swiper = this; + const zoom = swiper.zoom; + if (!zoom.enabled) return; + + swiper.zoom.enabled = false; + + const passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false; + + // Scale image + if (Support.gestures) { + swiper.$wrapperEl.off('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.off('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.off('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener); + } else if (swiper.touchEvents.start === 'touchstart') { + swiper.$wrapperEl.off(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.off(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.off(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener); + } + + // Move image + swiper.$wrapperEl.off(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, zoom.onTouchMove); + }, +}; + +var Zoom$1 = { + name: 'zoom', + params: { + zoom: { + enabled: false, + maxRatio: 3, + minRatio: 1, + toggle: true, + containerClass: 'swiper-zoom-container', + zoomedSlideClass: 'swiper-slide-zoomed', + }, + }, + create() { + const swiper = this; + const zoom = { + enabled: false, + scale: 1, + currentScale: 1, + isScaling: false, + gesture: { + $slideEl: undefined, + slideWidth: undefined, + slideHeight: undefined, + $imageEl: undefined, + $imageWrapEl: undefined, + maxRatio: 3, + }, + image: { + isTouched: undefined, + isMoved: undefined, + currentX: undefined, + currentY: undefined, + minX: undefined, + minY: undefined, + maxX: undefined, + maxY: undefined, + width: undefined, + height: undefined, + startX: undefined, + startY: undefined, + touchesStart: {}, + touchesCurrent: {}, + }, + velocity: { + x: undefined, + y: undefined, + prevPositionX: undefined, + prevPositionY: undefined, + prevTime: undefined, + }, + }; + + ('onGestureStart onGestureChange onGestureEnd onTouchStart onTouchMove onTouchEnd onTransitionEnd toggle enable disable in out').split(' ').forEach((methodName) => { + zoom[methodName] = Zoom[methodName].bind(swiper); + }); + Utils.extend(swiper, { + zoom, + }); + + let scale = 1; + Object.defineProperty(swiper.zoom, 'scale', { + get() { + return scale; + }, + set(value) { + if (scale !== value) { + const imageEl = swiper.zoom.gesture.$imageEl ? swiper.zoom.gesture.$imageEl[0] : undefined; + const slideEl = swiper.zoom.gesture.$slideEl ? swiper.zoom.gesture.$slideEl[0] : undefined; + swiper.emit('zoomChange', value, imageEl, slideEl); + } + scale = value; + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.zoom.enabled) { + swiper.zoom.enable(); + } + }, + destroy() { + const swiper = this; + swiper.zoom.disable(); + }, + touchStart(e) { + const swiper = this; + if (!swiper.zoom.enabled) return; + swiper.zoom.onTouchStart(e); + }, + touchEnd(e) { + const swiper = this; + if (!swiper.zoom.enabled) return; + swiper.zoom.onTouchEnd(e); + }, + doubleTap(e) { + const swiper = this; + if (swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) { + swiper.zoom.toggle(e); + } + }, + transitionEnd() { + const swiper = this; + if (swiper.zoom.enabled && swiper.params.zoom.enabled) { + swiper.zoom.onTransitionEnd(); + } + }, + }, +}; + +const Lazy = { + loadInSlide(index, loadInDuplicate = true) { + const swiper = this; + const params = swiper.params.lazy; + if (typeof index === 'undefined') return; + if (swiper.slides.length === 0) return; + const isVirtual = swiper.virtual && swiper.params.virtual.enabled; + + const $slideEl = isVirtual + ? swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-swiper-slide-index="${index}"]`) + : swiper.slides.eq(index); + + let $images = $slideEl.find(`.${params.elementClass}:not(.${params.loadedClass}):not(.${params.loadingClass})`); + if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) { + $images = $images.add($slideEl[0]); + } + if ($images.length === 0) return; + + $images.each((imageIndex, imageEl) => { + const $imageEl = $(imageEl); + $imageEl.addClass(params.loadingClass); + + const background = $imageEl.attr('data-background'); + const src = $imageEl.attr('data-src'); + const srcset = $imageEl.attr('data-srcset'); + const sizes = $imageEl.attr('data-sizes'); + + swiper.loadImage($imageEl[0], (src || background), srcset, sizes, false, () => { + if (typeof swiper === 'undefined' || swiper === null || !swiper || (swiper && !swiper.params) || swiper.destroyed) return; + if (background) { + $imageEl.css('background-image', `url("${background}")`); + $imageEl.removeAttr('data-background'); + } else { + if (srcset) { + $imageEl.attr('srcset', srcset); + $imageEl.removeAttr('data-srcset'); + } + if (sizes) { + $imageEl.attr('sizes', sizes); + $imageEl.removeAttr('data-sizes'); + } + if (src) { + $imageEl.attr('src', src); + $imageEl.removeAttr('data-src'); + } + } + + $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass); + $slideEl.find(`.${params.preloaderClass}`).remove(); + if (swiper.params.loop && loadInDuplicate) { + const slideOriginalIndex = $slideEl.attr('data-swiper-slide-index'); + if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) { + const originalSlide = swiper.$wrapperEl.children(`[data-swiper-slide-index="${slideOriginalIndex}"]:not(.${swiper.params.slideDuplicateClass})`); + swiper.lazy.loadInSlide(originalSlide.index(), false); + } else { + const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index="${slideOriginalIndex}"]`); + swiper.lazy.loadInSlide(duplicatedSlide.index(), false); + } + } + swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]); + }); + + swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]); + }); + }, + load() { + const swiper = this; + const { + $wrapperEl, params: swiperParams, slides, activeIndex, + } = swiper; + const isVirtual = swiper.virtual && swiperParams.virtual.enabled; + const params = swiperParams.lazy; + + let slidesPerView = swiperParams.slidesPerView; + if (slidesPerView === 'auto') { + slidesPerView = 0; + } + + function slideExist(index) { + if (isVirtual) { + if ($wrapperEl.children(`.${swiperParams.slideClass}[data-swiper-slide-index="${index}"]`).length) { + return true; + } + } else if (slides[index]) return true; + return false; + } + function slideIndex(slideEl) { + if (isVirtual) { + return $(slideEl).attr('data-swiper-slide-index'); + } + return $(slideEl).index(); + } + + if (!swiper.lazy.initialImageLoaded) swiper.lazy.initialImageLoaded = true; + if (swiper.params.watchSlidesVisibility) { + $wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each((elIndex, slideEl) => { + const index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index(); + swiper.lazy.loadInSlide(index); + }); + } else if (slidesPerView > 1) { + for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) { + if (slideExist(i)) swiper.lazy.loadInSlide(i); + } + } else { + swiper.lazy.loadInSlide(activeIndex); + } + if (params.loadPrevNext) { + if (slidesPerView > 1 || (params.loadPrevNextAmount && params.loadPrevNextAmount > 1)) { + const amount = params.loadPrevNextAmount; + const spv = slidesPerView; + const maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length); + const minIndex = Math.max(activeIndex - Math.max(spv, amount), 0); + // Next Slides + for (let i = activeIndex + slidesPerView; i < maxIndex; i += 1) { + if (slideExist(i)) swiper.lazy.loadInSlide(i); + } + // Prev Slides + for (let i = minIndex; i < activeIndex; i += 1) { + if (slideExist(i)) swiper.lazy.loadInSlide(i); + } + } else { + const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`); + if (nextSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(nextSlide)); + + const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`); + if (prevSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(prevSlide)); + } + } + }, +}; + +var Lazy$1 = { + name: 'lazy', + params: { + lazy: { + enabled: false, + loadPrevNext: false, + loadPrevNextAmount: 1, + loadOnTransitionStart: false, + + elementClass: 'swiper-lazy', + loadingClass: 'swiper-lazy-loading', + loadedClass: 'swiper-lazy-loaded', + preloaderClass: 'swiper-lazy-preloader', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + lazy: { + initialImageLoaded: false, + load: Lazy.load.bind(swiper), + loadInSlide: Lazy.loadInSlide.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.lazy.enabled && swiper.params.preloadImages) { + swiper.params.preloadImages = false; + } + }, + init() { + const swiper = this; + if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) { + swiper.lazy.load(); + } + }, + scroll() { + const swiper = this; + if (swiper.params.freeMode && !swiper.params.freeModeSticky) { + swiper.lazy.load(); + } + }, + resize() { + const swiper = this; + if (swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + }, + scrollbarDragMove() { + const swiper = this; + if (swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + }, + transitionStart() { + const swiper = this; + if (swiper.params.lazy.enabled) { + if (swiper.params.lazy.loadOnTransitionStart || (!swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded)) { + swiper.lazy.load(); + } + } + }, + transitionEnd() { + const swiper = this; + if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) { + swiper.lazy.load(); + } + }, + }, +}; + +/* eslint no-bitwise: ["error", { "allow": [">>"] }] */ + +const Controller = { + LinearSpline: function LinearSpline(x, y) { + const binarySearch = (function search() { + let maxIndex; + let minIndex; + let guess; + return (array, val) => { + minIndex = -1; + maxIndex = array.length; + while (maxIndex - minIndex > 1) { + guess = maxIndex + minIndex >> 1; + if (array[guess] <= val) { + minIndex = guess; + } else { + maxIndex = guess; + } + } + return maxIndex; + }; + }()); + this.x = x; + this.y = y; + this.lastIndex = x.length - 1; + // Given an x value (x2), return the expected y2 value: + // (x1,y1) is the known point before given value, + // (x3,y3) is the known point after given value. + let i1; + let i3; + + this.interpolate = function interpolate(x2) { + if (!x2) return 0; + + // Get the indexes of x1 and x3 (the array indexes before and after given x2): + i3 = binarySearch(this.x, x2); + i1 = i3 - 1; + + // We have our indexes i1 & i3, so we can calculate already: + // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1 + return (((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1])) + this.y[i1]; + }; + return this; + }, + // xxx: for now i will just save one spline function to to + getInterpolateFunction(c) { + const swiper = this; + if (!swiper.controller.spline) { + swiper.controller.spline = swiper.params.loop + ? new Controller.LinearSpline(swiper.slidesGrid, c.slidesGrid) + : new Controller.LinearSpline(swiper.snapGrid, c.snapGrid); + } + }, + setTranslate(setTranslate, byController) { + const swiper = this; + const controlled = swiper.controller.control; + let multiplier; + let controlledTranslate; + function setControlledTranslate(c) { + // this will create an Interpolate function based on the snapGrids + // x is the Grid of the scrolled scroller and y will be the controlled scroller + // it makes sense to create this only once and recall it for the interpolation + // the function does a lot of value caching for performance + const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate; + if (swiper.params.controller.by === 'slide') { + swiper.controller.getInterpolateFunction(c); + // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid + // but it did not work out + controlledTranslate = -swiper.controller.spline.interpolate(-translate); + } + + if (!controlledTranslate || swiper.params.controller.by === 'container') { + multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate()); + controlledTranslate = ((translate - swiper.minTranslate()) * multiplier) + c.minTranslate(); + } + + if (swiper.params.controller.inverse) { + controlledTranslate = c.maxTranslate() - controlledTranslate; + } + c.updateProgress(controlledTranslate); + c.setTranslate(controlledTranslate, swiper); + c.updateActiveIndex(); + c.updateSlidesClasses(); + } + if (Array.isArray(controlled)) { + for (let i = 0; i < controlled.length; i += 1) { + if (controlled[i] !== byController && controlled[i] instanceof Swiper) { + setControlledTranslate(controlled[i]); + } + } + } else if (controlled instanceof Swiper && byController !== controlled) { + setControlledTranslate(controlled); + } + }, + setTransition(duration, byController) { + const swiper = this; + const controlled = swiper.controller.control; + let i; + function setControlledTransition(c) { + c.setTransition(duration, swiper); + if (duration !== 0) { + c.transitionStart(); + if (c.params.autoHeight) { + Utils.nextTick(() => { + c.updateAutoHeight(); + }); + } + c.$wrapperEl.transitionEnd(() => { + if (!controlled) return; + if (c.params.loop && swiper.params.controller.by === 'slide') { + c.loopFix(); + } + c.transitionEnd(); + }); + } + } + if (Array.isArray(controlled)) { + for (i = 0; i < controlled.length; i += 1) { + if (controlled[i] !== byController && controlled[i] instanceof Swiper) { + setControlledTransition(controlled[i]); + } + } + } else if (controlled instanceof Swiper && byController !== controlled) { + setControlledTransition(controlled); + } + }, +}; +var Controller$1 = { + name: 'controller', + params: { + controller: { + control: undefined, + inverse: false, + by: 'slide', // or 'container' + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + controller: { + control: swiper.params.controller.control, + getInterpolateFunction: Controller.getInterpolateFunction.bind(swiper), + setTranslate: Controller.setTranslate.bind(swiper), + setTransition: Controller.setTransition.bind(swiper), + }, + }); + }, + on: { + update() { + const swiper = this; + if (!swiper.controller.control) return; + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + resize() { + const swiper = this; + if (!swiper.controller.control) return; + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + observerUpdate() { + const swiper = this; + if (!swiper.controller.control) return; + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + setTranslate(translate, byController) { + const swiper = this; + if (!swiper.controller.control) return; + swiper.controller.setTranslate(translate, byController); + }, + setTransition(duration, byController) { + const swiper = this; + if (!swiper.controller.control) return; + swiper.controller.setTransition(duration, byController); + }, + }, +}; + +const a11y = { + makeElFocusable($el) { + $el.attr('tabIndex', '0'); + return $el; + }, + addElRole($el, role) { + $el.attr('role', role); + return $el; + }, + addElLabel($el, label) { + $el.attr('aria-label', label); + return $el; + }, + disableEl($el) { + $el.attr('aria-disabled', true); + return $el; + }, + enableEl($el) { + $el.attr('aria-disabled', false); + return $el; + }, + onEnterKey(e) { + const swiper = this; + const params = swiper.params.a11y; + if (e.keyCode !== 13) return; + const $targetEl = $(e.target); + if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) { + if (!(swiper.isEnd && !swiper.params.loop)) { + swiper.slideNext(); + } + if (swiper.isEnd) { + swiper.a11y.notify(params.lastSlideMessage); + } else { + swiper.a11y.notify(params.nextSlideMessage); + } + } + if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) { + if (!(swiper.isBeginning && !swiper.params.loop)) { + swiper.slidePrev(); + } + if (swiper.isBeginning) { + swiper.a11y.notify(params.firstSlideMessage); + } else { + swiper.a11y.notify(params.prevSlideMessage); + } + } + if (swiper.pagination && $targetEl.is(`.${swiper.params.pagination.bulletClass}`)) { + $targetEl[0].click(); + } + }, + notify(message) { + const swiper = this; + const notification = swiper.a11y.liveRegion; + if (notification.length === 0) return; + notification.html(''); + notification.html(message); + }, + updateNavigation() { + const swiper = this; + + if (swiper.params.loop) return; + const { $nextEl, $prevEl } = swiper.navigation; + + if ($prevEl && $prevEl.length > 0) { + if (swiper.isBeginning) { + swiper.a11y.disableEl($prevEl); + } else { + swiper.a11y.enableEl($prevEl); + } + } + if ($nextEl && $nextEl.length > 0) { + if (swiper.isEnd) { + swiper.a11y.disableEl($nextEl); + } else { + swiper.a11y.enableEl($nextEl); + } + } + }, + updatePagination() { + const swiper = this; + const params = swiper.params.a11y; + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.bullets.each((bulletIndex, bulletEl) => { + const $bulletEl = $(bulletEl); + swiper.a11y.makeElFocusable($bulletEl); + swiper.a11y.addElRole($bulletEl, 'button'); + swiper.a11y.addElLabel($bulletEl, params.paginationBulletMessage.replace(/{{index}}/, $bulletEl.index() + 1)); + }); + } + }, + init() { + const swiper = this; + + swiper.$el.append(swiper.a11y.liveRegion); + + // Navigation + const params = swiper.params.a11y; + let $nextEl; + let $prevEl; + if (swiper.navigation && swiper.navigation.$nextEl) { + $nextEl = swiper.navigation.$nextEl; + } + if (swiper.navigation && swiper.navigation.$prevEl) { + $prevEl = swiper.navigation.$prevEl; + } + if ($nextEl) { + swiper.a11y.makeElFocusable($nextEl); + swiper.a11y.addElRole($nextEl, 'button'); + swiper.a11y.addElLabel($nextEl, params.nextSlideMessage); + $nextEl.on('keydown', swiper.a11y.onEnterKey); + } + if ($prevEl) { + swiper.a11y.makeElFocusable($prevEl); + swiper.a11y.addElRole($prevEl, 'button'); + swiper.a11y.addElLabel($prevEl, params.prevSlideMessage); + $prevEl.on('keydown', swiper.a11y.onEnterKey); + } + + // Pagination + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.$el.on('keydown', `.${swiper.params.pagination.bulletClass}`, swiper.a11y.onEnterKey); + } + }, + destroy() { + const swiper = this; + if (swiper.a11y.liveRegion && swiper.a11y.liveRegion.length > 0) swiper.a11y.liveRegion.remove(); + + let $nextEl; + let $prevEl; + if (swiper.navigation && swiper.navigation.$nextEl) { + $nextEl = swiper.navigation.$nextEl; + } + if (swiper.navigation && swiper.navigation.$prevEl) { + $prevEl = swiper.navigation.$prevEl; + } + if ($nextEl) { + $nextEl.off('keydown', swiper.a11y.onEnterKey); + } + if ($prevEl) { + $prevEl.off('keydown', swiper.a11y.onEnterKey); + } + + // Pagination + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.$el.off('keydown', `.${swiper.params.pagination.bulletClass}`, swiper.a11y.onEnterKey); + } + }, +}; +var A11y = { + name: 'a11y', + params: { + a11y: { + enabled: true, + notificationClass: 'swiper-notification', + prevSlideMessage: 'Previous slide', + nextSlideMessage: 'Next slide', + firstSlideMessage: 'This is the first slide', + lastSlideMessage: 'This is the last slide', + paginationBulletMessage: 'Go to slide {{index}}', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + a11y: { + liveRegion: $(``), + }, + }); + Object.keys(a11y).forEach((methodName) => { + swiper.a11y[methodName] = a11y[methodName].bind(swiper); + }); + }, + on: { + init() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.init(); + swiper.a11y.updateNavigation(); + }, + toEdge() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.updateNavigation(); + }, + fromEdge() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.updateNavigation(); + }, + paginationUpdate() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.updatePagination(); + }, + destroy() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.destroy(); + }, + }, +}; + +const History = { + init() { + const swiper = this; + if (!swiper.params.history) return; + if (!window.history || !window.history.pushState) { + swiper.params.history.enabled = false; + swiper.params.hashNavigation.enabled = true; + return; + } + const history = swiper.history; + history.initialized = true; + history.paths = History.getPathValues(); + if (!history.paths.key && !history.paths.value) return; + history.scrollToSlide(0, history.paths.value, swiper.params.runCallbacksOnInit); + if (!swiper.params.history.replaceState) { + window.addEventListener('popstate', swiper.history.setHistoryPopState); + } + }, + destroy() { + const swiper = this; + if (!swiper.params.history.replaceState) { + window.removeEventListener('popstate', swiper.history.setHistoryPopState); + } + }, + setHistoryPopState() { + const swiper = this; + swiper.history.paths = History.getPathValues(); + swiper.history.scrollToSlide(swiper.params.speed, swiper.history.paths.value, false); + }, + getPathValues() { + const pathArray = window.location.pathname.slice(1).split('/').filter(part => part !== ''); + const total = pathArray.length; + const key = pathArray[total - 2]; + const value = pathArray[total - 1]; + return { key, value }; + }, + setHistory(key, index) { + const swiper = this; + if (!swiper.history.initialized || !swiper.params.history.enabled) return; + const slide = swiper.slides.eq(index); + let value = History.slugify(slide.attr('data-history')); + if (!window.location.pathname.includes(key)) { + value = `${key}/${value}`; + } + const currentState = window.history.state; + if (currentState && currentState.value === value) { + return; + } + if (swiper.params.history.replaceState) { + window.history.replaceState({ value }, null, value); + } else { + window.history.pushState({ value }, null, value); + } + }, + slugify(text) { + return text.toString() + .replace(/\s+/g, '-') + .replace(/[^\w-]+/g, '') + .replace(/--+/g, '-') + .replace(/^-+/, '') + .replace(/-+$/, ''); + }, + scrollToSlide(speed, value, runCallbacks) { + const swiper = this; + if (value) { + for (let i = 0, length = swiper.slides.length; i < length; i += 1) { + const slide = swiper.slides.eq(i); + const slideHistory = History.slugify(slide.attr('data-history')); + if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) { + const index = slide.index(); + swiper.slideTo(index, speed, runCallbacks); + } + } + } else { + swiper.slideTo(0, speed, runCallbacks); + } + }, +}; + +var History$1 = { + name: 'history', + params: { + history: { + enabled: false, + replaceState: false, + key: 'slides', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + history: { + init: History.init.bind(swiper), + setHistory: History.setHistory.bind(swiper), + setHistoryPopState: History.setHistoryPopState.bind(swiper), + scrollToSlide: History.scrollToSlide.bind(swiper), + destroy: History.destroy.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.history.enabled) { + swiper.history.init(); + } + }, + destroy() { + const swiper = this; + if (swiper.params.history.enabled) { + swiper.history.destroy(); + } + }, + transitionEnd() { + const swiper = this; + if (swiper.history.initialized) { + swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex); + } + }, + }, +}; + +const HashNavigation = { + onHashCange() { + const swiper = this; + const newHash = document.location.hash.replace('#', ''); + const activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash'); + if (newHash !== activeSlideHash) { + const newIndex = swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-hash="${newHash}"]`).index(); + if (typeof newIndex === 'undefined') return; + swiper.slideTo(newIndex); + } + }, + setHash() { + const swiper = this; + if (!swiper.hashNavigation.initialized || !swiper.params.hashNavigation.enabled) return; + if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) { + window.history.replaceState(null, null, (`#${swiper.slides.eq(swiper.activeIndex).attr('data-hash')}` || '')); + } else { + const slide = swiper.slides.eq(swiper.activeIndex); + const hash = slide.attr('data-hash') || slide.attr('data-history'); + document.location.hash = hash || ''; + } + }, + init() { + const swiper = this; + if (!swiper.params.hashNavigation.enabled || (swiper.params.history && swiper.params.history.enabled)) return; + swiper.hashNavigation.initialized = true; + const hash = document.location.hash.replace('#', ''); + if (hash) { + const speed = 0; + for (let i = 0, length = swiper.slides.length; i < length; i += 1) { + const slide = swiper.slides.eq(i); + const slideHash = slide.attr('data-hash') || slide.attr('data-history'); + if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) { + const index = slide.index(); + swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true); + } + } + } + if (swiper.params.hashNavigation.watchState) { + $(window).on('hashchange', swiper.hashNavigation.onHashCange); + } + }, + destroy() { + const swiper = this; + if (swiper.params.hashNavigation.watchState) { + $(window).off('hashchange', swiper.hashNavigation.onHashCange); + } + }, +}; +var HashNavigation$1 = { + name: 'hash-navigation', + params: { + hashNavigation: { + enabled: false, + replaceState: false, + watchState: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + hashNavigation: { + initialized: false, + init: HashNavigation.init.bind(swiper), + destroy: HashNavigation.destroy.bind(swiper), + setHash: HashNavigation.setHash.bind(swiper), + onHashCange: HashNavigation.onHashCange.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.hashNavigation.enabled) { + swiper.hashNavigation.init(); + } + }, + destroy() { + const swiper = this; + if (swiper.params.hashNavigation.enabled) { + swiper.hashNavigation.destroy(); + } + }, + transitionEnd() { + const swiper = this; + if (swiper.hashNavigation.initialized) { + swiper.hashNavigation.setHash(); + } + }, + }, +}; + +/* eslint no-underscore-dangle: "off" */ + +const Autoplay = { + run() { + const swiper = this; + const $activeSlideEl = swiper.slides.eq(swiper.activeIndex); + let delay = swiper.params.autoplay.delay; + if ($activeSlideEl.attr('data-swiper-autoplay')) { + delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay; + } + swiper.autoplay.timeout = Utils.nextTick(() => { + if (swiper.params.autoplay.reverseDirection) { + if (swiper.params.loop) { + swiper.loopFix(); + swiper.slidePrev(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.isBeginning) { + swiper.slidePrev(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.params.autoplay.stopOnLastSlide) { + swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else { + swiper.autoplay.stop(); + } + } else if (swiper.params.loop) { + swiper.loopFix(); + swiper.slideNext(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.isEnd) { + swiper.slideNext(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.params.autoplay.stopOnLastSlide) { + swiper.slideTo(0, swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else { + swiper.autoplay.stop(); + } + }, delay); + }, + start() { + const swiper = this; + if (typeof swiper.autoplay.timeout !== 'undefined') return false; + if (swiper.autoplay.running) return false; + swiper.autoplay.running = true; + swiper.emit('autoplayStart'); + swiper.autoplay.run(); + return true; + }, + stop() { + const swiper = this; + if (!swiper.autoplay.running) return false; + if (typeof swiper.autoplay.timeout === 'undefined') return false; + + if (swiper.autoplay.timeout) { + clearTimeout(swiper.autoplay.timeout); + swiper.autoplay.timeout = undefined; + } + swiper.autoplay.running = false; + swiper.emit('autoplayStop'); + return true; + }, + pause(speed) { + const swiper = this; + if (!swiper.autoplay.running) return; + if (swiper.autoplay.paused) return; + if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout); + swiper.autoplay.paused = true; + if (speed === 0 || !swiper.params.autoplay.waitForTransition) { + swiper.autoplay.paused = false; + swiper.autoplay.run(); + } else { + swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd); + swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd); + } + }, +}; + +var Autoplay$1 = { + name: 'autoplay', + params: { + autoplay: { + enabled: false, + delay: 3000, + waitForTransition: true, + disableOnInteraction: true, + stopOnLastSlide: false, + reverseDirection: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + autoplay: { + running: false, + paused: false, + run: Autoplay.run.bind(swiper), + start: Autoplay.start.bind(swiper), + stop: Autoplay.stop.bind(swiper), + pause: Autoplay.pause.bind(swiper), + onTransitionEnd(e) { + if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return; + if (e.target !== this) return; + swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd); + swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd); + swiper.autoplay.paused = false; + if (!swiper.autoplay.running) { + swiper.autoplay.stop(); + } else { + swiper.autoplay.run(); + } + }, + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.autoplay.enabled) { + swiper.autoplay.start(); + } + }, + beforeTransitionStart(speed, internal) { + const swiper = this; + if (swiper.autoplay.running) { + if (internal || !swiper.params.autoplay.disableOnInteraction) { + swiper.autoplay.pause(speed); + } else { + swiper.autoplay.stop(); + } + } + }, + sliderFirstMove() { + const swiper = this; + if (swiper.autoplay.running) { + if (swiper.params.autoplay.disableOnInteraction) { + swiper.autoplay.stop(); + } else { + swiper.autoplay.pause(); + } + } + }, + destroy() { + const swiper = this; + if (swiper.autoplay.running) { + swiper.autoplay.stop(); + } + }, + }, +}; + +const Fade = { + setTranslate() { + const swiper = this; + const { slides } = swiper; + for (let i = 0; i < slides.length; i += 1) { + const $slideEl = swiper.slides.eq(i); + const offset = $slideEl[0].swiperSlideOffset; + let tx = -offset; + if (!swiper.params.virtualTranslate) tx -= swiper.translate; + let ty = 0; + if (!swiper.isHorizontal()) { + ty = tx; + tx = 0; + } + const slideOpacity = swiper.params.fadeEffect.crossFade + ? Math.max(1 - Math.abs($slideEl[0].progress), 0) + : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0); + $slideEl + .css({ + opacity: slideOpacity, + }) + .transform(`translate3d(${tx}px, ${ty}px, 0px)`); + } + }, + setTransition(duration) { + const swiper = this; + const { slides, $wrapperEl } = swiper; + slides.transition(duration); + if (swiper.params.virtualTranslate && duration !== 0) { + let eventTriggered = false; + slides.transitionEnd(() => { + if (eventTriggered) return; + if (!swiper || swiper.destroyed) return; + eventTriggered = true; + swiper.animating = false; + const triggerEvents = ['webkitTransitionEnd', 'transitionend']; + for (let i = 0; i < triggerEvents.length; i += 1) { + $wrapperEl.trigger(triggerEvents[i]); + } + }); + } + }, +}; + +var EffectFade = { + name: 'effect-fade', + params: { + fadeEffect: { + crossFade: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + fadeEffect: { + setTranslate: Fade.setTranslate.bind(swiper), + setTransition: Fade.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'fade') return; + swiper.classNames.push(`${swiper.params.containerModifierClass}fade`); + const overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + spaceBetween: 0, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'fade') return; + swiper.fadeEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'fade') return; + swiper.fadeEffect.setTransition(duration); + }, + }, +}; + +const Cube = { + setTranslate() { + const swiper = this; + const { + $el, $wrapperEl, slides, width: swiperWidth, height: swiperHeight, rtlTranslate: rtl, size: swiperSize, + } = swiper; + const params = swiper.params.cubeEffect; + const isHorizontal = swiper.isHorizontal(); + const isVirtual = swiper.virtual && swiper.params.virtual.enabled; + let wrapperRotate = 0; + let $cubeShadowEl; + if (params.shadow) { + if (isHorizontal) { + $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow'); + if ($cubeShadowEl.length === 0) { + $cubeShadowEl = $('
            '); + $wrapperEl.append($cubeShadowEl); + } + $cubeShadowEl.css({ height: `${swiperWidth}px` }); + } else { + $cubeShadowEl = $el.find('.swiper-cube-shadow'); + if ($cubeShadowEl.length === 0) { + $cubeShadowEl = $('
            '); + $el.append($cubeShadowEl); + } + } + } + for (let i = 0; i < slides.length; i += 1) { + const $slideEl = slides.eq(i); + let slideIndex = i; + if (isVirtual) { + slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10); + } + let slideAngle = slideIndex * 90; + let round = Math.floor(slideAngle / 360); + if (rtl) { + slideAngle = -slideAngle; + round = Math.floor(-slideAngle / 360); + } + const progress = Math.max(Math.min($slideEl[0].progress, 1), -1); + let tx = 0; + let ty = 0; + let tz = 0; + if (slideIndex % 4 === 0) { + tx = -round * 4 * swiperSize; + tz = 0; + } else if ((slideIndex - 1) % 4 === 0) { + tx = 0; + tz = -round * 4 * swiperSize; + } else if ((slideIndex - 2) % 4 === 0) { + tx = swiperSize + (round * 4 * swiperSize); + tz = swiperSize; + } else if ((slideIndex - 3) % 4 === 0) { + tx = -swiperSize; + tz = (3 * swiperSize) + (swiperSize * 4 * round); + } + if (rtl) { + tx = -tx; + } + + if (!isHorizontal) { + ty = tx; + tx = 0; + } + + const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${isHorizontal ? slideAngle : 0}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`; + if (progress <= 1 && progress > -1) { + wrapperRotate = (slideIndex * 90) + (progress * 90); + if (rtl) wrapperRotate = (-slideIndex * 90) - (progress * 90); + } + $slideEl.transform(transform); + if (params.slideShadows) { + // Set shadows + let shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + let shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if (shadowBefore.length === 0) { + shadowBefore = $(`
            `); + $slideEl.append(shadowBefore); + } + if (shadowAfter.length === 0) { + shadowAfter = $(`
            `); + $slideEl.append(shadowAfter); + } + if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0); + if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0); + } + } + $wrapperEl.css({ + '-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`, + '-moz-transform-origin': `50% 50% -${swiperSize / 2}px`, + '-ms-transform-origin': `50% 50% -${swiperSize / 2}px`, + 'transform-origin': `50% 50% -${swiperSize / 2}px`, + }); + + if (params.shadow) { + if (isHorizontal) { + $cubeShadowEl.transform(`translate3d(0px, ${(swiperWidth / 2) + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`); + } else { + const shadowAngle = Math.abs(wrapperRotate) - (Math.floor(Math.abs(wrapperRotate) / 90) * 90); + const multiplier = 1.5 - ( + (Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2) + + (Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2) + ); + const scale1 = params.shadowScale; + const scale2 = params.shadowScale / multiplier; + const offset = params.shadowOffset; + $cubeShadowEl.transform(`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${(swiperHeight / 2) + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-90deg)`); + } + } + const zFactor = (Browser.isSafari || Browser.isUiWebView) ? (-swiperSize / 2) : 0; + $wrapperEl + .transform(`translate3d(0px,0,${zFactor}px) rotateX(${swiper.isHorizontal() ? 0 : wrapperRotate}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`); + }, + setTransition(duration) { + const swiper = this; + const { $el, slides } = swiper; + slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) { + $el.find('.swiper-cube-shadow').transition(duration); + } + }, +}; + +var EffectCube = { + name: 'effect-cube', + params: { + cubeEffect: { + slideShadows: true, + shadow: true, + shadowOffset: 20, + shadowScale: 0.94, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + cubeEffect: { + setTranslate: Cube.setTranslate.bind(swiper), + setTransition: Cube.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'cube') return; + swiper.classNames.push(`${swiper.params.containerModifierClass}cube`); + swiper.classNames.push(`${swiper.params.containerModifierClass}3d`); + const overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + resistanceRatio: 0, + spaceBetween: 0, + centeredSlides: false, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'cube') return; + swiper.cubeEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'cube') return; + swiper.cubeEffect.setTransition(duration); + }, + }, +}; + +const Flip = { + setTranslate() { + const swiper = this; + const { slides, rtlTranslate: rtl } = swiper; + for (let i = 0; i < slides.length; i += 1) { + const $slideEl = slides.eq(i); + let progress = $slideEl[0].progress; + if (swiper.params.flipEffect.limitRotation) { + progress = Math.max(Math.min($slideEl[0].progress, 1), -1); + } + const offset = $slideEl[0].swiperSlideOffset; + const rotate = -180 * progress; + let rotateY = rotate; + let rotateX = 0; + let tx = -offset; + let ty = 0; + if (!swiper.isHorizontal()) { + ty = tx; + tx = 0; + rotateX = -rotateY; + rotateY = 0; + } else if (rtl) { + rotateY = -rotateY; + } + + $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length; + + if (swiper.params.flipEffect.slideShadows) { + // Set shadows + let shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + let shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if (shadowBefore.length === 0) { + shadowBefore = $(`
            `); + $slideEl.append(shadowBefore); + } + if (shadowAfter.length === 0) { + shadowAfter = $(`
            `); + $slideEl.append(shadowAfter); + } + if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0); + if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0); + } + $slideEl + .transform(`translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`); + } + }, + setTransition(duration) { + const swiper = this; + const { slides, activeIndex, $wrapperEl } = swiper; + slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + if (swiper.params.virtualTranslate && duration !== 0) { + let eventTriggered = false; + // eslint-disable-next-line + slides.eq(activeIndex).transitionEnd(function onTransitionEnd() { + if (eventTriggered) return; + if (!swiper || swiper.destroyed) return; + // if (!$(this).hasClass(swiper.params.slideActiveClass)) return; + eventTriggered = true; + swiper.animating = false; + const triggerEvents = ['webkitTransitionEnd', 'transitionend']; + for (let i = 0; i < triggerEvents.length; i += 1) { + $wrapperEl.trigger(triggerEvents[i]); + } + }); + } + }, +}; + +var EffectFlip = { + name: 'effect-flip', + params: { + flipEffect: { + slideShadows: true, + limitRotation: true, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + flipEffect: { + setTranslate: Flip.setTranslate.bind(swiper), + setTransition: Flip.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'flip') return; + swiper.classNames.push(`${swiper.params.containerModifierClass}flip`); + swiper.classNames.push(`${swiper.params.containerModifierClass}3d`); + const overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + spaceBetween: 0, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'flip') return; + swiper.flipEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'flip') return; + swiper.flipEffect.setTransition(duration); + }, + }, +}; + +const Coverflow = { + setTranslate() { + const swiper = this; + const { + width: swiperWidth, height: swiperHeight, slides, $wrapperEl, slidesSizesGrid, + } = swiper; + const params = swiper.params.coverflowEffect; + const isHorizontal = swiper.isHorizontal(); + const transform = swiper.translate; + const center = isHorizontal ? -transform + (swiperWidth / 2) : -transform + (swiperHeight / 2); + const rotate = isHorizontal ? params.rotate : -params.rotate; + const translate = params.depth; + // Each slide offset from center + for (let i = 0, length = slides.length; i < length; i += 1) { + const $slideEl = slides.eq(i); + const slideSize = slidesSizesGrid[i]; + const slideOffset = $slideEl[0].swiperSlideOffset; + const offsetMultiplier = ((center - slideOffset - (slideSize / 2)) / slideSize) * params.modifier; + + let rotateY = isHorizontal ? rotate * offsetMultiplier : 0; + let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; + // var rotateZ = 0 + let translateZ = -translate * Math.abs(offsetMultiplier); + + let translateY = isHorizontal ? 0 : params.stretch * (offsetMultiplier); + let translateX = isHorizontal ? params.stretch * (offsetMultiplier) : 0; + + // Fix for ultra small values + if (Math.abs(translateX) < 0.001) translateX = 0; + if (Math.abs(translateY) < 0.001) translateY = 0; + if (Math.abs(translateZ) < 0.001) translateZ = 0; + if (Math.abs(rotateY) < 0.001) rotateY = 0; + if (Math.abs(rotateX) < 0.001) rotateX = 0; + + const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; + + $slideEl.transform(slideTransform); + $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1; + if (params.slideShadows) { + // Set shadows + let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if ($shadowBeforeEl.length === 0) { + $shadowBeforeEl = $(`
            `); + $slideEl.append($shadowBeforeEl); + } + if ($shadowAfterEl.length === 0) { + $shadowAfterEl = $(`
            `); + $slideEl.append($shadowAfterEl); + } + if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0; + if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0; + } + } + + // Set correct perspective for IE10 + if (Support.pointerEvents || Support.prefixedPointerEvents) { + const ws = $wrapperEl[0].style; + ws.perspectiveOrigin = `${center}px 50%`; + } + }, + setTransition(duration) { + const swiper = this; + swiper.slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + }, +}; + +var EffectCoverflow = { + name: 'effect-coverflow', + params: { + coverflowEffect: { + rotate: 50, + stretch: 0, + depth: 100, + modifier: 1, + slideShadows: true, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + coverflowEffect: { + setTranslate: Coverflow.setTranslate.bind(swiper), + setTransition: Coverflow.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'coverflow') return; + + swiper.classNames.push(`${swiper.params.containerModifierClass}coverflow`); + swiper.classNames.push(`${swiper.params.containerModifierClass}3d`); + + swiper.params.watchSlidesProgress = true; + swiper.originalParams.watchSlidesProgress = true; + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'coverflow') return; + swiper.coverflowEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'coverflow') return; + swiper.coverflowEffect.setTransition(duration); + }, + }, +}; + +const Thumbs = { + init() { + const swiper = this; + const { thumbs: thumbsParams } = swiper.params; + const SwiperClass = swiper.constructor; + if (thumbsParams.swiper instanceof SwiperClass) { + swiper.thumbs.swiper = thumbsParams.swiper; + Utils.extend(swiper.thumbs.swiper.originalParams, { + watchSlidesProgress: true, + slideToClickedSlide: false, + }); + Utils.extend(swiper.thumbs.swiper.params, { + watchSlidesProgress: true, + slideToClickedSlide: false, + }); + } else if (Utils.isObject(thumbsParams.swiper)) { + swiper.thumbs.swiper = new SwiperClass(Utils.extend({}, thumbsParams.swiper, { + watchSlidesVisibility: true, + watchSlidesProgress: true, + slideToClickedSlide: false, + })); + swiper.thumbs.swiperCreated = true; + } + swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass); + swiper.thumbs.swiper.on('tap', swiper.thumbs.onThumbClick); + }, + onThumbClick() { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + const clickedIndex = thumbsSwiper.clickedIndex; + const clickedSlide = thumbsSwiper.clickedSlide; + if (clickedSlide && $(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) return; + if (typeof clickedIndex === 'undefined' || clickedIndex === null) return; + let slideToIndex; + if (thumbsSwiper.params.loop) { + slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10); + } else { + slideToIndex = clickedIndex; + } + if (swiper.params.loop) { + let currentIndex = swiper.activeIndex; + if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) { + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + currentIndex = swiper.activeIndex; + } + const prevIndex = swiper.slides.eq(currentIndex).prevAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index(); + const nextIndex = swiper.slides.eq(currentIndex).nextAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index(); + if (typeof prevIndex === 'undefined') slideToIndex = nextIndex; + else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex; + else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex; + else slideToIndex = prevIndex; + } + swiper.slideTo(slideToIndex); + }, + update(initial) { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + + const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' + ? thumbsSwiper.slidesPerViewDynamic() + : thumbsSwiper.params.slidesPerView; + + if (swiper.realIndex !== thumbsSwiper.realIndex) { + let currentThumbsIndex = thumbsSwiper.activeIndex; + let newThumbsIndex; + if (thumbsSwiper.params.loop) { + if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) { + thumbsSwiper.loopFix(); + // eslint-disable-next-line + thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft; + currentThumbsIndex = thumbsSwiper.activeIndex; + } + // Find actual thumbs index to slide to + const prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index(); + const nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index(); + if (typeof prevThumbsIndex === 'undefined') newThumbsIndex = nextThumbsIndex; + else if (typeof nextThumbsIndex === 'undefined') newThumbsIndex = prevThumbsIndex; + else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) newThumbsIndex = currentThumbsIndex; + else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) newThumbsIndex = nextThumbsIndex; + else newThumbsIndex = prevThumbsIndex; + } else { + newThumbsIndex = swiper.realIndex; + } + if (thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) { + if (thumbsSwiper.params.centeredSlides) { + if (newThumbsIndex > currentThumbsIndex) { + newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1; + } else { + newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1; + } + } else if (newThumbsIndex > currentThumbsIndex) { + newThumbsIndex = newThumbsIndex - slidesPerView + 1; + } + thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined); + } + } + + // Activate thumbs + let thumbsToActivate = 1; + const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass; + + if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) { + thumbsToActivate = swiper.params.slidesPerView; + } + + thumbsSwiper.slides.removeClass(thumbActiveClass); + if (thumbsSwiper.params.loop) { + for (let i = 0; i < thumbsToActivate; i += 1) { + thumbsSwiper.$wrapperEl.children(`[data-swiper-slide-index="${swiper.realIndex + i}"]`).addClass(thumbActiveClass); + } + } else { + for (let i = 0; i < thumbsToActivate; i += 1) { + thumbsSwiper.slides.eq(swiper.realIndex + i).addClass(thumbActiveClass); + } + } + }, +}; +var Thumbs$1 = { + name: 'thumbs', + params: { + thumbs: { + swiper: null, + slideThumbActiveClass: 'swiper-slide-thumb-active', + thumbsContainerClass: 'swiper-container-thumbs', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + thumbs: { + swiper: null, + init: Thumbs.init.bind(swiper), + update: Thumbs.update.bind(swiper), + onThumbClick: Thumbs.onThumbClick.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + const { thumbs } = swiper.params; + if (!thumbs || !thumbs.swiper) return; + swiper.thumbs.init(); + swiper.thumbs.update(true); + }, + slideChange() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + update() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + resize() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + observerUpdate() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + setTransition(duration) { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + thumbsSwiper.setTransition(duration); + }, + beforeDestroy() { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + if (swiper.thumbs.swiperCreated && thumbsSwiper) { + thumbsSwiper.destroy(); + } + }, + }, +}; + +// Swiper Class + +const components = [ + Device$1, + Support$1, + Browser$1, + Resize, + Observer$1, + Virtual$1, + Keyboard$1, + Mousewheel$1, + Navigation$1, + Pagination$1, + Scrollbar$1, + Parallax$1, + Zoom$1, + Lazy$1, + Controller$1, + A11y, + History$1, + HashNavigation$1, + Autoplay$1, + EffectFade, + EffectCube, + EffectFlip, + EffectCoverflow, + Thumbs$1 +]; + +if (typeof Swiper.use === 'undefined') { + Swiper.use = Swiper.Class.use; + Swiper.installModule = Swiper.Class.installModule; +} + +Swiper.use(components); + +export default Swiper; diff --git a/assets/3rd/swiper/js/swiper.esm.js b/assets/3rd/swiper/js/swiper.esm.js new file mode 100755 index 00000000..222f1802 --- /dev/null +++ b/assets/3rd/swiper/js/swiper.esm.js @@ -0,0 +1,7133 @@ +/** + * Swiper 4.5.0 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * http://www.idangero.us/swiper/ + * + * Copyright 2014-2019 Vladimir Kharlampidi + * + * Released under the MIT License + * + * Released on: February 22, 2019 + */ + +import { $, addClass, removeClass, hasClass, toggleClass, attr, removeAttr, data, transform, transition as transition$1, on, off, trigger, transitionEnd as transitionEnd$1, outerWidth, outerHeight, offset, css, each, html, text, is, index, eq, append, prepend, next, nextAll, prev, prevAll, parent, parents, closest, find, children, remove, add, styles } from 'dom7/dist/dom7.modular'; +import { window, document } from 'ssr-window'; + +const Methods = { + addClass, + removeClass, + hasClass, + toggleClass, + attr, + removeAttr, + data, + transform, + transition: transition$1, + on, + off, + trigger, + transitionEnd: transitionEnd$1, + outerWidth, + outerHeight, + offset, + css, + each, + html, + text, + is, + index, + eq, + append, + prepend, + next, + nextAll, + prev, + prevAll, + parent, + parents, + closest, + find, + children, + remove, + add, + styles, +}; + +Object.keys(Methods).forEach((methodName) => { + $.fn[methodName] = Methods[methodName]; +}); + +const Utils = { + deleteProps(obj) { + const object = obj; + Object.keys(object).forEach((key) => { + try { + object[key] = null; + } catch (e) { + // no getter for object + } + try { + delete object[key]; + } catch (e) { + // something got wrong + } + }); + }, + nextTick(callback, delay = 0) { + return setTimeout(callback, delay); + }, + now() { + return Date.now(); + }, + getTranslate(el, axis = 'x') { + let matrix; + let curTransform; + let transformMatrix; + + const curStyle = window.getComputedStyle(el, null); + + if (window.WebKitCSSMatrix) { + curTransform = curStyle.transform || curStyle.webkitTransform; + if (curTransform.split(',').length > 6) { + curTransform = curTransform.split(', ').map(a => a.replace(',', '.')).join(', '); + } + // Some old versions of Webkit choke when 'none' is passed; pass + // empty string instead in this case + transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform); + } else { + transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,'); + matrix = transformMatrix.toString().split(','); + } + + if (axis === 'x') { + // Latest Chrome and webkits Fix + if (window.WebKitCSSMatrix) curTransform = transformMatrix.m41; + // Crazy IE10 Matrix + else if (matrix.length === 16) curTransform = parseFloat(matrix[12]); + // Normal Browsers + else curTransform = parseFloat(matrix[4]); + } + if (axis === 'y') { + // Latest Chrome and webkits Fix + if (window.WebKitCSSMatrix) curTransform = transformMatrix.m42; + // Crazy IE10 Matrix + else if (matrix.length === 16) curTransform = parseFloat(matrix[13]); + // Normal Browsers + else curTransform = parseFloat(matrix[5]); + } + return curTransform || 0; + }, + parseUrlQuery(url) { + const query = {}; + let urlToParse = url || window.location.href; + let i; + let params; + let param; + let length; + if (typeof urlToParse === 'string' && urlToParse.length) { + urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\S*\?/, '') : ''; + params = urlToParse.split('&').filter(paramsPart => paramsPart !== ''); + length = params.length; + + for (i = 0; i < length; i += 1) { + param = params[i].replace(/#\S+/g, '').split('='); + query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param[1]) || ''; + } + } + return query; + }, + isObject(o) { + return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object; + }, + extend(...args) { + const to = Object(args[0]); + for (let i = 1; i < args.length; i += 1) { + const nextSource = args[i]; + if (nextSource !== undefined && nextSource !== null) { + const keysArray = Object.keys(Object(nextSource)); + for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) { + const nextKey = keysArray[nextIndex]; + const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); + if (desc !== undefined && desc.enumerable) { + if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) { + Utils.extend(to[nextKey], nextSource[nextKey]); + } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) { + to[nextKey] = {}; + Utils.extend(to[nextKey], nextSource[nextKey]); + } else { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + } + return to; + }, +}; + +const Support = (function Support() { + const testDiv = document.createElement('div'); + return { + touch: (window.Modernizr && window.Modernizr.touch === true) || (function checkTouch() { + return !!((window.navigator.maxTouchPoints > 0) || ('ontouchstart' in window) || (window.DocumentTouch && document instanceof window.DocumentTouch)); + }()), + + pointerEvents: !!(window.navigator.pointerEnabled || window.PointerEvent || ('maxTouchPoints' in window.navigator && window.navigator.maxTouchPoints > 0)), + prefixedPointerEvents: !!window.navigator.msPointerEnabled, + + transition: (function checkTransition() { + const style = testDiv.style; + return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style); + }()), + transforms3d: (window.Modernizr && window.Modernizr.csstransforms3d === true) || (function checkTransforms3d() { + const style = testDiv.style; + return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style); + }()), + + flexbox: (function checkFlexbox() { + const style = testDiv.style; + const styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' '); + for (let i = 0; i < styles.length; i += 1) { + if (styles[i] in style) return true; + } + return false; + }()), + + observer: (function checkObserver() { + return ('MutationObserver' in window || 'WebkitMutationObserver' in window); + }()), + + passiveListener: (function checkPassiveListener() { + let supportsPassive = false; + try { + const opts = Object.defineProperty({}, 'passive', { + // eslint-disable-next-line + get() { + supportsPassive = true; + }, + }); + window.addEventListener('testPassiveListener', null, opts); + } catch (e) { + // No support + } + return supportsPassive; + }()), + + gestures: (function checkGestures() { + return 'ongesturestart' in window; + }()), + }; +}()); + +const Browser = (function Browser() { + function isSafari() { + const ua = window.navigator.userAgent.toLowerCase(); + return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0); + } + return { + isIE: !!window.navigator.userAgent.match(/Trident/g) || !!window.navigator.userAgent.match(/MSIE/g), + isEdge: !!window.navigator.userAgent.match(/Edge/g), + isSafari: isSafari(), + isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent), + }; +}()); + +class SwiperClass { + constructor(params = {}) { + const self = this; + self.params = params; + + // Events + self.eventsListeners = {}; + + if (self.params && self.params.on) { + Object.keys(self.params.on).forEach((eventName) => { + self.on(eventName, self.params.on[eventName]); + }); + } + } + + on(events, handler, priority) { + const self = this; + if (typeof handler !== 'function') return self; + const method = priority ? 'unshift' : 'push'; + events.split(' ').forEach((event) => { + if (!self.eventsListeners[event]) self.eventsListeners[event] = []; + self.eventsListeners[event][method](handler); + }); + return self; + } + + once(events, handler, priority) { + const self = this; + if (typeof handler !== 'function') return self; + function onceHandler(...args) { + handler.apply(self, args); + self.off(events, onceHandler); + if (onceHandler.f7proxy) { + delete onceHandler.f7proxy; + } + } + onceHandler.f7proxy = handler; + return self.on(events, onceHandler, priority); + } + + off(events, handler) { + const self = this; + if (!self.eventsListeners) return self; + events.split(' ').forEach((event) => { + if (typeof handler === 'undefined') { + self.eventsListeners[event] = []; + } else if (self.eventsListeners[event] && self.eventsListeners[event].length) { + self.eventsListeners[event].forEach((eventHandler, index) => { + if (eventHandler === handler || (eventHandler.f7proxy && eventHandler.f7proxy === handler)) { + self.eventsListeners[event].splice(index, 1); + } + }); + } + }); + return self; + } + + emit(...args) { + const self = this; + if (!self.eventsListeners) return self; + let events; + let data; + let context; + if (typeof args[0] === 'string' || Array.isArray(args[0])) { + events = args[0]; + data = args.slice(1, args.length); + context = self; + } else { + events = args[0].events; + data = args[0].data; + context = args[0].context || self; + } + const eventsArray = Array.isArray(events) ? events : events.split(' '); + eventsArray.forEach((event) => { + if (self.eventsListeners && self.eventsListeners[event]) { + const handlers = []; + self.eventsListeners[event].forEach((eventHandler) => { + handlers.push(eventHandler); + }); + handlers.forEach((eventHandler) => { + eventHandler.apply(context, data); + }); + } + }); + return self; + } + + useModulesParams(instanceParams) { + const instance = this; + if (!instance.modules) return; + Object.keys(instance.modules).forEach((moduleName) => { + const module = instance.modules[moduleName]; + // Extend params + if (module.params) { + Utils.extend(instanceParams, module.params); + } + }); + } + + useModules(modulesParams = {}) { + const instance = this; + if (!instance.modules) return; + Object.keys(instance.modules).forEach((moduleName) => { + const module = instance.modules[moduleName]; + const moduleParams = modulesParams[moduleName] || {}; + // Extend instance methods and props + if (module.instance) { + Object.keys(module.instance).forEach((modulePropName) => { + const moduleProp = module.instance[modulePropName]; + if (typeof moduleProp === 'function') { + instance[modulePropName] = moduleProp.bind(instance); + } else { + instance[modulePropName] = moduleProp; + } + }); + } + // Add event listeners + if (module.on && instance.on) { + Object.keys(module.on).forEach((moduleEventName) => { + instance.on(moduleEventName, module.on[moduleEventName]); + }); + } + + // Module create callback + if (module.create) { + module.create.bind(instance)(moduleParams); + } + }); + } + + static set components(components) { + const Class = this; + if (!Class.use) return; + Class.use(components); + } + + static installModule(module, ...params) { + const Class = this; + if (!Class.prototype.modules) Class.prototype.modules = {}; + const name = module.name || (`${Object.keys(Class.prototype.modules).length}_${Utils.now()}`); + Class.prototype.modules[name] = module; + // Prototype + if (module.proto) { + Object.keys(module.proto).forEach((key) => { + Class.prototype[key] = module.proto[key]; + }); + } + // Class + if (module.static) { + Object.keys(module.static).forEach((key) => { + Class[key] = module.static[key]; + }); + } + // Callback + if (module.install) { + module.install.apply(Class, params); + } + return Class; + } + + static use(module, ...params) { + const Class = this; + if (Array.isArray(module)) { + module.forEach(m => Class.installModule(m)); + return Class; + } + return Class.installModule(module, ...params); + } +} + +function updateSize () { + const swiper = this; + let width; + let height; + const $el = swiper.$el; + if (typeof swiper.params.width !== 'undefined') { + width = swiper.params.width; + } else { + width = $el[0].clientWidth; + } + if (typeof swiper.params.height !== 'undefined') { + height = swiper.params.height; + } else { + height = $el[0].clientHeight; + } + if ((width === 0 && swiper.isHorizontal()) || (height === 0 && swiper.isVertical())) { + return; + } + + // Subtract paddings + width = width - parseInt($el.css('padding-left'), 10) - parseInt($el.css('padding-right'), 10); + height = height - parseInt($el.css('padding-top'), 10) - parseInt($el.css('padding-bottom'), 10); + + Utils.extend(swiper, { + width, + height, + size: swiper.isHorizontal() ? width : height, + }); +} + +function updateSlides () { + const swiper = this; + const params = swiper.params; + + const { + $wrapperEl, size: swiperSize, rtlTranslate: rtl, wrongRTL, + } = swiper; + const isVirtual = swiper.virtual && params.virtual.enabled; + const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length; + const slides = $wrapperEl.children(`.${swiper.params.slideClass}`); + const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length; + let snapGrid = []; + const slidesGrid = []; + const slidesSizesGrid = []; + + let offsetBefore = params.slidesOffsetBefore; + if (typeof offsetBefore === 'function') { + offsetBefore = params.slidesOffsetBefore.call(swiper); + } + + let offsetAfter = params.slidesOffsetAfter; + if (typeof offsetAfter === 'function') { + offsetAfter = params.slidesOffsetAfter.call(swiper); + } + + const previousSnapGridLength = swiper.snapGrid.length; + const previousSlidesGridLength = swiper.snapGrid.length; + + let spaceBetween = params.spaceBetween; + let slidePosition = -offsetBefore; + let prevSlideSize = 0; + let index = 0; + if (typeof swiperSize === 'undefined') { + return; + } + if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { + spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiperSize; + } + + swiper.virtualSize = -spaceBetween; + + // reset margins + if (rtl) slides.css({ marginLeft: '', marginTop: '' }); + else slides.css({ marginRight: '', marginBottom: '' }); + + let slidesNumberEvenToRows; + if (params.slidesPerColumn > 1) { + if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) { + slidesNumberEvenToRows = slidesLength; + } else { + slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn; + } + if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') { + slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, params.slidesPerView * params.slidesPerColumn); + } + } + + // Calc slides + let slideSize; + const slidesPerColumn = params.slidesPerColumn; + const slidesPerRow = slidesNumberEvenToRows / slidesPerColumn; + const numFullColumns = Math.floor(slidesLength / params.slidesPerColumn); + for (let i = 0; i < slidesLength; i += 1) { + slideSize = 0; + const slide = slides.eq(i); + if (params.slidesPerColumn > 1) { + // Set slides order + let newSlideOrderIndex; + let column; + let row; + if (params.slidesPerColumnFill === 'column') { + column = Math.floor(i / slidesPerColumn); + row = i - (column * slidesPerColumn); + if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) { + row += 1; + if (row >= slidesPerColumn) { + row = 0; + column += 1; + } + } + newSlideOrderIndex = column + ((row * slidesNumberEvenToRows) / slidesPerColumn); + slide + .css({ + '-webkit-box-ordinal-group': newSlideOrderIndex, + '-moz-box-ordinal-group': newSlideOrderIndex, + '-ms-flex-order': newSlideOrderIndex, + '-webkit-order': newSlideOrderIndex, + order: newSlideOrderIndex, + }); + } else { + row = Math.floor(i / slidesPerRow); + column = i - (row * slidesPerRow); + } + slide + .css( + `margin-${swiper.isHorizontal() ? 'top' : 'left'}`, + (row !== 0 && params.spaceBetween) && (`${params.spaceBetween}px`) + ) + .attr('data-swiper-column', column) + .attr('data-swiper-row', row); + } + if (slide.css('display') === 'none') continue; // eslint-disable-line + + if (params.slidesPerView === 'auto') { + const slideStyles = window.getComputedStyle(slide[0], null); + const currentTransform = slide[0].style.transform; + const currentWebKitTransform = slide[0].style.webkitTransform; + if (currentTransform) { + slide[0].style.transform = 'none'; + } + if (currentWebKitTransform) { + slide[0].style.webkitTransform = 'none'; + } + if (params.roundLengths) { + slideSize = swiper.isHorizontal() + ? slide.outerWidth(true) + : slide.outerHeight(true); + } else { + // eslint-disable-next-line + if (swiper.isHorizontal()) { + const width = parseFloat(slideStyles.getPropertyValue('width')); + const paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left')); + const paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right')); + const marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left')); + const marginRight = parseFloat(slideStyles.getPropertyValue('margin-right')); + const boxSizing = slideStyles.getPropertyValue('box-sizing'); + if (boxSizing && boxSizing === 'border-box') { + slideSize = width + marginLeft + marginRight; + } else { + slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight; + } + } else { + const height = parseFloat(slideStyles.getPropertyValue('height')); + const paddingTop = parseFloat(slideStyles.getPropertyValue('padding-top')); + const paddingBottom = parseFloat(slideStyles.getPropertyValue('padding-bottom')); + const marginTop = parseFloat(slideStyles.getPropertyValue('margin-top')); + const marginBottom = parseFloat(slideStyles.getPropertyValue('margin-bottom')); + const boxSizing = slideStyles.getPropertyValue('box-sizing'); + if (boxSizing && boxSizing === 'border-box') { + slideSize = height + marginTop + marginBottom; + } else { + slideSize = height + paddingTop + paddingBottom + marginTop + marginBottom; + } + } + } + if (currentTransform) { + slide[0].style.transform = currentTransform; + } + if (currentWebKitTransform) { + slide[0].style.webkitTransform = currentWebKitTransform; + } + if (params.roundLengths) slideSize = Math.floor(slideSize); + } else { + slideSize = (swiperSize - ((params.slidesPerView - 1) * spaceBetween)) / params.slidesPerView; + if (params.roundLengths) slideSize = Math.floor(slideSize); + + if (slides[i]) { + if (swiper.isHorizontal()) { + slides[i].style.width = `${slideSize}px`; + } else { + slides[i].style.height = `${slideSize}px`; + } + } + } + if (slides[i]) { + slides[i].swiperSlideSize = slideSize; + } + slidesSizesGrid.push(slideSize); + + + if (params.centeredSlides) { + slidePosition = slidePosition + (slideSize / 2) + (prevSlideSize / 2) + spaceBetween; + if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; + if (i === 0) slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; + if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0; + if (params.roundLengths) slidePosition = Math.floor(slidePosition); + if ((index) % params.slidesPerGroup === 0) snapGrid.push(slidePosition); + slidesGrid.push(slidePosition); + } else { + if (params.roundLengths) slidePosition = Math.floor(slidePosition); + if ((index) % params.slidesPerGroup === 0) snapGrid.push(slidePosition); + slidesGrid.push(slidePosition); + slidePosition = slidePosition + slideSize + spaceBetween; + } + + swiper.virtualSize += slideSize + spaceBetween; + + prevSlideSize = slideSize; + + index += 1; + } + swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter; + let newSlidesGrid; + + if ( + rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) { + $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); + } + if (!Support.flexbox || params.setWrapperSize) { + if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); + else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` }); + } + + if (params.slidesPerColumn > 1) { + swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumberEvenToRows; + swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween; + if (swiper.isHorizontal()) $wrapperEl.css({ width: `${swiper.virtualSize + params.spaceBetween}px` }); + else $wrapperEl.css({ height: `${swiper.virtualSize + params.spaceBetween}px` }); + if (params.centeredSlides) { + newSlidesGrid = []; + for (let i = 0; i < snapGrid.length; i += 1) { + let slidesGridItem = snapGrid[i]; + if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); + if (snapGrid[i] < swiper.virtualSize + snapGrid[0]) newSlidesGrid.push(slidesGridItem); + } + snapGrid = newSlidesGrid; + } + } + + // Remove last grid elements depending on width + if (!params.centeredSlides) { + newSlidesGrid = []; + for (let i = 0; i < snapGrid.length; i += 1) { + let slidesGridItem = snapGrid[i]; + if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem); + if (snapGrid[i] <= swiper.virtualSize - swiperSize) { + newSlidesGrid.push(slidesGridItem); + } + } + snapGrid = newSlidesGrid; + if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) { + snapGrid.push(swiper.virtualSize - swiperSize); + } + } + if (snapGrid.length === 0) snapGrid = [0]; + + if (params.spaceBetween !== 0) { + if (swiper.isHorizontal()) { + if (rtl) slides.css({ marginLeft: `${spaceBetween}px` }); + else slides.css({ marginRight: `${spaceBetween}px` }); + } else slides.css({ marginBottom: `${spaceBetween}px` }); + } + + if (params.centerInsufficientSlides) { + let allSlidesSize = 0; + slidesSizesGrid.forEach((slideSizeValue) => { + allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0); + }); + allSlidesSize -= params.spaceBetween; + if (allSlidesSize < swiperSize) { + const allSlidesOffset = (swiperSize - allSlidesSize) / 2; + snapGrid.forEach((snap, snapIndex) => { + snapGrid[snapIndex] = snap - allSlidesOffset; + }); + slidesGrid.forEach((snap, snapIndex) => { + slidesGrid[snapIndex] = snap + allSlidesOffset; + }); + } + } + + Utils.extend(swiper, { + slides, + snapGrid, + slidesGrid, + slidesSizesGrid, + }); + + if (slidesLength !== previousSlidesLength) { + swiper.emit('slidesLengthChange'); + } + if (snapGrid.length !== previousSnapGridLength) { + if (swiper.params.watchOverflow) swiper.checkOverflow(); + swiper.emit('snapGridLengthChange'); + } + if (slidesGrid.length !== previousSlidesGridLength) { + swiper.emit('slidesGridLengthChange'); + } + + if (params.watchSlidesProgress || params.watchSlidesVisibility) { + swiper.updateSlidesOffset(); + } +} + +function updateAutoHeight (speed) { + const swiper = this; + const activeSlides = []; + let newHeight = 0; + let i; + if (typeof speed === 'number') { + swiper.setTransition(speed); + } else if (speed === true) { + swiper.setTransition(swiper.params.speed); + } + // Find slides currently in view + if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) { + for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) { + const index = swiper.activeIndex + i; + if (index > swiper.slides.length) break; + activeSlides.push(swiper.slides.eq(index)[0]); + } + } else { + activeSlides.push(swiper.slides.eq(swiper.activeIndex)[0]); + } + + // Find new height from highest slide in view + for (i = 0; i < activeSlides.length; i += 1) { + if (typeof activeSlides[i] !== 'undefined') { + const height = activeSlides[i].offsetHeight; + newHeight = height > newHeight ? height : newHeight; + } + } + + // Update Height + if (newHeight) swiper.$wrapperEl.css('height', `${newHeight}px`); +} + +function updateSlidesOffset () { + const swiper = this; + const slides = swiper.slides; + for (let i = 0; i < slides.length; i += 1) { + slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop; + } +} + +function updateSlidesProgress (translate = (this && this.translate) || 0) { + const swiper = this; + const params = swiper.params; + + const { slides, rtlTranslate: rtl } = swiper; + + if (slides.length === 0) return; + if (typeof slides[0].swiperSlideOffset === 'undefined') swiper.updateSlidesOffset(); + + let offsetCenter = -translate; + if (rtl) offsetCenter = translate; + + // Visible Slides + slides.removeClass(params.slideVisibleClass); + + swiper.visibleSlidesIndexes = []; + swiper.visibleSlides = []; + + for (let i = 0; i < slides.length; i += 1) { + const slide = slides[i]; + const slideProgress = ( + (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0)) - slide.swiperSlideOffset + ) / (slide.swiperSlideSize + params.spaceBetween); + if (params.watchSlidesVisibility) { + const slideBefore = -(offsetCenter - slide.swiperSlideOffset); + const slideAfter = slideBefore + swiper.slidesSizesGrid[i]; + const isVisible = (slideBefore >= 0 && slideBefore < swiper.size) + || (slideAfter > 0 && slideAfter <= swiper.size) + || (slideBefore <= 0 && slideAfter >= swiper.size); + if (isVisible) { + swiper.visibleSlides.push(slide); + swiper.visibleSlidesIndexes.push(i); + slides.eq(i).addClass(params.slideVisibleClass); + } + } + slide.progress = rtl ? -slideProgress : slideProgress; + } + swiper.visibleSlides = $(swiper.visibleSlides); +} + +function updateProgress (translate = (this && this.translate) || 0) { + const swiper = this; + const params = swiper.params; + + const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); + let { progress, isBeginning, isEnd } = swiper; + const wasBeginning = isBeginning; + const wasEnd = isEnd; + if (translatesDiff === 0) { + progress = 0; + isBeginning = true; + isEnd = true; + } else { + progress = (translate - swiper.minTranslate()) / (translatesDiff); + isBeginning = progress <= 0; + isEnd = progress >= 1; + } + Utils.extend(swiper, { + progress, + isBeginning, + isEnd, + }); + + if (params.watchSlidesProgress || params.watchSlidesVisibility) swiper.updateSlidesProgress(translate); + + if (isBeginning && !wasBeginning) { + swiper.emit('reachBeginning toEdge'); + } + if (isEnd && !wasEnd) { + swiper.emit('reachEnd toEdge'); + } + if ((wasBeginning && !isBeginning) || (wasEnd && !isEnd)) { + swiper.emit('fromEdge'); + } + + swiper.emit('progress', progress); +} + +function updateSlidesClasses () { + const swiper = this; + + const { + slides, params, $wrapperEl, activeIndex, realIndex, + } = swiper; + const isVirtual = swiper.virtual && params.virtual.enabled; + + slides.removeClass(`${params.slideActiveClass} ${params.slideNextClass} ${params.slidePrevClass} ${params.slideDuplicateActiveClass} ${params.slideDuplicateNextClass} ${params.slideDuplicatePrevClass}`); + + let activeSlide; + if (isVirtual) { + activeSlide = swiper.$wrapperEl.find(`.${params.slideClass}[data-swiper-slide-index="${activeIndex}"]`); + } else { + activeSlide = slides.eq(activeIndex); + } + + // Active classes + activeSlide.addClass(params.slideActiveClass); + + if (params.loop) { + // Duplicate to all looped slides + if (activeSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${realIndex}"]`) + .addClass(params.slideDuplicateActiveClass); + } else { + $wrapperEl + .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${realIndex}"]`) + .addClass(params.slideDuplicateActiveClass); + } + } + // Next Slide + let nextSlide = activeSlide.nextAll(`.${params.slideClass}`).eq(0).addClass(params.slideNextClass); + if (params.loop && nextSlide.length === 0) { + nextSlide = slides.eq(0); + nextSlide.addClass(params.slideNextClass); + } + // Prev Slide + let prevSlide = activeSlide.prevAll(`.${params.slideClass}`).eq(0).addClass(params.slidePrevClass); + if (params.loop && prevSlide.length === 0) { + prevSlide = slides.eq(-1); + prevSlide.addClass(params.slidePrevClass); + } + if (params.loop) { + // Duplicate to all looped slides + if (nextSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicateNextClass); + } else { + $wrapperEl + .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${nextSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicateNextClass); + } + if (prevSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(`.${params.slideClass}:not(.${params.slideDuplicateClass})[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicatePrevClass); + } else { + $wrapperEl + .children(`.${params.slideClass}.${params.slideDuplicateClass}[data-swiper-slide-index="${prevSlide.attr('data-swiper-slide-index')}"]`) + .addClass(params.slideDuplicatePrevClass); + } + } +} + +function updateActiveIndex (newActiveIndex) { + const swiper = this; + const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; + const { + slidesGrid, snapGrid, params, activeIndex: previousIndex, realIndex: previousRealIndex, snapIndex: previousSnapIndex, + } = swiper; + let activeIndex = newActiveIndex; + let snapIndex; + if (typeof activeIndex === 'undefined') { + for (let i = 0; i < slidesGrid.length; i += 1) { + if (typeof slidesGrid[i + 1] !== 'undefined') { + if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - ((slidesGrid[i + 1] - slidesGrid[i]) / 2)) { + activeIndex = i; + } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) { + activeIndex = i + 1; + } + } else if (translate >= slidesGrid[i]) { + activeIndex = i; + } + } + // Normalize slideIndex + if (params.normalizeSlideIndex) { + if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0; + } + } + if (snapGrid.indexOf(translate) >= 0) { + snapIndex = snapGrid.indexOf(translate); + } else { + snapIndex = Math.floor(activeIndex / params.slidesPerGroup); + } + if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; + if (activeIndex === previousIndex) { + if (snapIndex !== previousSnapIndex) { + swiper.snapIndex = snapIndex; + swiper.emit('snapIndexChange'); + } + return; + } + + // Get real index + const realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10); + + Utils.extend(swiper, { + snapIndex, + realIndex, + previousIndex, + activeIndex, + }); + swiper.emit('activeIndexChange'); + swiper.emit('snapIndexChange'); + if (previousRealIndex !== realIndex) { + swiper.emit('realIndexChange'); + } + swiper.emit('slideChange'); +} + +function updateClickedSlide (e) { + const swiper = this; + const params = swiper.params; + const slide = $(e.target).closest(`.${params.slideClass}`)[0]; + let slideFound = false; + if (slide) { + for (let i = 0; i < swiper.slides.length; i += 1) { + if (swiper.slides[i] === slide) slideFound = true; + } + } + + if (slide && slideFound) { + swiper.clickedSlide = slide; + if (swiper.virtual && swiper.params.virtual.enabled) { + swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10); + } else { + swiper.clickedIndex = $(slide).index(); + } + } else { + swiper.clickedSlide = undefined; + swiper.clickedIndex = undefined; + return; + } + if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) { + swiper.slideToClickedSlide(); + } +} + +var update = { + updateSize, + updateSlides, + updateAutoHeight, + updateSlidesOffset, + updateSlidesProgress, + updateProgress, + updateSlidesClasses, + updateActiveIndex, + updateClickedSlide, +}; + +function getTranslate (axis = this.isHorizontal() ? 'x' : 'y') { + const swiper = this; + + const { + params, rtlTranslate: rtl, translate, $wrapperEl, + } = swiper; + + if (params.virtualTranslate) { + return rtl ? -translate : translate; + } + + let currentTranslate = Utils.getTranslate($wrapperEl[0], axis); + if (rtl) currentTranslate = -currentTranslate; + + return currentTranslate || 0; +} + +function setTranslate (translate, byController) { + const swiper = this; + const { + rtlTranslate: rtl, params, $wrapperEl, progress, + } = swiper; + let x = 0; + let y = 0; + const z = 0; + + if (swiper.isHorizontal()) { + x = rtl ? -translate : translate; + } else { + y = translate; + } + + if (params.roundLengths) { + x = Math.floor(x); + y = Math.floor(y); + } + + if (!params.virtualTranslate) { + if (Support.transforms3d) $wrapperEl.transform(`translate3d(${x}px, ${y}px, ${z}px)`); + else $wrapperEl.transform(`translate(${x}px, ${y}px)`); + } + swiper.previousTranslate = swiper.translate; + swiper.translate = swiper.isHorizontal() ? x : y; + + // Check if we need to update progress + let newProgress; + const translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); + if (translatesDiff === 0) { + newProgress = 0; + } else { + newProgress = (translate - swiper.minTranslate()) / (translatesDiff); + } + if (newProgress !== progress) { + swiper.updateProgress(translate); + } + + swiper.emit('setTranslate', swiper.translate, byController); +} + +function minTranslate () { + return (-this.snapGrid[0]); +} + +function maxTranslate () { + return (-this.snapGrid[this.snapGrid.length - 1]); +} + +var translate = { + getTranslate, + setTranslate, + minTranslate, + maxTranslate, +}; + +function setTransition (duration, byController) { + const swiper = this; + + swiper.$wrapperEl.transition(duration); + + swiper.emit('setTransition', duration, byController); +} + +function transitionStart (runCallbacks = true, direction) { + const swiper = this; + const { activeIndex, params, previousIndex } = swiper; + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + + let dir = direction; + if (!dir) { + if (activeIndex > previousIndex) dir = 'next'; + else if (activeIndex < previousIndex) dir = 'prev'; + else dir = 'reset'; + } + + swiper.emit('transitionStart'); + + if (runCallbacks && activeIndex !== previousIndex) { + if (dir === 'reset') { + swiper.emit('slideResetTransitionStart'); + return; + } + swiper.emit('slideChangeTransitionStart'); + if (dir === 'next') { + swiper.emit('slideNextTransitionStart'); + } else { + swiper.emit('slidePrevTransitionStart'); + } + } +} + +function transitionEnd (runCallbacks = true, direction) { + const swiper = this; + const { activeIndex, previousIndex } = swiper; + swiper.animating = false; + swiper.setTransition(0); + + let dir = direction; + if (!dir) { + if (activeIndex > previousIndex) dir = 'next'; + else if (activeIndex < previousIndex) dir = 'prev'; + else dir = 'reset'; + } + + swiper.emit('transitionEnd'); + + if (runCallbacks && activeIndex !== previousIndex) { + if (dir === 'reset') { + swiper.emit('slideResetTransitionEnd'); + return; + } + swiper.emit('slideChangeTransitionEnd'); + if (dir === 'next') { + swiper.emit('slideNextTransitionEnd'); + } else { + swiper.emit('slidePrevTransitionEnd'); + } + } +} + +var transition = { + setTransition, + transitionStart, + transitionEnd, +}; + +function slideTo (index = 0, speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + let slideIndex = index; + if (slideIndex < 0) slideIndex = 0; + + const { + params, snapGrid, slidesGrid, previousIndex, activeIndex, rtlTranslate: rtl, + } = swiper; + if (swiper.animating && params.preventInteractionOnTransition) { + return false; + } + + let snapIndex = Math.floor(slideIndex / params.slidesPerGroup); + if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1; + + if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) { + swiper.emit('beforeSlideChangeStart'); + } + + const translate = -snapGrid[snapIndex]; + + // Update progress + swiper.updateProgress(translate); + + // Normalize slideIndex + if (params.normalizeSlideIndex) { + for (let i = 0; i < slidesGrid.length; i += 1) { + if (-Math.floor(translate * 100) >= Math.floor(slidesGrid[i] * 100)) { + slideIndex = i; + } + } + } + // Directions locks + if (swiper.initialized && slideIndex !== activeIndex) { + if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) { + return false; + } + if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) { + if ((activeIndex || 0) !== slideIndex) return false; + } + } + + let direction; + if (slideIndex > activeIndex) direction = 'next'; + else if (slideIndex < activeIndex) direction = 'prev'; + else direction = 'reset'; + + + // Update Index + if ((rtl && -translate === swiper.translate) || (!rtl && translate === swiper.translate)) { + swiper.updateActiveIndex(slideIndex); + // Update Height + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + swiper.updateSlidesClasses(); + if (params.effect !== 'slide') { + swiper.setTranslate(translate); + } + if (direction !== 'reset') { + swiper.transitionStart(runCallbacks, direction); + swiper.transitionEnd(runCallbacks, direction); + } + return false; + } + + if (speed === 0 || !Support.transition) { + swiper.setTransition(0); + swiper.setTranslate(translate); + swiper.updateActiveIndex(slideIndex); + swiper.updateSlidesClasses(); + swiper.emit('beforeTransitionStart', speed, internal); + swiper.transitionStart(runCallbacks, direction); + swiper.transitionEnd(runCallbacks, direction); + } else { + swiper.setTransition(speed); + swiper.setTranslate(translate); + swiper.updateActiveIndex(slideIndex); + swiper.updateSlidesClasses(); + swiper.emit('beforeTransitionStart', speed, internal); + swiper.transitionStart(runCallbacks, direction); + if (!swiper.animating) { + swiper.animating = true; + if (!swiper.onSlideToWrapperTransitionEnd) { + swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) { + if (!swiper || swiper.destroyed) return; + if (e.target !== this) return; + swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); + swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); + swiper.onSlideToWrapperTransitionEnd = null; + delete swiper.onSlideToWrapperTransitionEnd; + swiper.transitionEnd(runCallbacks, direction); + }; + } + swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); + swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); + } + } + + return true; +} + +function slideToLoop (index = 0, speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + let newIndex = index; + if (swiper.params.loop) { + newIndex += swiper.loopedSlides; + } + + return swiper.slideTo(newIndex, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slideNext (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + const { params, animating } = swiper; + if (params.loop) { + if (animating) return false; + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal); + } + return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slidePrev (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + const { + params, animating, snapGrid, slidesGrid, rtlTranslate, + } = swiper; + + if (params.loop) { + if (animating) return false; + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + } + const translate = rtlTranslate ? swiper.translate : -swiper.translate; + function normalize(val) { + if (val < 0) return -Math.floor(Math.abs(val)); + return Math.floor(val); + } + const normalizedTranslate = normalize(translate); + const normalizedSnapGrid = snapGrid.map(val => normalize(val)); + const normalizedSlidesGrid = slidesGrid.map(val => normalize(val)); + + const currentSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate)]; + const prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1]; + let prevIndex; + if (typeof prevSnap !== 'undefined') { + prevIndex = slidesGrid.indexOf(prevSnap); + if (prevIndex < 0) prevIndex = swiper.activeIndex - 1; + } + return swiper.slideTo(prevIndex, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slideReset (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal); +} + +/* eslint no-unused-vars: "off" */ +function slideToClosest (speed = this.params.speed, runCallbacks = true, internal) { + const swiper = this; + let index = swiper.activeIndex; + const snapIndex = Math.floor(index / swiper.params.slidesPerGroup); + + if (snapIndex < swiper.snapGrid.length - 1) { + const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; + + const currentSnap = swiper.snapGrid[snapIndex]; + const nextSnap = swiper.snapGrid[snapIndex + 1]; + + if ((translate - currentSnap) > (nextSnap - currentSnap) / 2) { + index = swiper.params.slidesPerGroup; + } + } + + return swiper.slideTo(index, speed, runCallbacks, internal); +} + +function slideToClickedSlide () { + const swiper = this; + const { params, $wrapperEl } = swiper; + + const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView; + let slideToIndex = swiper.clickedIndex; + let realIndex; + if (params.loop) { + if (swiper.animating) return; + realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10); + if (params.centeredSlides) { + if ( + (slideToIndex < swiper.loopedSlides - (slidesPerView / 2)) + || (slideToIndex > (swiper.slides.length - swiper.loopedSlides) + (slidesPerView / 2)) + ) { + swiper.loopFix(); + slideToIndex = $wrapperEl + .children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`) + .eq(0) + .index(); + + Utils.nextTick(() => { + swiper.slideTo(slideToIndex); + }); + } else { + swiper.slideTo(slideToIndex); + } + } else if (slideToIndex > swiper.slides.length - slidesPerView) { + swiper.loopFix(); + slideToIndex = $wrapperEl + .children(`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`) + .eq(0) + .index(); + + Utils.nextTick(() => { + swiper.slideTo(slideToIndex); + }); + } else { + swiper.slideTo(slideToIndex); + } + } else { + swiper.slideTo(slideToIndex); + } +} + +var slide = { + slideTo, + slideToLoop, + slideNext, + slidePrev, + slideReset, + slideToClosest, + slideToClickedSlide, +}; + +function loopCreate () { + const swiper = this; + const { params, $wrapperEl } = swiper; + // Remove duplicated slides + $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass}`).remove(); + + let slides = $wrapperEl.children(`.${params.slideClass}`); + + if (params.loopFillGroupWithBlank) { + const blankSlidesNum = params.slidesPerGroup - (slides.length % params.slidesPerGroup); + if (blankSlidesNum !== params.slidesPerGroup) { + for (let i = 0; i < blankSlidesNum; i += 1) { + const blankNode = $(document.createElement('div')).addClass(`${params.slideClass} ${params.slideBlankClass}`); + $wrapperEl.append(blankNode); + } + slides = $wrapperEl.children(`.${params.slideClass}`); + } + } + + if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length; + + swiper.loopedSlides = parseInt(params.loopedSlides || params.slidesPerView, 10); + swiper.loopedSlides += params.loopAdditionalSlides; + if (swiper.loopedSlides > slides.length) { + swiper.loopedSlides = slides.length; + } + + const prependSlides = []; + const appendSlides = []; + slides.each((index, el) => { + const slide = $(el); + if (index < swiper.loopedSlides) appendSlides.push(el); + if (index < slides.length && index >= slides.length - swiper.loopedSlides) prependSlides.push(el); + slide.attr('data-swiper-slide-index', index); + }); + for (let i = 0; i < appendSlides.length; i += 1) { + $wrapperEl.append($(appendSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass)); + } + for (let i = prependSlides.length - 1; i >= 0; i -= 1) { + $wrapperEl.prepend($(prependSlides[i].cloneNode(true)).addClass(params.slideDuplicateClass)); + } +} + +function loopFix () { + const swiper = this; + const { + params, activeIndex, slides, loopedSlides, allowSlidePrev, allowSlideNext, snapGrid, rtlTranslate: rtl, + } = swiper; + let newIndex; + swiper.allowSlidePrev = true; + swiper.allowSlideNext = true; + + const snapTranslate = -snapGrid[activeIndex]; + const diff = snapTranslate - swiper.getTranslate(); + + + // Fix For Negative Oversliding + if (activeIndex < loopedSlides) { + newIndex = (slides.length - (loopedSlides * 3)) + activeIndex; + newIndex += loopedSlides; + const slideChanged = swiper.slideTo(newIndex, 0, false, true); + if (slideChanged && diff !== 0) { + swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); + } + } else if ((params.slidesPerView === 'auto' && activeIndex >= loopedSlides * 2) || (activeIndex >= slides.length - loopedSlides)) { + // Fix For Positive Oversliding + newIndex = -slides.length + activeIndex + loopedSlides; + newIndex += loopedSlides; + const slideChanged = swiper.slideTo(newIndex, 0, false, true); + if (slideChanged && diff !== 0) { + swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); + } + } + swiper.allowSlidePrev = allowSlidePrev; + swiper.allowSlideNext = allowSlideNext; +} + +function loopDestroy () { + const swiper = this; + const { $wrapperEl, params, slides } = swiper; + $wrapperEl.children(`.${params.slideClass}.${params.slideDuplicateClass},.${params.slideClass}.${params.slideBlankClass}`).remove(); + slides.removeAttr('data-swiper-slide-index'); +} + +var loop = { + loopCreate, + loopFix, + loopDestroy, +}; + +function setGrabCursor (moving) { + const swiper = this; + if (Support.touch || !swiper.params.simulateTouch || (swiper.params.watchOverflow && swiper.isLocked)) return; + const el = swiper.el; + el.style.cursor = 'move'; + el.style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab'; + el.style.cursor = moving ? '-moz-grabbin' : '-moz-grab'; + el.style.cursor = moving ? 'grabbing' : 'grab'; +} + +function unsetGrabCursor () { + const swiper = this; + if (Support.touch || (swiper.params.watchOverflow && swiper.isLocked)) return; + swiper.el.style.cursor = ''; +} + +var grabCursor = { + setGrabCursor, + unsetGrabCursor, +}; + +function appendSlide (slides) { + const swiper = this; + const { $wrapperEl, params } = swiper; + if (params.loop) { + swiper.loopDestroy(); + } + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) $wrapperEl.append(slides[i]); + } + } else { + $wrapperEl.append(slides); + } + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } +} + +function prependSlide (slides) { + const swiper = this; + const { params, $wrapperEl, activeIndex } = swiper; + + if (params.loop) { + swiper.loopDestroy(); + } + let newActiveIndex = activeIndex + 1; + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) $wrapperEl.prepend(slides[i]); + } + newActiveIndex = activeIndex + slides.length; + } else { + $wrapperEl.prepend(slides); + } + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } + swiper.slideTo(newActiveIndex, 0, false); +} + +function addSlide (index, slides) { + const swiper = this; + const { $wrapperEl, params, activeIndex } = swiper; + let activeIndexBuffer = activeIndex; + if (params.loop) { + activeIndexBuffer -= swiper.loopedSlides; + swiper.loopDestroy(); + swiper.slides = $wrapperEl.children(`.${params.slideClass}`); + } + const baseLength = swiper.slides.length; + if (index <= 0) { + swiper.prependSlide(slides); + return; + } + if (index >= baseLength) { + swiper.appendSlide(slides); + return; + } + let newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer; + + const slidesBuffer = []; + for (let i = baseLength - 1; i >= index; i -= 1) { + const currentSlide = swiper.slides.eq(i); + currentSlide.remove(); + slidesBuffer.unshift(currentSlide); + } + + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) $wrapperEl.append(slides[i]); + } + newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer; + } else { + $wrapperEl.append(slides); + } + + for (let i = 0; i < slidesBuffer.length; i += 1) { + $wrapperEl.append(slidesBuffer[i]); + } + + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } + if (params.loop) { + swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); + } else { + swiper.slideTo(newActiveIndex, 0, false); + } +} + +function removeSlide (slidesIndexes) { + const swiper = this; + const { params, $wrapperEl, activeIndex } = swiper; + + let activeIndexBuffer = activeIndex; + if (params.loop) { + activeIndexBuffer -= swiper.loopedSlides; + swiper.loopDestroy(); + swiper.slides = $wrapperEl.children(`.${params.slideClass}`); + } + let newActiveIndex = activeIndexBuffer; + let indexToRemove; + + if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) { + for (let i = 0; i < slidesIndexes.length; i += 1) { + indexToRemove = slidesIndexes[i]; + if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove(); + if (indexToRemove < newActiveIndex) newActiveIndex -= 1; + } + newActiveIndex = Math.max(newActiveIndex, 0); + } else { + indexToRemove = slidesIndexes; + if (swiper.slides[indexToRemove]) swiper.slides.eq(indexToRemove).remove(); + if (indexToRemove < newActiveIndex) newActiveIndex -= 1; + newActiveIndex = Math.max(newActiveIndex, 0); + } + + if (params.loop) { + swiper.loopCreate(); + } + + if (!(params.observer && Support.observer)) { + swiper.update(); + } + if (params.loop) { + swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); + } else { + swiper.slideTo(newActiveIndex, 0, false); + } +} + +function removeAllSlides () { + const swiper = this; + + const slidesIndexes = []; + for (let i = 0; i < swiper.slides.length; i += 1) { + slidesIndexes.push(i); + } + swiper.removeSlide(slidesIndexes); +} + +var manipulation = { + appendSlide, + prependSlide, + addSlide, + removeSlide, + removeAllSlides, +}; + +const Device = (function Device() { + const ua = window.navigator.userAgent; + + const device = { + ios: false, + android: false, + androidChrome: false, + desktop: false, + windows: false, + iphone: false, + ipod: false, + ipad: false, + cordova: window.cordova || window.phonegap, + phonegap: window.cordova || window.phonegap, + }; + + const windows = ua.match(/(Windows Phone);?[\s\/]+([\d.]+)?/); // eslint-disable-line + const android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line + const ipad = ua.match(/(iPad).*OS\s([\d_]+)/); + const ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); + const iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/); + + + // Windows + if (windows) { + device.os = 'windows'; + device.osVersion = windows[2]; + device.windows = true; + } + // Android + if (android && !windows) { + device.os = 'android'; + device.osVersion = android[2]; + device.android = true; + device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0; + } + if (ipad || iphone || ipod) { + device.os = 'ios'; + device.ios = true; + } + // iOS + if (iphone && !ipod) { + device.osVersion = iphone[2].replace(/_/g, '.'); + device.iphone = true; + } + if (ipad) { + device.osVersion = ipad[2].replace(/_/g, '.'); + device.ipad = true; + } + if (ipod) { + device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null; + device.iphone = true; + } + // iOS 8+ changed UA + if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) { + if (device.osVersion.split('.')[0] === '10') { + device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0]; + } + } + + // Desktop + device.desktop = !(device.os || device.android || device.webView); + + // Webview + device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i); + + // Minimal UI + if (device.os && device.os === 'ios') { + const osVersionArr = device.osVersion.split('.'); + const metaViewport = document.querySelector('meta[name="viewport"]'); + device.minimalUi = !device.webView + && (ipod || iphone) + && (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7) + && metaViewport && metaViewport.getAttribute('content').indexOf('minimal-ui') >= 0; + } + + // Pixel Ratio + device.pixelRatio = window.devicePixelRatio || 1; + + // Export object + return device; +}()); + +function onTouchStart (event) { + const swiper = this; + const data = swiper.touchEventsData; + const { params, touches } = swiper; + if (swiper.animating && params.preventInteractionOnTransition) { + return; + } + let e = event; + if (e.originalEvent) e = e.originalEvent; + data.isTouchEvent = e.type === 'touchstart'; + if (!data.isTouchEvent && 'which' in e && e.which === 3) return; + if (!data.isTouchEvent && 'button' in e && e.button > 0) return; + if (data.isTouched && data.isMoved) return; + if (params.noSwiping && $(e.target).closest(params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`)[0]) { + swiper.allowClick = true; + return; + } + if (params.swipeHandler) { + if (!$(e).closest(params.swipeHandler)[0]) return; + } + + touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; + touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; + const startX = touches.currentX; + const startY = touches.currentY; + + // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore + + const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection; + const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold; + if ( + edgeSwipeDetection + && ((startX <= edgeSwipeThreshold) + || (startX >= window.screen.width - edgeSwipeThreshold)) + ) { + return; + } + + Utils.extend(data, { + isTouched: true, + isMoved: false, + allowTouchCallbacks: true, + isScrolling: undefined, + startMoving: undefined, + }); + + touches.startX = startX; + touches.startY = startY; + data.touchStartTime = Utils.now(); + swiper.allowClick = true; + swiper.updateSize(); + swiper.swipeDirection = undefined; + if (params.threshold > 0) data.allowThresholdMove = false; + if (e.type !== 'touchstart') { + let preventDefault = true; + if ($(e.target).is(data.formElements)) preventDefault = false; + if ( + document.activeElement + && $(document.activeElement).is(data.formElements) + && document.activeElement !== e.target + ) { + document.activeElement.blur(); + } + + const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault; + if (params.touchStartForcePreventDefault || shouldPreventDefault) { + e.preventDefault(); + } + } + swiper.emit('touchStart', e); +} + +function onTouchMove (event) { + const swiper = this; + const data = swiper.touchEventsData; + const { params, touches, rtlTranslate: rtl } = swiper; + let e = event; + if (e.originalEvent) e = e.originalEvent; + if (!data.isTouched) { + if (data.startMoving && data.isScrolling) { + swiper.emit('touchMoveOpposite', e); + } + return; + } + if (data.isTouchEvent && e.type === 'mousemove') return; + const pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; + const pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; + if (e.preventedByNestedSwiper) { + touches.startX = pageX; + touches.startY = pageY; + return; + } + if (!swiper.allowTouchMove) { + // isMoved = true; + swiper.allowClick = false; + if (data.isTouched) { + Utils.extend(touches, { + startX: pageX, + startY: pageY, + currentX: pageX, + currentY: pageY, + }); + data.touchStartTime = Utils.now(); + } + return; + } + if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) { + if (swiper.isVertical()) { + // Vertical + if ( + (pageY < touches.startY && swiper.translate <= swiper.maxTranslate()) + || (pageY > touches.startY && swiper.translate >= swiper.minTranslate()) + ) { + data.isTouched = false; + data.isMoved = false; + return; + } + } else if ( + (pageX < touches.startX && swiper.translate <= swiper.maxTranslate()) + || (pageX > touches.startX && swiper.translate >= swiper.minTranslate()) + ) { + return; + } + } + if (data.isTouchEvent && document.activeElement) { + if (e.target === document.activeElement && $(e.target).is(data.formElements)) { + data.isMoved = true; + swiper.allowClick = false; + return; + } + } + if (data.allowTouchCallbacks) { + swiper.emit('touchMove', e); + } + if (e.targetTouches && e.targetTouches.length > 1) return; + + touches.currentX = pageX; + touches.currentY = pageY; + + const diffX = touches.currentX - touches.startX; + const diffY = touches.currentY - touches.startY; + if (swiper.params.threshold && Math.sqrt((diffX ** 2) + (diffY ** 2)) < swiper.params.threshold) return; + + if (typeof data.isScrolling === 'undefined') { + let touchAngle; + if ((swiper.isHorizontal() && touches.currentY === touches.startY) || (swiper.isVertical() && touches.currentX === touches.startX)) { + data.isScrolling = false; + } else { + // eslint-disable-next-line + if ((diffX * diffX) + (diffY * diffY) >= 25) { + touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI; + data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : (90 - touchAngle > params.touchAngle); + } + } + } + if (data.isScrolling) { + swiper.emit('touchMoveOpposite', e); + } + if (typeof data.startMoving === 'undefined') { + if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) { + data.startMoving = true; + } + } + if (data.isScrolling) { + data.isTouched = false; + return; + } + if (!data.startMoving) { + return; + } + swiper.allowClick = false; + e.preventDefault(); + if (params.touchMoveStopPropagation && !params.nested) { + e.stopPropagation(); + } + + if (!data.isMoved) { + if (params.loop) { + swiper.loopFix(); + } + data.startTranslate = swiper.getTranslate(); + swiper.setTransition(0); + if (swiper.animating) { + swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend'); + } + data.allowMomentumBounce = false; + // Grab Cursor + if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { + swiper.setGrabCursor(true); + } + swiper.emit('sliderFirstMove', e); + } + swiper.emit('sliderMove', e); + data.isMoved = true; + + let diff = swiper.isHorizontal() ? diffX : diffY; + touches.diff = diff; + + diff *= params.touchRatio; + if (rtl) diff = -diff; + + swiper.swipeDirection = diff > 0 ? 'prev' : 'next'; + data.currentTranslate = diff + data.startTranslate; + + let disableParentSwiper = true; + let resistanceRatio = params.resistanceRatio; + if (params.touchReleaseOnEdges) { + resistanceRatio = 0; + } + if ((diff > 0 && data.currentTranslate > swiper.minTranslate())) { + disableParentSwiper = false; + if (params.resistance) data.currentTranslate = (swiper.minTranslate() - 1) + ((-swiper.minTranslate() + data.startTranslate + diff) ** resistanceRatio); + } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) { + disableParentSwiper = false; + if (params.resistance) data.currentTranslate = (swiper.maxTranslate() + 1) - ((swiper.maxTranslate() - data.startTranslate - diff) ** resistanceRatio); + } + + if (disableParentSwiper) { + e.preventedByNestedSwiper = true; + } + + // Directions locks + if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) { + data.currentTranslate = data.startTranslate; + } + if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) { + data.currentTranslate = data.startTranslate; + } + + + // Threshold + if (params.threshold > 0) { + if (Math.abs(diff) > params.threshold || data.allowThresholdMove) { + if (!data.allowThresholdMove) { + data.allowThresholdMove = true; + touches.startX = touches.currentX; + touches.startY = touches.currentY; + data.currentTranslate = data.startTranslate; + touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY; + return; + } + } else { + data.currentTranslate = data.startTranslate; + return; + } + } + + if (!params.followFinger) return; + + // Update active index in free mode + if (params.freeMode || params.watchSlidesProgress || params.watchSlidesVisibility) { + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + if (params.freeMode) { + // Velocity + if (data.velocities.length === 0) { + data.velocities.push({ + position: touches[swiper.isHorizontal() ? 'startX' : 'startY'], + time: data.touchStartTime, + }); + } + data.velocities.push({ + position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'], + time: Utils.now(), + }); + } + // Update progress + swiper.updateProgress(data.currentTranslate); + // Update translate + swiper.setTranslate(data.currentTranslate); +} + +function onTouchEnd (event) { + const swiper = this; + const data = swiper.touchEventsData; + + const { + params, touches, rtlTranslate: rtl, $wrapperEl, slidesGrid, snapGrid, + } = swiper; + let e = event; + if (e.originalEvent) e = e.originalEvent; + if (data.allowTouchCallbacks) { + swiper.emit('touchEnd', e); + } + data.allowTouchCallbacks = false; + if (!data.isTouched) { + if (data.isMoved && params.grabCursor) { + swiper.setGrabCursor(false); + } + data.isMoved = false; + data.startMoving = false; + return; + } + // Return Grab Cursor + if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { + swiper.setGrabCursor(false); + } + + // Time diff + const touchEndTime = Utils.now(); + const timeDiff = touchEndTime - data.touchStartTime; + + // Tap, doubleTap, Click + if (swiper.allowClick) { + swiper.updateClickedSlide(e); + swiper.emit('tap', e); + if (timeDiff < 300 && (touchEndTime - data.lastClickTime) > 300) { + if (data.clickTimeout) clearTimeout(data.clickTimeout); + data.clickTimeout = Utils.nextTick(() => { + if (!swiper || swiper.destroyed) return; + swiper.emit('click', e); + }, 300); + } + if (timeDiff < 300 && (touchEndTime - data.lastClickTime) < 300) { + if (data.clickTimeout) clearTimeout(data.clickTimeout); + swiper.emit('doubleTap', e); + } + } + + data.lastClickTime = Utils.now(); + Utils.nextTick(() => { + if (!swiper.destroyed) swiper.allowClick = true; + }); + + if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) { + data.isTouched = false; + data.isMoved = false; + data.startMoving = false; + return; + } + data.isTouched = false; + data.isMoved = false; + data.startMoving = false; + + let currentPos; + if (params.followFinger) { + currentPos = rtl ? swiper.translate : -swiper.translate; + } else { + currentPos = -data.currentTranslate; + } + + if (params.freeMode) { + if (currentPos < -swiper.minTranslate()) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (currentPos > -swiper.maxTranslate()) { + if (swiper.slides.length < snapGrid.length) { + swiper.slideTo(snapGrid.length - 1); + } else { + swiper.slideTo(swiper.slides.length - 1); + } + return; + } + + if (params.freeModeMomentum) { + if (data.velocities.length > 1) { + const lastMoveEvent = data.velocities.pop(); + const velocityEvent = data.velocities.pop(); + + const distance = lastMoveEvent.position - velocityEvent.position; + const time = lastMoveEvent.time - velocityEvent.time; + swiper.velocity = distance / time; + swiper.velocity /= 2; + if (Math.abs(swiper.velocity) < params.freeModeMinimumVelocity) { + swiper.velocity = 0; + } + // this implies that the user stopped moving a finger then released. + // There would be no events with distance zero, so the last event is stale. + if (time > 150 || (Utils.now() - lastMoveEvent.time) > 300) { + swiper.velocity = 0; + } + } else { + swiper.velocity = 0; + } + swiper.velocity *= params.freeModeMomentumVelocityRatio; + + data.velocities.length = 0; + let momentumDuration = 1000 * params.freeModeMomentumRatio; + const momentumDistance = swiper.velocity * momentumDuration; + + let newPosition = swiper.translate + momentumDistance; + if (rtl) newPosition = -newPosition; + + let doBounce = false; + let afterBouncePosition; + const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeModeMomentumBounceRatio; + let needsLoopFix; + if (newPosition < swiper.maxTranslate()) { + if (params.freeModeMomentumBounce) { + if (newPosition + swiper.maxTranslate() < -bounceAmount) { + newPosition = swiper.maxTranslate() - bounceAmount; + } + afterBouncePosition = swiper.maxTranslate(); + doBounce = true; + data.allowMomentumBounce = true; + } else { + newPosition = swiper.maxTranslate(); + } + if (params.loop && params.centeredSlides) needsLoopFix = true; + } else if (newPosition > swiper.minTranslate()) { + if (params.freeModeMomentumBounce) { + if (newPosition - swiper.minTranslate() > bounceAmount) { + newPosition = swiper.minTranslate() + bounceAmount; + } + afterBouncePosition = swiper.minTranslate(); + doBounce = true; + data.allowMomentumBounce = true; + } else { + newPosition = swiper.minTranslate(); + } + if (params.loop && params.centeredSlides) needsLoopFix = true; + } else if (params.freeModeSticky) { + let nextSlide; + for (let j = 0; j < snapGrid.length; j += 1) { + if (snapGrid[j] > -newPosition) { + nextSlide = j; + break; + } + } + + if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') { + newPosition = snapGrid[nextSlide]; + } else { + newPosition = snapGrid[nextSlide - 1]; + } + newPosition = -newPosition; + } + if (needsLoopFix) { + swiper.once('transitionEnd', () => { + swiper.loopFix(); + }); + } + // Fix duration + if (swiper.velocity !== 0) { + if (rtl) { + momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity); + } else { + momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity); + } + } else if (params.freeModeSticky) { + swiper.slideToClosest(); + return; + } + + if (params.freeModeMomentumBounce && doBounce) { + swiper.updateProgress(afterBouncePosition); + swiper.setTransition(momentumDuration); + swiper.setTranslate(newPosition); + swiper.transitionStart(true, swiper.swipeDirection); + swiper.animating = true; + $wrapperEl.transitionEnd(() => { + if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return; + swiper.emit('momentumBounce'); + + swiper.setTransition(params.speed); + swiper.setTranslate(afterBouncePosition); + $wrapperEl.transitionEnd(() => { + if (!swiper || swiper.destroyed) return; + swiper.transitionEnd(); + }); + }); + } else if (swiper.velocity) { + swiper.updateProgress(newPosition); + swiper.setTransition(momentumDuration); + swiper.setTranslate(newPosition); + swiper.transitionStart(true, swiper.swipeDirection); + if (!swiper.animating) { + swiper.animating = true; + $wrapperEl.transitionEnd(() => { + if (!swiper || swiper.destroyed) return; + swiper.transitionEnd(); + }); + } + } else { + swiper.updateProgress(newPosition); + } + + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } else if (params.freeModeSticky) { + swiper.slideToClosest(); + return; + } + + if (!params.freeModeMomentum || timeDiff >= params.longSwipesMs) { + swiper.updateProgress(); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + return; + } + + // Find current slide + let stopIndex = 0; + let groupSize = swiper.slidesSizesGrid[0]; + for (let i = 0; i < slidesGrid.length; i += params.slidesPerGroup) { + if (typeof slidesGrid[i + params.slidesPerGroup] !== 'undefined') { + if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + params.slidesPerGroup]) { + stopIndex = i; + groupSize = slidesGrid[i + params.slidesPerGroup] - slidesGrid[i]; + } + } else if (currentPos >= slidesGrid[i]) { + stopIndex = i; + groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2]; + } + } + + // Find current slide size + const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize; + + if (timeDiff > params.longSwipesMs) { + // Long touches + if (!params.longSwipes) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (swiper.swipeDirection === 'next') { + if (ratio >= params.longSwipesRatio) swiper.slideTo(stopIndex + params.slidesPerGroup); + else swiper.slideTo(stopIndex); + } + if (swiper.swipeDirection === 'prev') { + if (ratio > (1 - params.longSwipesRatio)) swiper.slideTo(stopIndex + params.slidesPerGroup); + else swiper.slideTo(stopIndex); + } + } else { + // Short swipes + if (!params.shortSwipes) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (swiper.swipeDirection === 'next') { + swiper.slideTo(stopIndex + params.slidesPerGroup); + } + if (swiper.swipeDirection === 'prev') { + swiper.slideTo(stopIndex); + } + } +} + +function onResize () { + const swiper = this; + + const { params, el } = swiper; + + if (el && el.offsetWidth === 0) return; + + // Breakpoints + if (params.breakpoints) { + swiper.setBreakpoint(); + } + + // Save locks + const { allowSlideNext, allowSlidePrev, snapGrid } = swiper; + + // Disable locks on resize + swiper.allowSlideNext = true; + swiper.allowSlidePrev = true; + + swiper.updateSize(); + swiper.updateSlides(); + + if (params.freeMode) { + const newTranslate = Math.min(Math.max(swiper.translate, swiper.maxTranslate()), swiper.minTranslate()); + swiper.setTranslate(newTranslate); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + } else { + swiper.updateSlidesClasses(); + if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) { + swiper.slideTo(swiper.slides.length - 1, 0, false, true); + } else { + swiper.slideTo(swiper.activeIndex, 0, false, true); + } + } + // Return locks after resize + swiper.allowSlidePrev = allowSlidePrev; + swiper.allowSlideNext = allowSlideNext; + + if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) { + swiper.checkOverflow(); + } +} + +function onClick (e) { + const swiper = this; + if (!swiper.allowClick) { + if (swiper.params.preventClicks) e.preventDefault(); + if (swiper.params.preventClicksPropagation && swiper.animating) { + e.stopPropagation(); + e.stopImmediatePropagation(); + } + } +} + +function attachEvents() { + const swiper = this; + const { + params, touchEvents, el, wrapperEl, + } = swiper; + + { + swiper.onTouchStart = onTouchStart.bind(swiper); + swiper.onTouchMove = onTouchMove.bind(swiper); + swiper.onTouchEnd = onTouchEnd.bind(swiper); + } + + swiper.onClick = onClick.bind(swiper); + + const target = params.touchEventsTarget === 'container' ? el : wrapperEl; + const capture = !!params.nested; + + // Touch Events + { + if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) { + target.addEventListener(touchEvents.start, swiper.onTouchStart, false); + document.addEventListener(touchEvents.move, swiper.onTouchMove, capture); + document.addEventListener(touchEvents.end, swiper.onTouchEnd, false); + } else { + if (Support.touch) { + const passiveListener = touchEvents.start === 'touchstart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + target.addEventListener(touchEvents.start, swiper.onTouchStart, passiveListener); + target.addEventListener(touchEvents.move, swiper.onTouchMove, Support.passiveListener ? { passive: false, capture } : capture); + target.addEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener); + } + if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) { + target.addEventListener('mousedown', swiper.onTouchStart, false); + document.addEventListener('mousemove', swiper.onTouchMove, capture); + document.addEventListener('mouseup', swiper.onTouchEnd, false); + } + } + // Prevent Links Clicks + if (params.preventClicks || params.preventClicksPropagation) { + target.addEventListener('click', swiper.onClick, true); + } + } + + // Resize handler + swiper.on((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize, true); +} + +function detachEvents() { + const swiper = this; + + const { + params, touchEvents, el, wrapperEl, + } = swiper; + + const target = params.touchEventsTarget === 'container' ? el : wrapperEl; + const capture = !!params.nested; + + // Touch Events + { + if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) { + target.removeEventListener(touchEvents.start, swiper.onTouchStart, false); + document.removeEventListener(touchEvents.move, swiper.onTouchMove, capture); + document.removeEventListener(touchEvents.end, swiper.onTouchEnd, false); + } else { + if (Support.touch) { + const passiveListener = touchEvents.start === 'onTouchStart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + target.removeEventListener(touchEvents.start, swiper.onTouchStart, passiveListener); + target.removeEventListener(touchEvents.move, swiper.onTouchMove, capture); + target.removeEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener); + } + if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) { + target.removeEventListener('mousedown', swiper.onTouchStart, false); + document.removeEventListener('mousemove', swiper.onTouchMove, capture); + document.removeEventListener('mouseup', swiper.onTouchEnd, false); + } + } + // Prevent Links Clicks + if (params.preventClicks || params.preventClicksPropagation) { + target.removeEventListener('click', swiper.onClick, true); + } + } + + // Resize handler + swiper.off((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize); +} + +var events = { + attachEvents, + detachEvents, +}; + +function setBreakpoint () { + const swiper = this; + const { + activeIndex, initialized, loopedSlides = 0, params, + } = swiper; + const breakpoints = params.breakpoints; + if (!breakpoints || (breakpoints && Object.keys(breakpoints).length === 0)) return; + + // Set breakpoint for window width and update parameters + const breakpoint = swiper.getBreakpoint(breakpoints); + + if (breakpoint && swiper.currentBreakpoint !== breakpoint) { + const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined; + if (breakpointOnlyParams) { + ['slidesPerView', 'spaceBetween', 'slidesPerGroup'].forEach((param) => { + const paramValue = breakpointOnlyParams[param]; + if (typeof paramValue === 'undefined') return; + if (param === 'slidesPerView' && (paramValue === 'AUTO' || paramValue === 'auto')) { + breakpointOnlyParams[param] = 'auto'; + } else if (param === 'slidesPerView') { + breakpointOnlyParams[param] = parseFloat(paramValue); + } else { + breakpointOnlyParams[param] = parseInt(paramValue, 10); + } + }); + } + + const breakpointParams = breakpointOnlyParams || swiper.originalParams; + const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction; + const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged); + + if (directionChanged && initialized) { + swiper.changeDirection(); + } + + Utils.extend(swiper.params, breakpointParams); + + Utils.extend(swiper, { + allowTouchMove: swiper.params.allowTouchMove, + allowSlideNext: swiper.params.allowSlideNext, + allowSlidePrev: swiper.params.allowSlidePrev, + }); + + swiper.currentBreakpoint = breakpoint; + + if (needsReLoop && initialized) { + swiper.loopDestroy(); + swiper.loopCreate(); + swiper.updateSlides(); + swiper.slideTo((activeIndex - loopedSlides) + swiper.loopedSlides, 0, false); + } + + swiper.emit('breakpoint', breakpointParams); + } +} + +function getBreakpoint (breakpoints) { + const swiper = this; + // Get breakpoint for window width + if (!breakpoints) return undefined; + let breakpoint = false; + const points = []; + Object.keys(breakpoints).forEach((point) => { + points.push(point); + }); + points.sort((a, b) => parseInt(a, 10) - parseInt(b, 10)); + for (let i = 0; i < points.length; i += 1) { + const point = points[i]; + if (swiper.params.breakpointsInverse) { + if (point <= window.innerWidth) { + breakpoint = point; + } + } else if (point >= window.innerWidth && !breakpoint) { + breakpoint = point; + } + } + return breakpoint || 'max'; +} + +var breakpoints = { setBreakpoint, getBreakpoint }; + +function addClasses () { + const swiper = this; + const { + classNames, params, rtl, $el, + } = swiper; + const suffixes = []; + + suffixes.push('initialized'); + suffixes.push(params.direction); + + if (params.freeMode) { + suffixes.push('free-mode'); + } + if (!Support.flexbox) { + suffixes.push('no-flexbox'); + } + if (params.autoHeight) { + suffixes.push('autoheight'); + } + if (rtl) { + suffixes.push('rtl'); + } + if (params.slidesPerColumn > 1) { + suffixes.push('multirow'); + } + if (Device.android) { + suffixes.push('android'); + } + if (Device.ios) { + suffixes.push('ios'); + } + // WP8 Touch Events Fix + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + suffixes.push(`wp8-${params.direction}`); + } + + suffixes.forEach((suffix) => { + classNames.push(params.containerModifierClass + suffix); + }); + + $el.addClass(classNames.join(' ')); +} + +function removeClasses () { + const swiper = this; + const { $el, classNames } = swiper; + + $el.removeClass(classNames.join(' ')); +} + +var classes = { addClasses, removeClasses }; + +function loadImage (imageEl, src, srcset, sizes, checkForComplete, callback) { + let image; + function onReady() { + if (callback) callback(); + } + if (!imageEl.complete || !checkForComplete) { + if (src) { + image = new window.Image(); + image.onload = onReady; + image.onerror = onReady; + if (sizes) { + image.sizes = sizes; + } + if (srcset) { + image.srcset = srcset; + } + if (src) { + image.src = src; + } + } else { + onReady(); + } + } else { + // image already loaded... + onReady(); + } +} + +function preloadImages () { + const swiper = this; + swiper.imagesToLoad = swiper.$el.find('img'); + function onReady() { + if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) return; + if (swiper.imagesLoaded !== undefined) swiper.imagesLoaded += 1; + if (swiper.imagesLoaded === swiper.imagesToLoad.length) { + if (swiper.params.updateOnImagesReady) swiper.update(); + swiper.emit('imagesReady'); + } + } + for (let i = 0; i < swiper.imagesToLoad.length; i += 1) { + const imageEl = swiper.imagesToLoad[i]; + swiper.loadImage( + imageEl, + imageEl.currentSrc || imageEl.getAttribute('src'), + imageEl.srcset || imageEl.getAttribute('srcset'), + imageEl.sizes || imageEl.getAttribute('sizes'), + true, + onReady + ); + } +} + +var images = { + loadImage, + preloadImages, +}; + +function checkOverflow() { + const swiper = this; + const wasLocked = swiper.isLocked; + + swiper.isLocked = swiper.snapGrid.length === 1; + swiper.allowSlideNext = !swiper.isLocked; + swiper.allowSlidePrev = !swiper.isLocked; + + // events + if (wasLocked !== swiper.isLocked) swiper.emit(swiper.isLocked ? 'lock' : 'unlock'); + + if (wasLocked && wasLocked !== swiper.isLocked) { + swiper.isEnd = false; + swiper.navigation.update(); + } +} + +var checkOverflow$1 = { checkOverflow }; + +var defaults = { + init: true, + direction: 'horizontal', + touchEventsTarget: 'container', + initialSlide: 0, + speed: 300, + // + preventInteractionOnTransition: false, + + // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView). + edgeSwipeDetection: false, + edgeSwipeThreshold: 20, + + // Free mode + freeMode: false, + freeModeMomentum: true, + freeModeMomentumRatio: 1, + freeModeMomentumBounce: true, + freeModeMomentumBounceRatio: 1, + freeModeMomentumVelocityRatio: 1, + freeModeSticky: false, + freeModeMinimumVelocity: 0.02, + + // Autoheight + autoHeight: false, + + // Set wrapper width + setWrapperSize: false, + + // Virtual Translate + virtualTranslate: false, + + // Effects + effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip' + + // Breakpoints + breakpoints: undefined, + breakpointsInverse: false, + + // Slides grid + spaceBetween: 0, + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerColumnFill: 'column', + slidesPerGroup: 1, + centeredSlides: false, + slidesOffsetBefore: 0, // in px + slidesOffsetAfter: 0, // in px + normalizeSlideIndex: true, + centerInsufficientSlides: false, + + // Disable swiper and hide navigation when container not overflow + watchOverflow: false, + + // Round length + roundLengths: false, + + // Touches + touchRatio: 1, + touchAngle: 45, + simulateTouch: true, + shortSwipes: true, + longSwipes: true, + longSwipesRatio: 0.5, + longSwipesMs: 300, + followFinger: true, + allowTouchMove: true, + threshold: 0, + touchMoveStopPropagation: true, + touchStartPreventDefault: true, + touchStartForcePreventDefault: false, + touchReleaseOnEdges: false, + + // Unique Navigation Elements + uniqueNavElements: true, + + // Resistance + resistance: true, + resistanceRatio: 0.85, + + // Progress + watchSlidesProgress: false, + watchSlidesVisibility: false, + + // Cursor + grabCursor: false, + + // Clicks + preventClicks: true, + preventClicksPropagation: true, + slideToClickedSlide: false, + + // Images + preloadImages: true, + updateOnImagesReady: true, + + // loop + loop: false, + loopAdditionalSlides: 0, + loopedSlides: null, + loopFillGroupWithBlank: false, + + // Swiping/no swiping + allowSlidePrev: true, + allowSlideNext: true, + swipeHandler: null, // '.swipe-handler', + noSwiping: true, + noSwipingClass: 'swiper-no-swiping', + noSwipingSelector: null, + + // Passive Listeners + passiveListeners: true, + + // NS + containerModifierClass: 'swiper-container-', // NEW + slideClass: 'swiper-slide', + slideBlankClass: 'swiper-slide-invisible-blank', + slideActiveClass: 'swiper-slide-active', + slideDuplicateActiveClass: 'swiper-slide-duplicate-active', + slideVisibleClass: 'swiper-slide-visible', + slideDuplicateClass: 'swiper-slide-duplicate', + slideNextClass: 'swiper-slide-next', + slideDuplicateNextClass: 'swiper-slide-duplicate-next', + slidePrevClass: 'swiper-slide-prev', + slideDuplicatePrevClass: 'swiper-slide-duplicate-prev', + wrapperClass: 'swiper-wrapper', + + // Callbacks + runCallbacksOnInit: true, +}; + +/* eslint no-param-reassign: "off" */ + +const prototypes = { + update, + translate, + transition, + slide, + loop, + grabCursor, + manipulation, + events, + breakpoints, + checkOverflow: checkOverflow$1, + classes, + images, +}; + +const extendedDefaults = {}; + +class Swiper extends SwiperClass { + constructor(...args) { + let el; + let params; + if (args.length === 1 && args[0].constructor && args[0].constructor === Object) { + params = args[0]; + } else { + [el, params] = args; + } + if (!params) params = {}; + + params = Utils.extend({}, params); + if (el && !params.el) params.el = el; + + super(params); + + Object.keys(prototypes).forEach((prototypeGroup) => { + Object.keys(prototypes[prototypeGroup]).forEach((protoMethod) => { + if (!Swiper.prototype[protoMethod]) { + Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod]; + } + }); + }); + + // Swiper Instance + const swiper = this; + if (typeof swiper.modules === 'undefined') { + swiper.modules = {}; + } + Object.keys(swiper.modules).forEach((moduleName) => { + const module = swiper.modules[moduleName]; + if (module.params) { + const moduleParamName = Object.keys(module.params)[0]; + const moduleParams = module.params[moduleParamName]; + if (typeof moduleParams !== 'object' || moduleParams === null) return; + if (!(moduleParamName in params && 'enabled' in moduleParams)) return; + if (params[moduleParamName] === true) { + params[moduleParamName] = { enabled: true }; + } + if ( + typeof params[moduleParamName] === 'object' + && !('enabled' in params[moduleParamName]) + ) { + params[moduleParamName].enabled = true; + } + if (!params[moduleParamName]) params[moduleParamName] = { enabled: false }; + } + }); + + // Extend defaults with modules params + const swiperParams = Utils.extend({}, defaults); + swiper.useModulesParams(swiperParams); + + // Extend defaults with passed params + swiper.params = Utils.extend({}, swiperParams, extendedDefaults, params); + swiper.originalParams = Utils.extend({}, swiper.params); + swiper.passedParams = Utils.extend({}, params); + + // Save Dom lib + swiper.$ = $; + + // Find el + const $el = $(swiper.params.el); + el = $el[0]; + + if (!el) { + return undefined; + } + + if ($el.length > 1) { + const swipers = []; + $el.each((index, containerEl) => { + const newParams = Utils.extend({}, params, { el: containerEl }); + swipers.push(new Swiper(newParams)); + }); + return swipers; + } + + el.swiper = swiper; + $el.data('swiper', swiper); + + // Find Wrapper + const $wrapperEl = $el.children(`.${swiper.params.wrapperClass}`); + + // Extend Swiper + Utils.extend(swiper, { + $el, + el, + $wrapperEl, + wrapperEl: $wrapperEl[0], + + // Classes + classNames: [], + + // Slides + slides: $(), + slidesGrid: [], + snapGrid: [], + slidesSizesGrid: [], + + // isDirection + isHorizontal() { + return swiper.params.direction === 'horizontal'; + }, + isVertical() { + return swiper.params.direction === 'vertical'; + }, + // RTL + rtl: (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'), + rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'), + wrongRTL: $wrapperEl.css('display') === '-webkit-box', + + // Indexes + activeIndex: 0, + realIndex: 0, + + // + isBeginning: true, + isEnd: false, + + // Props + translate: 0, + previousTranslate: 0, + progress: 0, + velocity: 0, + animating: false, + + // Locks + allowSlideNext: swiper.params.allowSlideNext, + allowSlidePrev: swiper.params.allowSlidePrev, + + // Touch Events + touchEvents: (function touchEvents() { + const touch = ['touchstart', 'touchmove', 'touchend']; + let desktop = ['mousedown', 'mousemove', 'mouseup']; + if (Support.pointerEvents) { + desktop = ['pointerdown', 'pointermove', 'pointerup']; + } else if (Support.prefixedPointerEvents) { + desktop = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp']; + } + swiper.touchEventsTouch = { + start: touch[0], + move: touch[1], + end: touch[2], + }; + swiper.touchEventsDesktop = { + start: desktop[0], + move: desktop[1], + end: desktop[2], + }; + return Support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop; + }()), + touchEventsData: { + isTouched: undefined, + isMoved: undefined, + allowTouchCallbacks: undefined, + touchStartTime: undefined, + isScrolling: undefined, + currentTranslate: undefined, + startTranslate: undefined, + allowThresholdMove: undefined, + // Form elements to match + formElements: 'input, select, option, textarea, button, video', + // Last click time + lastClickTime: Utils.now(), + clickTimeout: undefined, + // Velocities + velocities: [], + allowMomentumBounce: undefined, + isTouchEvent: undefined, + startMoving: undefined, + }, + + // Clicks + allowClick: true, + + // Touches + allowTouchMove: swiper.params.allowTouchMove, + + touches: { + startX: 0, + startY: 0, + currentX: 0, + currentY: 0, + diff: 0, + }, + + // Images + imagesToLoad: [], + imagesLoaded: 0, + + }); + + // Install Modules + swiper.useModules(); + + // Init + if (swiper.params.init) { + swiper.init(); + } + + // Return app instance + return swiper; + } + + slidesPerViewDynamic() { + const swiper = this; + const { + params, slides, slidesGrid, size: swiperSize, activeIndex, + } = swiper; + let spv = 1; + if (params.centeredSlides) { + let slideSize = slides[activeIndex].swiperSlideSize; + let breakLoop; + for (let i = activeIndex + 1; i < slides.length; i += 1) { + if (slides[i] && !breakLoop) { + slideSize += slides[i].swiperSlideSize; + spv += 1; + if (slideSize > swiperSize) breakLoop = true; + } + } + for (let i = activeIndex - 1; i >= 0; i -= 1) { + if (slides[i] && !breakLoop) { + slideSize += slides[i].swiperSlideSize; + spv += 1; + if (slideSize > swiperSize) breakLoop = true; + } + } + } else { + for (let i = activeIndex + 1; i < slides.length; i += 1) { + if (slidesGrid[i] - slidesGrid[activeIndex] < swiperSize) { + spv += 1; + } + } + } + return spv; + } + + update() { + const swiper = this; + if (!swiper || swiper.destroyed) return; + const { snapGrid, params } = swiper; + // Breakpoints + if (params.breakpoints) { + swiper.setBreakpoint(); + } + swiper.updateSize(); + swiper.updateSlides(); + swiper.updateProgress(); + swiper.updateSlidesClasses(); + + function setTranslate() { + const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate; + const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate()); + swiper.setTranslate(newTranslate); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + let translated; + if (swiper.params.freeMode) { + setTranslate(); + if (swiper.params.autoHeight) { + swiper.updateAutoHeight(); + } + } else { + if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) { + translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true); + } else { + translated = swiper.slideTo(swiper.activeIndex, 0, false, true); + } + if (!translated) { + setTranslate(); + } + } + if (params.watchOverflow && snapGrid !== swiper.snapGrid) { + swiper.checkOverflow(); + } + swiper.emit('update'); + } + + changeDirection(newDirection, needUpdate = true) { + const swiper = this; + const currentDirection = swiper.params.direction; + if (!newDirection) { + // eslint-disable-next-line + newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal'; + } + if ((newDirection === currentDirection) || (newDirection !== 'horizontal' && newDirection !== 'vertical')) { + return swiper; + } + + if (currentDirection === 'vertical') { + swiper.$el + .removeClass(`${swiper.params.containerModifierClass}vertical wp8-vertical`) + .addClass(`${swiper.params.containerModifierClass}${newDirection}`); + + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + swiper.$el.addClass(`${swiper.params.containerModifierClass}wp8-${newDirection}`); + } + } + if (currentDirection === 'horizontal') { + swiper.$el + .removeClass(`${swiper.params.containerModifierClass}horizontal wp8-horizontal`) + .addClass(`${swiper.params.containerModifierClass}${newDirection}`); + + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + swiper.$el.addClass(`${swiper.params.containerModifierClass}wp8-${newDirection}`); + } + } + + swiper.params.direction = newDirection; + + swiper.slides.each((slideIndex, slideEl) => { + if (newDirection === 'vertical') { + slideEl.style.width = ''; + } else { + slideEl.style.height = ''; + } + }); + + swiper.emit('changeDirection'); + if (needUpdate) swiper.update(); + + return swiper; + } + + init() { + const swiper = this; + if (swiper.initialized) return; + + swiper.emit('beforeInit'); + + // Set breakpoint + if (swiper.params.breakpoints) { + swiper.setBreakpoint(); + } + + // Add Classes + swiper.addClasses(); + + // Create loop + if (swiper.params.loop) { + swiper.loopCreate(); + } + + // Update size + swiper.updateSize(); + + // Update slides + swiper.updateSlides(); + + if (swiper.params.watchOverflow) { + swiper.checkOverflow(); + } + + // Set Grab Cursor + if (swiper.params.grabCursor) { + swiper.setGrabCursor(); + } + + if (swiper.params.preloadImages) { + swiper.preloadImages(); + } + + // Slide To Initial Slide + if (swiper.params.loop) { + swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit); + } else { + swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit); + } + + // Attach events + swiper.attachEvents(); + + // Init Flag + swiper.initialized = true; + + // Emit + swiper.emit('init'); + } + + destroy(deleteInstance = true, cleanStyles = true) { + const swiper = this; + const { + params, $el, $wrapperEl, slides, + } = swiper; + + if (typeof swiper.params === 'undefined' || swiper.destroyed) { + return null; + } + + swiper.emit('beforeDestroy'); + + // Init Flag + swiper.initialized = false; + + // Detach events + swiper.detachEvents(); + + // Destroy loop + if (params.loop) { + swiper.loopDestroy(); + } + + // Cleanup styles + if (cleanStyles) { + swiper.removeClasses(); + $el.removeAttr('style'); + $wrapperEl.removeAttr('style'); + if (slides && slides.length) { + slides + .removeClass([ + params.slideVisibleClass, + params.slideActiveClass, + params.slideNextClass, + params.slidePrevClass, + ].join(' ')) + .removeAttr('style') + .removeAttr('data-swiper-slide-index') + .removeAttr('data-swiper-column') + .removeAttr('data-swiper-row'); + } + } + + swiper.emit('destroy'); + + // Detach emitter events + Object.keys(swiper.eventsListeners).forEach((eventName) => { + swiper.off(eventName); + }); + + if (deleteInstance !== false) { + swiper.$el[0].swiper = null; + swiper.$el.data('swiper', null); + Utils.deleteProps(swiper); + } + swiper.destroyed = true; + + return null; + } + + static extendDefaults(newDefaults) { + Utils.extend(extendedDefaults, newDefaults); + } + + static get extendedDefaults() { + return extendedDefaults; + } + + static get defaults() { + return defaults; + } + + static get Class() { + return SwiperClass; + } + + static get $() { + return $; + } +} + +var Device$1 = { + name: 'device', + proto: { + device: Device, + }, + static: { + device: Device, + }, +}; + +var Support$1 = { + name: 'support', + proto: { + support: Support, + }, + static: { + support: Support, + }, +}; + +var Browser$1 = { + name: 'browser', + proto: { + browser: Browser, + }, + static: { + browser: Browser, + }, +}; + +var Resize = { + name: 'resize', + create() { + const swiper = this; + Utils.extend(swiper, { + resize: { + resizeHandler() { + if (!swiper || swiper.destroyed || !swiper.initialized) return; + swiper.emit('beforeResize'); + swiper.emit('resize'); + }, + orientationChangeHandler() { + if (!swiper || swiper.destroyed || !swiper.initialized) return; + swiper.emit('orientationchange'); + }, + }, + }); + }, + on: { + init() { + const swiper = this; + // Emit resize + window.addEventListener('resize', swiper.resize.resizeHandler); + + // Emit orientationchange + window.addEventListener('orientationchange', swiper.resize.orientationChangeHandler); + }, + destroy() { + const swiper = this; + window.removeEventListener('resize', swiper.resize.resizeHandler); + window.removeEventListener('orientationchange', swiper.resize.orientationChangeHandler); + }, + }, +}; + +const Observer = { + func: window.MutationObserver || window.WebkitMutationObserver, + attach(target, options = {}) { + const swiper = this; + + const ObserverFunc = Observer.func; + const observer = new ObserverFunc((mutations) => { + // The observerUpdate event should only be triggered + // once despite the number of mutations. Additional + // triggers are redundant and are very costly + if (mutations.length === 1) { + swiper.emit('observerUpdate', mutations[0]); + return; + } + const observerUpdate = function observerUpdate() { + swiper.emit('observerUpdate', mutations[0]); + }; + + if (window.requestAnimationFrame) { + window.requestAnimationFrame(observerUpdate); + } else { + window.setTimeout(observerUpdate, 0); + } + }); + + observer.observe(target, { + attributes: typeof options.attributes === 'undefined' ? true : options.attributes, + childList: typeof options.childList === 'undefined' ? true : options.childList, + characterData: typeof options.characterData === 'undefined' ? true : options.characterData, + }); + + swiper.observer.observers.push(observer); + }, + init() { + const swiper = this; + if (!Support.observer || !swiper.params.observer) return; + if (swiper.params.observeParents) { + const containerParents = swiper.$el.parents(); + for (let i = 0; i < containerParents.length; i += 1) { + swiper.observer.attach(containerParents[i]); + } + } + // Observe container + swiper.observer.attach(swiper.$el[0], { childList: swiper.params.observeSlideChildren }); + + // Observe wrapper + swiper.observer.attach(swiper.$wrapperEl[0], { attributes: false }); + }, + destroy() { + const swiper = this; + swiper.observer.observers.forEach((observer) => { + observer.disconnect(); + }); + swiper.observer.observers = []; + }, +}; + +var Observer$1 = { + name: 'observer', + params: { + observer: false, + observeParents: false, + observeSlideChildren: false, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + observer: { + init: Observer.init.bind(swiper), + attach: Observer.attach.bind(swiper), + destroy: Observer.destroy.bind(swiper), + observers: [], + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.observer.init(); + }, + destroy() { + const swiper = this; + swiper.observer.destroy(); + }, + }, +}; + +const Virtual = { + update(force) { + const swiper = this; + const { slidesPerView, slidesPerGroup, centeredSlides } = swiper.params; + const { addSlidesBefore, addSlidesAfter } = swiper.params.virtual; + const { + from: previousFrom, + to: previousTo, + slides, + slidesGrid: previousSlidesGrid, + renderSlide, + offset: previousOffset, + } = swiper.virtual; + swiper.updateActiveIndex(); + const activeIndex = swiper.activeIndex || 0; + + let offsetProp; + if (swiper.rtlTranslate) offsetProp = 'right'; + else offsetProp = swiper.isHorizontal() ? 'left' : 'top'; + + let slidesAfter; + let slidesBefore; + if (centeredSlides) { + slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore; + slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter; + } else { + slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesBefore; + slidesBefore = slidesPerGroup + addSlidesAfter; + } + const from = Math.max((activeIndex || 0) - slidesBefore, 0); + const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1); + const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0); + + Utils.extend(swiper.virtual, { + from, + to, + offset, + slidesGrid: swiper.slidesGrid, + }); + + function onRendered() { + swiper.updateSlides(); + swiper.updateProgress(); + swiper.updateSlidesClasses(); + if (swiper.lazy && swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + } + + if (previousFrom === from && previousTo === to && !force) { + if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) { + swiper.slides.css(offsetProp, `${offset}px`); + } + swiper.updateProgress(); + return; + } + if (swiper.params.virtual.renderExternal) { + swiper.params.virtual.renderExternal.call(swiper, { + offset, + from, + to, + slides: (function getSlides() { + const slidesToRender = []; + for (let i = from; i <= to; i += 1) { + slidesToRender.push(slides[i]); + } + return slidesToRender; + }()), + }); + onRendered(); + return; + } + const prependIndexes = []; + const appendIndexes = []; + if (force) { + swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove(); + } else { + for (let i = previousFrom; i <= previousTo; i += 1) { + if (i < from || i > to) { + swiper.$wrapperEl.find(`.${swiper.params.slideClass}[data-swiper-slide-index="${i}"]`).remove(); + } + } + } + for (let i = 0; i < slides.length; i += 1) { + if (i >= from && i <= to) { + if (typeof previousTo === 'undefined' || force) { + appendIndexes.push(i); + } else { + if (i > previousTo) appendIndexes.push(i); + if (i < previousFrom) prependIndexes.push(i); + } + } + } + appendIndexes.forEach((index) => { + swiper.$wrapperEl.append(renderSlide(slides[index], index)); + }); + prependIndexes.sort((a, b) => b - a).forEach((index) => { + swiper.$wrapperEl.prepend(renderSlide(slides[index], index)); + }); + swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, `${offset}px`); + onRendered(); + }, + renderSlide(slide, index) { + const swiper = this; + const params = swiper.params.virtual; + if (params.cache && swiper.virtual.cache[index]) { + return swiper.virtual.cache[index]; + } + const $slideEl = params.renderSlide + ? $(params.renderSlide.call(swiper, slide, index)) + : $(`
            ${slide}
            `); + if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index); + if (params.cache) swiper.virtual.cache[index] = $slideEl; + return $slideEl; + }, + appendSlide(slides) { + const swiper = this; + if (typeof slides === 'object' && 'length' in slides) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) swiper.virtual.slides.push(slides[i]); + } + } else { + swiper.virtual.slides.push(slides); + } + swiper.virtual.update(true); + }, + prependSlide(slides) { + const swiper = this; + const activeIndex = swiper.activeIndex; + let newActiveIndex = activeIndex + 1; + let numberOfNewSlides = 1; + + if (Array.isArray(slides)) { + for (let i = 0; i < slides.length; i += 1) { + if (slides[i]) swiper.virtual.slides.unshift(slides[i]); + } + newActiveIndex = activeIndex + slides.length; + numberOfNewSlides = slides.length; + } else { + swiper.virtual.slides.unshift(slides); + } + if (swiper.params.virtual.cache) { + const cache = swiper.virtual.cache; + const newCache = {}; + Object.keys(cache).forEach((cachedIndex) => { + newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cache[cachedIndex]; + }); + swiper.virtual.cache = newCache; + } + swiper.virtual.update(true); + swiper.slideTo(newActiveIndex, 0); + }, + removeSlide(slidesIndexes) { + const swiper = this; + if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return; + let activeIndex = swiper.activeIndex; + if (Array.isArray(slidesIndexes)) { + for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) { + swiper.virtual.slides.splice(slidesIndexes[i], 1); + if (swiper.params.virtual.cache) { + delete swiper.virtual.cache[slidesIndexes[i]]; + } + if (slidesIndexes[i] < activeIndex) activeIndex -= 1; + activeIndex = Math.max(activeIndex, 0); + } + } else { + swiper.virtual.slides.splice(slidesIndexes, 1); + if (swiper.params.virtual.cache) { + delete swiper.virtual.cache[slidesIndexes]; + } + if (slidesIndexes < activeIndex) activeIndex -= 1; + activeIndex = Math.max(activeIndex, 0); + } + swiper.virtual.update(true); + swiper.slideTo(activeIndex, 0); + }, + removeAllSlides() { + const swiper = this; + swiper.virtual.slides = []; + if (swiper.params.virtual.cache) { + swiper.virtual.cache = {}; + } + swiper.virtual.update(true); + swiper.slideTo(0, 0); + }, +}; + +var virtual = { + name: 'virtual', + params: { + virtual: { + enabled: false, + slides: [], + cache: true, + renderSlide: null, + renderExternal: null, + addSlidesBefore: 0, + addSlidesAfter: 0, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + virtual: { + update: Virtual.update.bind(swiper), + appendSlide: Virtual.appendSlide.bind(swiper), + prependSlide: Virtual.prependSlide.bind(swiper), + removeSlide: Virtual.removeSlide.bind(swiper), + removeAllSlides: Virtual.removeAllSlides.bind(swiper), + renderSlide: Virtual.renderSlide.bind(swiper), + slides: swiper.params.virtual.slides, + cache: {}, + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (!swiper.params.virtual.enabled) return; + swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`); + const overwriteParams = { + watchSlidesProgress: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + + if (!swiper.params.initialSlide) { + swiper.virtual.update(); + } + }, + setTranslate() { + const swiper = this; + if (!swiper.params.virtual.enabled) return; + swiper.virtual.update(); + }, + }, +}; + +const Keyboard = { + handle(event) { + const swiper = this; + const { rtlTranslate: rtl } = swiper; + let e = event; + if (e.originalEvent) e = e.originalEvent; // jquery fix + const kc = e.keyCode || e.charCode; + // Directions locks + if (!swiper.allowSlideNext && ((swiper.isHorizontal() && kc === 39) || (swiper.isVertical() && kc === 40))) { + return false; + } + if (!swiper.allowSlidePrev && ((swiper.isHorizontal() && kc === 37) || (swiper.isVertical() && kc === 38))) { + return false; + } + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { + return undefined; + } + if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) { + return undefined; + } + if (swiper.params.keyboard.onlyInViewport && (kc === 37 || kc === 39 || kc === 38 || kc === 40)) { + let inView = false; + // Check that swiper should be inside of visible area of window + if (swiper.$el.parents(`.${swiper.params.slideClass}`).length > 0 && swiper.$el.parents(`.${swiper.params.slideActiveClass}`).length === 0) { + return undefined; + } + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + const swiperOffset = swiper.$el.offset(); + if (rtl) swiperOffset.left -= swiper.$el[0].scrollLeft; + const swiperCoord = [ + [swiperOffset.left, swiperOffset.top], + [swiperOffset.left + swiper.width, swiperOffset.top], + [swiperOffset.left, swiperOffset.top + swiper.height], + [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height], + ]; + for (let i = 0; i < swiperCoord.length; i += 1) { + const point = swiperCoord[i]; + if ( + point[0] >= 0 && point[0] <= windowWidth + && point[1] >= 0 && point[1] <= windowHeight + ) { + inView = true; + } + } + if (!inView) return undefined; + } + if (swiper.isHorizontal()) { + if (kc === 37 || kc === 39) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + } + if ((kc === 39 && !rtl) || (kc === 37 && rtl)) swiper.slideNext(); + if ((kc === 37 && !rtl) || (kc === 39 && rtl)) swiper.slidePrev(); + } else { + if (kc === 38 || kc === 40) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + } + if (kc === 40) swiper.slideNext(); + if (kc === 38) swiper.slidePrev(); + } + swiper.emit('keyPress', kc); + return undefined; + }, + enable() { + const swiper = this; + if (swiper.keyboard.enabled) return; + $(document).on('keydown', swiper.keyboard.handle); + swiper.keyboard.enabled = true; + }, + disable() { + const swiper = this; + if (!swiper.keyboard.enabled) return; + $(document).off('keydown', swiper.keyboard.handle); + swiper.keyboard.enabled = false; + }, +}; + +var keyboard = { + name: 'keyboard', + params: { + keyboard: { + enabled: false, + onlyInViewport: true, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + keyboard: { + enabled: false, + enable: Keyboard.enable.bind(swiper), + disable: Keyboard.disable.bind(swiper), + handle: Keyboard.handle.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.keyboard.enabled) { + swiper.keyboard.enable(); + } + }, + destroy() { + const swiper = this; + if (swiper.keyboard.enabled) { + swiper.keyboard.disable(); + } + }, + }, +}; + +function isEventSupported() { + const eventName = 'onwheel'; + let isSupported = eventName in document; + + if (!isSupported) { + const element = document.createElement('div'); + element.setAttribute(eventName, 'return;'); + isSupported = typeof element[eventName] === 'function'; + } + + if (!isSupported + && document.implementation + && document.implementation.hasFeature + // always returns true in newer browsers as per the standard. + // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature + && document.implementation.hasFeature('', '') !== true + ) { + // This is the only way to test support for the `wheel` event in IE9+. + isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); + } + + return isSupported; +} +const Mousewheel = { + lastScrollTime: Utils.now(), + event: (function getEvent() { + if (window.navigator.userAgent.indexOf('firefox') > -1) return 'DOMMouseScroll'; + return isEventSupported() ? 'wheel' : 'mousewheel'; + }()), + normalize(e) { + // Reasonable defaults + const PIXEL_STEP = 10; + const LINE_HEIGHT = 40; + const PAGE_HEIGHT = 800; + + let sX = 0; + let sY = 0; // spinX, spinY + let pX = 0; + let pY = 0; // pixelX, pixelY + + // Legacy + if ('detail' in e) { + sY = e.detail; + } + if ('wheelDelta' in e) { + sY = -e.wheelDelta / 120; + } + if ('wheelDeltaY' in e) { + sY = -e.wheelDeltaY / 120; + } + if ('wheelDeltaX' in e) { + sX = -e.wheelDeltaX / 120; + } + + // side scrolling on FF with DOMMouseScroll + if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) { + sX = sY; + sY = 0; + } + + pX = sX * PIXEL_STEP; + pY = sY * PIXEL_STEP; + + if ('deltaY' in e) { + pY = e.deltaY; + } + if ('deltaX' in e) { + pX = e.deltaX; + } + + if ((pX || pY) && e.deltaMode) { + if (e.deltaMode === 1) { // delta in LINE units + pX *= LINE_HEIGHT; + pY *= LINE_HEIGHT; + } else { // delta in PAGE units + pX *= PAGE_HEIGHT; + pY *= PAGE_HEIGHT; + } + } + + // Fall-back if spin cannot be determined + if (pX && !sX) { + sX = (pX < 1) ? -1 : 1; + } + if (pY && !sY) { + sY = (pY < 1) ? -1 : 1; + } + + return { + spinX: sX, + spinY: sY, + pixelX: pX, + pixelY: pY, + }; + }, + handleMouseEnter() { + const swiper = this; + swiper.mouseEntered = true; + }, + handleMouseLeave() { + const swiper = this; + swiper.mouseEntered = false; + }, + handle(event) { + let e = event; + const swiper = this; + const params = swiper.params.mousewheel; + + if (!swiper.mouseEntered && !params.releaseOnEdges) return true; + + if (e.originalEvent) e = e.originalEvent; // jquery fix + let delta = 0; + const rtlFactor = swiper.rtlTranslate ? -1 : 1; + + const data = Mousewheel.normalize(e); + + if (params.forceToAxis) { + if (swiper.isHorizontal()) { + if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) delta = data.pixelX * rtlFactor; + else return true; + } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) delta = data.pixelY; + else return true; + } else { + delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY; + } + + if (delta === 0) return true; + + if (params.invert) delta = -delta; + + if (!swiper.params.freeMode) { + if (Utils.now() - swiper.mousewheel.lastScrollTime > 60) { + if (delta < 0) { + if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) { + swiper.slideNext(); + swiper.emit('scroll', e); + } else if (params.releaseOnEdges) return true; + } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) { + swiper.slidePrev(); + swiper.emit('scroll', e); + } else if (params.releaseOnEdges) return true; + } + swiper.mousewheel.lastScrollTime = (new window.Date()).getTime(); + } else { + // Freemode or scrollContainer: + if (swiper.params.loop) { + swiper.loopFix(); + } + let position = swiper.getTranslate() + (delta * params.sensitivity); + const wasBeginning = swiper.isBeginning; + const wasEnd = swiper.isEnd; + + if (position >= swiper.minTranslate()) position = swiper.minTranslate(); + if (position <= swiper.maxTranslate()) position = swiper.maxTranslate(); + + swiper.setTransition(0); + swiper.setTranslate(position); + swiper.updateProgress(); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + + if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) { + swiper.updateSlidesClasses(); + } + + if (swiper.params.freeModeSticky) { + clearTimeout(swiper.mousewheel.timeout); + swiper.mousewheel.timeout = Utils.nextTick(() => { + swiper.slideToClosest(); + }, 300); + } + // Emit event + swiper.emit('scroll', e); + + // Stop autoplay + if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) swiper.autoplay.stop(); + // Return page scroll on edge positions + if (position === swiper.minTranslate() || position === swiper.maxTranslate()) return true; + } + + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + return false; + }, + enable() { + const swiper = this; + if (!Mousewheel.event) return false; + if (swiper.mousewheel.enabled) return false; + let target = swiper.$el; + if (swiper.params.mousewheel.eventsTarged !== 'container') { + target = $(swiper.params.mousewheel.eventsTarged); + } + target.on('mouseenter', swiper.mousewheel.handleMouseEnter); + target.on('mouseleave', swiper.mousewheel.handleMouseLeave); + target.on(Mousewheel.event, swiper.mousewheel.handle); + swiper.mousewheel.enabled = true; + return true; + }, + disable() { + const swiper = this; + if (!Mousewheel.event) return false; + if (!swiper.mousewheel.enabled) return false; + let target = swiper.$el; + if (swiper.params.mousewheel.eventsTarged !== 'container') { + target = $(swiper.params.mousewheel.eventsTarged); + } + target.off(Mousewheel.event, swiper.mousewheel.handle); + swiper.mousewheel.enabled = false; + return true; + }, +}; + +var mousewheel = { + name: 'mousewheel', + params: { + mousewheel: { + enabled: false, + releaseOnEdges: false, + invert: false, + forceToAxis: false, + sensitivity: 1, + eventsTarged: 'container', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + mousewheel: { + enabled: false, + enable: Mousewheel.enable.bind(swiper), + disable: Mousewheel.disable.bind(swiper), + handle: Mousewheel.handle.bind(swiper), + handleMouseEnter: Mousewheel.handleMouseEnter.bind(swiper), + handleMouseLeave: Mousewheel.handleMouseLeave.bind(swiper), + lastScrollTime: Utils.now(), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.mousewheel.enabled) swiper.mousewheel.enable(); + }, + destroy() { + const swiper = this; + if (swiper.mousewheel.enabled) swiper.mousewheel.disable(); + }, + }, +}; + +const Navigation = { + update() { + // Update Navigation Buttons + const swiper = this; + const params = swiper.params.navigation; + + if (swiper.params.loop) return; + const { $nextEl, $prevEl } = swiper.navigation; + + if ($prevEl && $prevEl.length > 0) { + if (swiper.isBeginning) { + $prevEl.addClass(params.disabledClass); + } else { + $prevEl.removeClass(params.disabledClass); + } + $prevEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + } + if ($nextEl && $nextEl.length > 0) { + if (swiper.isEnd) { + $nextEl.addClass(params.disabledClass); + } else { + $nextEl.removeClass(params.disabledClass); + } + $nextEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + } + }, + onPrevClick(e) { + const swiper = this; + e.preventDefault(); + if (swiper.isBeginning && !swiper.params.loop) return; + swiper.slidePrev(); + }, + onNextClick(e) { + const swiper = this; + e.preventDefault(); + if (swiper.isEnd && !swiper.params.loop) return; + swiper.slideNext(); + }, + init() { + const swiper = this; + const params = swiper.params.navigation; + if (!(params.nextEl || params.prevEl)) return; + + let $nextEl; + let $prevEl; + if (params.nextEl) { + $nextEl = $(params.nextEl); + if ( + swiper.params.uniqueNavElements + && typeof params.nextEl === 'string' + && $nextEl.length > 1 + && swiper.$el.find(params.nextEl).length === 1 + ) { + $nextEl = swiper.$el.find(params.nextEl); + } + } + if (params.prevEl) { + $prevEl = $(params.prevEl); + if ( + swiper.params.uniqueNavElements + && typeof params.prevEl === 'string' + && $prevEl.length > 1 + && swiper.$el.find(params.prevEl).length === 1 + ) { + $prevEl = swiper.$el.find(params.prevEl); + } + } + + if ($nextEl && $nextEl.length > 0) { + $nextEl.on('click', swiper.navigation.onNextClick); + } + if ($prevEl && $prevEl.length > 0) { + $prevEl.on('click', swiper.navigation.onPrevClick); + } + + Utils.extend(swiper.navigation, { + $nextEl, + nextEl: $nextEl && $nextEl[0], + $prevEl, + prevEl: $prevEl && $prevEl[0], + }); + }, + destroy() { + const swiper = this; + const { $nextEl, $prevEl } = swiper.navigation; + if ($nextEl && $nextEl.length) { + $nextEl.off('click', swiper.navigation.onNextClick); + $nextEl.removeClass(swiper.params.navigation.disabledClass); + } + if ($prevEl && $prevEl.length) { + $prevEl.off('click', swiper.navigation.onPrevClick); + $prevEl.removeClass(swiper.params.navigation.disabledClass); + } + }, +}; + +var navigation = { + name: 'navigation', + params: { + navigation: { + nextEl: null, + prevEl: null, + + hideOnClick: false, + disabledClass: 'swiper-button-disabled', + hiddenClass: 'swiper-button-hidden', + lockClass: 'swiper-button-lock', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + navigation: { + init: Navigation.init.bind(swiper), + update: Navigation.update.bind(swiper), + destroy: Navigation.destroy.bind(swiper), + onNextClick: Navigation.onNextClick.bind(swiper), + onPrevClick: Navigation.onPrevClick.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.navigation.init(); + swiper.navigation.update(); + }, + toEdge() { + const swiper = this; + swiper.navigation.update(); + }, + fromEdge() { + const swiper = this; + swiper.navigation.update(); + }, + destroy() { + const swiper = this; + swiper.navigation.destroy(); + }, + click(e) { + const swiper = this; + const { $nextEl, $prevEl } = swiper.navigation; + if ( + swiper.params.navigation.hideOnClick + && !$(e.target).is($prevEl) + && !$(e.target).is($nextEl) + ) { + let isHidden; + if ($nextEl) { + isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass); + } else if ($prevEl) { + isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass); + } + if (isHidden === true) { + swiper.emit('navigationShow', swiper); + } else { + swiper.emit('navigationHide', swiper); + } + if ($nextEl) { + $nextEl.toggleClass(swiper.params.navigation.hiddenClass); + } + if ($prevEl) { + $prevEl.toggleClass(swiper.params.navigation.hiddenClass); + } + } + }, + }, +}; + +const Pagination = { + update() { + // Render || Update Pagination bullets/items + const swiper = this; + const rtl = swiper.rtl; + const params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return; + const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; + const $el = swiper.pagination.$el; + // Current/Total + let current; + const total = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; + if (swiper.params.loop) { + current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup); + if (current > slidesLength - 1 - (swiper.loopedSlides * 2)) { + current -= (slidesLength - (swiper.loopedSlides * 2)); + } + if (current > total - 1) current -= total; + if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current; + } else if (typeof swiper.snapIndex !== 'undefined') { + current = swiper.snapIndex; + } else { + current = swiper.activeIndex || 0; + } + // Types + if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) { + const bullets = swiper.pagination.bullets; + let firstIndex; + let lastIndex; + let midIndex; + if (params.dynamicBullets) { + swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true); + $el.css(swiper.isHorizontal() ? 'width' : 'height', `${swiper.pagination.bulletSize * (params.dynamicMainBullets + 4)}px`); + if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) { + swiper.pagination.dynamicBulletIndex += (current - swiper.previousIndex); + if (swiper.pagination.dynamicBulletIndex > (params.dynamicMainBullets - 1)) { + swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1; + } else if (swiper.pagination.dynamicBulletIndex < 0) { + swiper.pagination.dynamicBulletIndex = 0; + } + } + firstIndex = current - swiper.pagination.dynamicBulletIndex; + lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1); + midIndex = (lastIndex + firstIndex) / 2; + } + bullets.removeClass(`${params.bulletActiveClass} ${params.bulletActiveClass}-next ${params.bulletActiveClass}-next-next ${params.bulletActiveClass}-prev ${params.bulletActiveClass}-prev-prev ${params.bulletActiveClass}-main`); + if ($el.length > 1) { + bullets.each((index, bullet) => { + const $bullet = $(bullet); + const bulletIndex = $bullet.index(); + if (bulletIndex === current) { + $bullet.addClass(params.bulletActiveClass); + } + if (params.dynamicBullets) { + if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) { + $bullet.addClass(`${params.bulletActiveClass}-main`); + } + if (bulletIndex === firstIndex) { + $bullet + .prev() + .addClass(`${params.bulletActiveClass}-prev`) + .prev() + .addClass(`${params.bulletActiveClass}-prev-prev`); + } + if (bulletIndex === lastIndex) { + $bullet + .next() + .addClass(`${params.bulletActiveClass}-next`) + .next() + .addClass(`${params.bulletActiveClass}-next-next`); + } + } + }); + } else { + const $bullet = bullets.eq(current); + $bullet.addClass(params.bulletActiveClass); + if (params.dynamicBullets) { + const $firstDisplayedBullet = bullets.eq(firstIndex); + const $lastDisplayedBullet = bullets.eq(lastIndex); + for (let i = firstIndex; i <= lastIndex; i += 1) { + bullets.eq(i).addClass(`${params.bulletActiveClass}-main`); + } + $firstDisplayedBullet + .prev() + .addClass(`${params.bulletActiveClass}-prev`) + .prev() + .addClass(`${params.bulletActiveClass}-prev-prev`); + $lastDisplayedBullet + .next() + .addClass(`${params.bulletActiveClass}-next`) + .next() + .addClass(`${params.bulletActiveClass}-next-next`); + } + } + if (params.dynamicBullets) { + const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4); + const bulletsOffset = (((swiper.pagination.bulletSize * dynamicBulletsLength) - (swiper.pagination.bulletSize)) / 2) - (midIndex * swiper.pagination.bulletSize); + const offsetProp = rtl ? 'right' : 'left'; + bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`); + } + } + if (params.type === 'fraction') { + $el.find(`.${params.currentClass}`).text(params.formatFractionCurrent(current + 1)); + $el.find(`.${params.totalClass}`).text(params.formatFractionTotal(total)); + } + if (params.type === 'progressbar') { + let progressbarDirection; + if (params.progressbarOpposite) { + progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal'; + } else { + progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical'; + } + const scale = (current + 1) / total; + let scaleX = 1; + let scaleY = 1; + if (progressbarDirection === 'horizontal') { + scaleX = scale; + } else { + scaleY = scale; + } + $el.find(`.${params.progressbarFillClass}`).transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`).transition(swiper.params.speed); + } + if (params.type === 'custom' && params.renderCustom) { + $el.html(params.renderCustom(swiper, current + 1, total)); + swiper.emit('paginationRender', swiper, $el[0]); + } else { + swiper.emit('paginationUpdate', swiper, $el[0]); + } + $el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + }, + render() { + // Render Container + const swiper = this; + const params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return; + const slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; + + const $el = swiper.pagination.$el; + let paginationHTML = ''; + if (params.type === 'bullets') { + const numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; + for (let i = 0; i < numberOfBullets; i += 1) { + if (params.renderBullet) { + paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass); + } else { + paginationHTML += `<${params.bulletElement} class="${params.bulletClass}">`; + } + } + $el.html(paginationHTML); + swiper.pagination.bullets = $el.find(`.${params.bulletClass}`); + } + if (params.type === 'fraction') { + if (params.renderFraction) { + paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass); + } else { + paginationHTML = `` + + ' / ' + + ``; + } + $el.html(paginationHTML); + } + if (params.type === 'progressbar') { + if (params.renderProgressbar) { + paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass); + } else { + paginationHTML = ``; + } + $el.html(paginationHTML); + } + if (params.type !== 'custom') { + swiper.emit('paginationRender', swiper.pagination.$el[0]); + } + }, + init() { + const swiper = this; + const params = swiper.params.pagination; + if (!params.el) return; + + let $el = $(params.el); + if ($el.length === 0) return; + + if ( + swiper.params.uniqueNavElements + && typeof params.el === 'string' + && $el.length > 1 + && swiper.$el.find(params.el).length === 1 + ) { + $el = swiper.$el.find(params.el); + } + + if (params.type === 'bullets' && params.clickable) { + $el.addClass(params.clickableClass); + } + + $el.addClass(params.modifierClass + params.type); + + if (params.type === 'bullets' && params.dynamicBullets) { + $el.addClass(`${params.modifierClass}${params.type}-dynamic`); + swiper.pagination.dynamicBulletIndex = 0; + if (params.dynamicMainBullets < 1) { + params.dynamicMainBullets = 1; + } + } + if (params.type === 'progressbar' && params.progressbarOpposite) { + $el.addClass(params.progressbarOppositeClass); + } + + if (params.clickable) { + $el.on('click', `.${params.bulletClass}`, function onClick(e) { + e.preventDefault(); + let index = $(this).index() * swiper.params.slidesPerGroup; + if (swiper.params.loop) index += swiper.loopedSlides; + swiper.slideTo(index); + }); + } + + Utils.extend(swiper.pagination, { + $el, + el: $el[0], + }); + }, + destroy() { + const swiper = this; + const params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) return; + const $el = swiper.pagination.$el; + + $el.removeClass(params.hiddenClass); + $el.removeClass(params.modifierClass + params.type); + if (swiper.pagination.bullets) swiper.pagination.bullets.removeClass(params.bulletActiveClass); + if (params.clickable) { + $el.off('click', `.${params.bulletClass}`); + } + }, +}; + +var pagination = { + name: 'pagination', + params: { + pagination: { + el: null, + bulletElement: 'span', + clickable: false, + hideOnClick: false, + renderBullet: null, + renderProgressbar: null, + renderFraction: null, + renderCustom: null, + progressbarOpposite: false, + type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom' + dynamicBullets: false, + dynamicMainBullets: 1, + formatFractionCurrent: number => number, + formatFractionTotal: number => number, + bulletClass: 'swiper-pagination-bullet', + bulletActiveClass: 'swiper-pagination-bullet-active', + modifierClass: 'swiper-pagination-', // NEW + currentClass: 'swiper-pagination-current', + totalClass: 'swiper-pagination-total', + hiddenClass: 'swiper-pagination-hidden', + progressbarFillClass: 'swiper-pagination-progressbar-fill', + progressbarOppositeClass: 'swiper-pagination-progressbar-opposite', + clickableClass: 'swiper-pagination-clickable', // NEW + lockClass: 'swiper-pagination-lock', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + pagination: { + init: Pagination.init.bind(swiper), + render: Pagination.render.bind(swiper), + update: Pagination.update.bind(swiper), + destroy: Pagination.destroy.bind(swiper), + dynamicBulletIndex: 0, + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.pagination.init(); + swiper.pagination.render(); + swiper.pagination.update(); + }, + activeIndexChange() { + const swiper = this; + if (swiper.params.loop) { + swiper.pagination.update(); + } else if (typeof swiper.snapIndex === 'undefined') { + swiper.pagination.update(); + } + }, + snapIndexChange() { + const swiper = this; + if (!swiper.params.loop) { + swiper.pagination.update(); + } + }, + slidesLengthChange() { + const swiper = this; + if (swiper.params.loop) { + swiper.pagination.render(); + swiper.pagination.update(); + } + }, + snapGridLengthChange() { + const swiper = this; + if (!swiper.params.loop) { + swiper.pagination.render(); + swiper.pagination.update(); + } + }, + destroy() { + const swiper = this; + swiper.pagination.destroy(); + }, + click(e) { + const swiper = this; + if ( + swiper.params.pagination.el + && swiper.params.pagination.hideOnClick + && swiper.pagination.$el.length > 0 + && !$(e.target).hasClass(swiper.params.pagination.bulletClass) + ) { + const isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass); + if (isHidden === true) { + swiper.emit('paginationShow', swiper); + } else { + swiper.emit('paginationHide', swiper); + } + swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass); + } + }, + }, +}; + +const Scrollbar = { + setTranslate() { + const swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; + const { scrollbar, rtlTranslate: rtl, progress } = swiper; + const { + dragSize, trackSize, $dragEl, $el, + } = scrollbar; + const params = swiper.params.scrollbar; + + let newSize = dragSize; + let newPos = (trackSize - dragSize) * progress; + if (rtl) { + newPos = -newPos; + if (newPos > 0) { + newSize = dragSize - newPos; + newPos = 0; + } else if (-newPos + dragSize > trackSize) { + newSize = trackSize + newPos; + } + } else if (newPos < 0) { + newSize = dragSize + newPos; + newPos = 0; + } else if (newPos + dragSize > trackSize) { + newSize = trackSize - newPos; + } + if (swiper.isHorizontal()) { + if (Support.transforms3d) { + $dragEl.transform(`translate3d(${newPos}px, 0, 0)`); + } else { + $dragEl.transform(`translateX(${newPos}px)`); + } + $dragEl[0].style.width = `${newSize}px`; + } else { + if (Support.transforms3d) { + $dragEl.transform(`translate3d(0px, ${newPos}px, 0)`); + } else { + $dragEl.transform(`translateY(${newPos}px)`); + } + $dragEl[0].style.height = `${newSize}px`; + } + if (params.hide) { + clearTimeout(swiper.scrollbar.timeout); + $el[0].style.opacity = 1; + swiper.scrollbar.timeout = setTimeout(() => { + $el[0].style.opacity = 0; + $el.transition(400); + }, 1000); + } + }, + setTransition(duration) { + const swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; + swiper.scrollbar.$dragEl.transition(duration); + }, + updateSize() { + const swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return; + + const { scrollbar } = swiper; + const { $dragEl, $el } = scrollbar; + + $dragEl[0].style.width = ''; + $dragEl[0].style.height = ''; + const trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight; + + const divider = swiper.size / swiper.virtualSize; + const moveDivider = divider * (trackSize / swiper.size); + let dragSize; + if (swiper.params.scrollbar.dragSize === 'auto') { + dragSize = trackSize * divider; + } else { + dragSize = parseInt(swiper.params.scrollbar.dragSize, 10); + } + + if (swiper.isHorizontal()) { + $dragEl[0].style.width = `${dragSize}px`; + } else { + $dragEl[0].style.height = `${dragSize}px`; + } + + if (divider >= 1) { + $el[0].style.display = 'none'; + } else { + $el[0].style.display = ''; + } + if (swiper.params.scrollbar.hide) { + $el[0].style.opacity = 0; + } + Utils.extend(scrollbar, { + trackSize, + divider, + moveDivider, + dragSize, + }); + scrollbar.$el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass); + }, + setDragPosition(e) { + const swiper = this; + const { scrollbar, rtlTranslate: rtl } = swiper; + const { $el, dragSize, trackSize } = scrollbar; + + let pointerPosition; + if (swiper.isHorizontal()) { + pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX); + } else { + pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY); + } + let positionRatio; + positionRatio = ((pointerPosition) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragSize / 2)) / (trackSize - dragSize); + positionRatio = Math.max(Math.min(positionRatio, 1), 0); + if (rtl) { + positionRatio = 1 - positionRatio; + } + + const position = swiper.minTranslate() + ((swiper.maxTranslate() - swiper.minTranslate()) * positionRatio); + + swiper.updateProgress(position); + swiper.setTranslate(position); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + }, + onDragStart(e) { + const swiper = this; + const params = swiper.params.scrollbar; + const { scrollbar, $wrapperEl } = swiper; + const { $el, $dragEl } = scrollbar; + swiper.scrollbar.isTouched = true; + e.preventDefault(); + e.stopPropagation(); + + $wrapperEl.transition(100); + $dragEl.transition(100); + scrollbar.setDragPosition(e); + + clearTimeout(swiper.scrollbar.dragTimeout); + + $el.transition(0); + if (params.hide) { + $el.css('opacity', 1); + } + swiper.emit('scrollbarDragStart', e); + }, + onDragMove(e) { + const swiper = this; + const { scrollbar, $wrapperEl } = swiper; + const { $el, $dragEl } = scrollbar; + + if (!swiper.scrollbar.isTouched) return; + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + scrollbar.setDragPosition(e); + $wrapperEl.transition(0); + $el.transition(0); + $dragEl.transition(0); + swiper.emit('scrollbarDragMove', e); + }, + onDragEnd(e) { + const swiper = this; + + const params = swiper.params.scrollbar; + const { scrollbar } = swiper; + const { $el } = scrollbar; + + if (!swiper.scrollbar.isTouched) return; + swiper.scrollbar.isTouched = false; + if (params.hide) { + clearTimeout(swiper.scrollbar.dragTimeout); + swiper.scrollbar.dragTimeout = Utils.nextTick(() => { + $el.css('opacity', 0); + $el.transition(400); + }, 1000); + } + swiper.emit('scrollbarDragEnd', e); + if (params.snapOnRelease) { + swiper.slideToClosest(); + } + }, + enableDraggable() { + const swiper = this; + if (!swiper.params.scrollbar.el) return; + const { + scrollbar, touchEventsTouch, touchEventsDesktop, params, + } = swiper; + const $el = scrollbar.$el; + const target = $el[0]; + const activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false; + const passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + if (!Support.touch) { + target.addEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener); + document.addEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener); + document.addEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener); + } else { + target.addEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener); + target.addEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener); + target.addEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener); + } + }, + disableDraggable() { + const swiper = this; + if (!swiper.params.scrollbar.el) return; + const { + scrollbar, touchEventsTouch, touchEventsDesktop, params, + } = swiper; + const $el = scrollbar.$el; + const target = $el[0]; + const activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false; + const passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + if (!Support.touch) { + target.removeEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener); + document.removeEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener); + document.removeEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener); + } else { + target.removeEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener); + target.removeEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener); + target.removeEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener); + } + }, + init() { + const swiper = this; + if (!swiper.params.scrollbar.el) return; + const { scrollbar, $el: $swiperEl } = swiper; + const params = swiper.params.scrollbar; + + let $el = $(params.el); + if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) { + $el = $swiperEl.find(params.el); + } + + let $dragEl = $el.find(`.${swiper.params.scrollbar.dragClass}`); + if ($dragEl.length === 0) { + $dragEl = $(`
            `); + $el.append($dragEl); + } + + Utils.extend(scrollbar, { + $el, + el: $el[0], + $dragEl, + dragEl: $dragEl[0], + }); + + if (params.draggable) { + scrollbar.enableDraggable(); + } + }, + destroy() { + const swiper = this; + swiper.scrollbar.disableDraggable(); + }, +}; + +var scrollbar = { + name: 'scrollbar', + params: { + scrollbar: { + el: null, + dragSize: 'auto', + hide: false, + draggable: false, + snapOnRelease: true, + lockClass: 'swiper-scrollbar-lock', + dragClass: 'swiper-scrollbar-drag', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + scrollbar: { + init: Scrollbar.init.bind(swiper), + destroy: Scrollbar.destroy.bind(swiper), + updateSize: Scrollbar.updateSize.bind(swiper), + setTranslate: Scrollbar.setTranslate.bind(swiper), + setTransition: Scrollbar.setTransition.bind(swiper), + enableDraggable: Scrollbar.enableDraggable.bind(swiper), + disableDraggable: Scrollbar.disableDraggable.bind(swiper), + setDragPosition: Scrollbar.setDragPosition.bind(swiper), + onDragStart: Scrollbar.onDragStart.bind(swiper), + onDragMove: Scrollbar.onDragMove.bind(swiper), + onDragEnd: Scrollbar.onDragEnd.bind(swiper), + isTouched: false, + timeout: null, + dragTimeout: null, + }, + }); + }, + on: { + init() { + const swiper = this; + swiper.scrollbar.init(); + swiper.scrollbar.updateSize(); + swiper.scrollbar.setTranslate(); + }, + update() { + const swiper = this; + swiper.scrollbar.updateSize(); + }, + resize() { + const swiper = this; + swiper.scrollbar.updateSize(); + }, + observerUpdate() { + const swiper = this; + swiper.scrollbar.updateSize(); + }, + setTranslate() { + const swiper = this; + swiper.scrollbar.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + swiper.scrollbar.setTransition(duration); + }, + destroy() { + const swiper = this; + swiper.scrollbar.destroy(); + }, + }, +}; + +const Parallax = { + setTransform(el, progress) { + const swiper = this; + const { rtl } = swiper; + + const $el = $(el); + const rtlFactor = rtl ? -1 : 1; + + const p = $el.attr('data-swiper-parallax') || '0'; + let x = $el.attr('data-swiper-parallax-x'); + let y = $el.attr('data-swiper-parallax-y'); + const scale = $el.attr('data-swiper-parallax-scale'); + const opacity = $el.attr('data-swiper-parallax-opacity'); + + if (x || y) { + x = x || '0'; + y = y || '0'; + } else if (swiper.isHorizontal()) { + x = p; + y = '0'; + } else { + y = p; + x = '0'; + } + + if ((x).indexOf('%') >= 0) { + x = `${parseInt(x, 10) * progress * rtlFactor}%`; + } else { + x = `${x * progress * rtlFactor}px`; + } + if ((y).indexOf('%') >= 0) { + y = `${parseInt(y, 10) * progress}%`; + } else { + y = `${y * progress}px`; + } + + if (typeof opacity !== 'undefined' && opacity !== null) { + const currentOpacity = opacity - ((opacity - 1) * (1 - Math.abs(progress))); + $el[0].style.opacity = currentOpacity; + } + if (typeof scale === 'undefined' || scale === null) { + $el.transform(`translate3d(${x}, ${y}, 0px)`); + } else { + const currentScale = scale - ((scale - 1) * (1 - Math.abs(progress))); + $el.transform(`translate3d(${x}, ${y}, 0px) scale(${currentScale})`); + } + }, + setTranslate() { + const swiper = this; + const { + $el, slides, progress, snapGrid, + } = swiper; + $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each((index, el) => { + swiper.parallax.setTransform(el, progress); + }); + slides.each((slideIndex, slideEl) => { + let slideProgress = slideEl.progress; + if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') { + slideProgress += Math.ceil(slideIndex / 2) - (progress * (snapGrid.length - 1)); + } + slideProgress = Math.min(Math.max(slideProgress, -1), 1); + $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each((index, el) => { + swiper.parallax.setTransform(el, slideProgress); + }); + }); + }, + setTransition(duration = this.params.speed) { + const swiper = this; + const { $el } = swiper; + $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each((index, parallaxEl) => { + const $parallaxEl = $(parallaxEl); + let parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration; + if (duration === 0) parallaxDuration = 0; + $parallaxEl.transition(parallaxDuration); + }); + }, +}; + +var parallax = { + name: 'parallax', + params: { + parallax: { + enabled: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + parallax: { + setTransform: Parallax.setTransform.bind(swiper), + setTranslate: Parallax.setTranslate.bind(swiper), + setTransition: Parallax.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.params.watchSlidesProgress = true; + swiper.originalParams.watchSlidesProgress = true; + }, + init() { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.parallax.setTranslate(); + }, + setTranslate() { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.parallax.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (!swiper.params.parallax.enabled) return; + swiper.parallax.setTransition(duration); + }, + }, +}; + +const Zoom = { + // Calc Scale From Multi-touches + getDistanceBetweenTouches(e) { + if (e.targetTouches.length < 2) return 1; + const x1 = e.targetTouches[0].pageX; + const y1 = e.targetTouches[0].pageY; + const x2 = e.targetTouches[1].pageX; + const y2 = e.targetTouches[1].pageY; + const distance = Math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2)); + return distance; + }, + // Events + onGestureStart(e) { + const swiper = this; + const params = swiper.params.zoom; + const zoom = swiper.zoom; + const { gesture } = zoom; + zoom.fakeGestureTouched = false; + zoom.fakeGestureMoved = false; + if (!Support.gestures) { + if (e.type !== 'touchstart' || (e.type === 'touchstart' && e.targetTouches.length < 2)) { + return; + } + zoom.fakeGestureTouched = true; + gesture.scaleStart = Zoom.getDistanceBetweenTouches(e); + } + if (!gesture.$slideEl || !gesture.$slideEl.length) { + gesture.$slideEl = $(e.target).closest('.swiper-slide'); + if (gesture.$slideEl.length === 0) gesture.$slideEl = swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); + gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + if (gesture.$imageWrapEl.length === 0) { + gesture.$imageEl = undefined; + return; + } + } + gesture.$imageEl.transition(0); + swiper.zoom.isScaling = true; + }, + onGestureChange(e) { + const swiper = this; + const params = swiper.params.zoom; + const zoom = swiper.zoom; + const { gesture } = zoom; + if (!Support.gestures) { + if (e.type !== 'touchmove' || (e.type === 'touchmove' && e.targetTouches.length < 2)) { + return; + } + zoom.fakeGestureMoved = true; + gesture.scaleMove = Zoom.getDistanceBetweenTouches(e); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + if (Support.gestures) { + zoom.scale = e.scale * zoom.currentScale; + } else { + zoom.scale = (gesture.scaleMove / gesture.scaleStart) * zoom.currentScale; + } + if (zoom.scale > gesture.maxRatio) { + zoom.scale = (gesture.maxRatio - 1) + (((zoom.scale - gesture.maxRatio) + 1) ** 0.5); + } + if (zoom.scale < params.minRatio) { + zoom.scale = (params.minRatio + 1) - (((params.minRatio - zoom.scale) + 1) ** 0.5); + } + gesture.$imageEl.transform(`translate3d(0,0,0) scale(${zoom.scale})`); + }, + onGestureEnd(e) { + const swiper = this; + const params = swiper.params.zoom; + const zoom = swiper.zoom; + const { gesture } = zoom; + if (!Support.gestures) { + if (!zoom.fakeGestureTouched || !zoom.fakeGestureMoved) { + return; + } + if (e.type !== 'touchend' || (e.type === 'touchend' && e.changedTouches.length < 2 && !Device.android)) { + return; + } + zoom.fakeGestureTouched = false; + zoom.fakeGestureMoved = false; + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio); + gesture.$imageEl.transition(swiper.params.speed).transform(`translate3d(0,0,0) scale(${zoom.scale})`); + zoom.currentScale = zoom.scale; + zoom.isScaling = false; + if (zoom.scale === 1) gesture.$slideEl = undefined; + }, + onTouchStart(e) { + const swiper = this; + const zoom = swiper.zoom; + const { gesture, image } = zoom; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + if (image.isTouched) return; + if (Device.android) e.preventDefault(); + image.isTouched = true; + image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; + image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; + }, + onTouchMove(e) { + const swiper = this; + const zoom = swiper.zoom; + const { gesture, image, velocity } = zoom; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + swiper.allowClick = false; + if (!image.isTouched || !gesture.$slideEl) return; + + if (!image.isMoved) { + image.width = gesture.$imageEl[0].offsetWidth; + image.height = gesture.$imageEl[0].offsetHeight; + image.startX = Utils.getTranslate(gesture.$imageWrapEl[0], 'x') || 0; + image.startY = Utils.getTranslate(gesture.$imageWrapEl[0], 'y') || 0; + gesture.slideWidth = gesture.$slideEl[0].offsetWidth; + gesture.slideHeight = gesture.$slideEl[0].offsetHeight; + gesture.$imageWrapEl.transition(0); + if (swiper.rtl) { + image.startX = -image.startX; + image.startY = -image.startY; + } + } + // Define if we need image drag + const scaledWidth = image.width * zoom.scale; + const scaledHeight = image.height * zoom.scale; + + if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) return; + + image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0); + image.maxX = -image.minX; + image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0); + image.maxY = -image.minY; + + image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; + image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; + + if (!image.isMoved && !zoom.isScaling) { + if ( + swiper.isHorizontal() + && ( + (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x) + || (Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x) + ) + ) { + image.isTouched = false; + return; + } if ( + !swiper.isHorizontal() + && ( + (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y) + || (Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y) + ) + ) { + image.isTouched = false; + return; + } + } + e.preventDefault(); + e.stopPropagation(); + + image.isMoved = true; + image.currentX = (image.touchesCurrent.x - image.touchesStart.x) + image.startX; + image.currentY = (image.touchesCurrent.y - image.touchesStart.y) + image.startY; + + if (image.currentX < image.minX) { + image.currentX = (image.minX + 1) - (((image.minX - image.currentX) + 1) ** 0.8); + } + if (image.currentX > image.maxX) { + image.currentX = (image.maxX - 1) + (((image.currentX - image.maxX) + 1) ** 0.8); + } + + if (image.currentY < image.minY) { + image.currentY = (image.minY + 1) - (((image.minY - image.currentY) + 1) ** 0.8); + } + if (image.currentY > image.maxY) { + image.currentY = (image.maxY - 1) + (((image.currentY - image.maxY) + 1) ** 0.8); + } + + // Velocity + if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x; + if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y; + if (!velocity.prevTime) velocity.prevTime = Date.now(); + velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2; + velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2; + if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) velocity.x = 0; + if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) velocity.y = 0; + velocity.prevPositionX = image.touchesCurrent.x; + velocity.prevPositionY = image.touchesCurrent.y; + velocity.prevTime = Date.now(); + + gesture.$imageWrapEl.transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`); + }, + onTouchEnd() { + const swiper = this; + const zoom = swiper.zoom; + const { gesture, image, velocity } = zoom; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + if (!image.isTouched || !image.isMoved) { + image.isTouched = false; + image.isMoved = false; + return; + } + image.isTouched = false; + image.isMoved = false; + let momentumDurationX = 300; + let momentumDurationY = 300; + const momentumDistanceX = velocity.x * momentumDurationX; + const newPositionX = image.currentX + momentumDistanceX; + const momentumDistanceY = velocity.y * momentumDurationY; + const newPositionY = image.currentY + momentumDistanceY; + + // Fix duration + if (velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x); + if (velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y); + const momentumDuration = Math.max(momentumDurationX, momentumDurationY); + + image.currentX = newPositionX; + image.currentY = newPositionY; + + // Define if we need image drag + const scaledWidth = image.width * zoom.scale; + const scaledHeight = image.height * zoom.scale; + image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0); + image.maxX = -image.minX; + image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0); + image.maxY = -image.minY; + image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX); + image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY); + + gesture.$imageWrapEl.transition(momentumDuration).transform(`translate3d(${image.currentX}px, ${image.currentY}px,0)`); + }, + onTransitionEnd() { + const swiper = this; + const zoom = swiper.zoom; + const { gesture } = zoom; + if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) { + gesture.$imageEl.transform('translate3d(0,0,0) scale(1)'); + gesture.$imageWrapEl.transform('translate3d(0,0,0)'); + + zoom.scale = 1; + zoom.currentScale = 1; + + gesture.$slideEl = undefined; + gesture.$imageEl = undefined; + gesture.$imageWrapEl = undefined; + } + }, + // Toggle Zoom + toggle(e) { + const swiper = this; + const zoom = swiper.zoom; + + if (zoom.scale && zoom.scale !== 1) { + // Zoom Out + zoom.out(); + } else { + // Zoom In + zoom.in(e); + } + }, + in(e) { + const swiper = this; + + const zoom = swiper.zoom; + const params = swiper.params.zoom; + const { gesture, image } = zoom; + + if (!gesture.$slideEl) { + gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + + gesture.$slideEl.addClass(`${params.zoomedSlideClass}`); + + let touchX; + let touchY; + let offsetX; + let offsetY; + let diffX; + let diffY; + let translateX; + let translateY; + let imageWidth; + let imageHeight; + let scaledWidth; + let scaledHeight; + let translateMinX; + let translateMinY; + let translateMaxX; + let translateMaxY; + let slideWidth; + let slideHeight; + + if (typeof image.touchesStart.x === 'undefined' && e) { + touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX; + touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY; + } else { + touchX = image.touchesStart.x; + touchY = image.touchesStart.y; + } + + zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + zoom.currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + if (e) { + slideWidth = gesture.$slideEl[0].offsetWidth; + slideHeight = gesture.$slideEl[0].offsetHeight; + offsetX = gesture.$slideEl.offset().left; + offsetY = gesture.$slideEl.offset().top; + diffX = (offsetX + (slideWidth / 2)) - touchX; + diffY = (offsetY + (slideHeight / 2)) - touchY; + + imageWidth = gesture.$imageEl[0].offsetWidth; + imageHeight = gesture.$imageEl[0].offsetHeight; + scaledWidth = imageWidth * zoom.scale; + scaledHeight = imageHeight * zoom.scale; + + translateMinX = Math.min(((slideWidth / 2) - (scaledWidth / 2)), 0); + translateMinY = Math.min(((slideHeight / 2) - (scaledHeight / 2)), 0); + translateMaxX = -translateMinX; + translateMaxY = -translateMinY; + + translateX = diffX * zoom.scale; + translateY = diffY * zoom.scale; + + if (translateX < translateMinX) { + translateX = translateMinX; + } + if (translateX > translateMaxX) { + translateX = translateMaxX; + } + + if (translateY < translateMinY) { + translateY = translateMinY; + } + if (translateY > translateMaxY) { + translateY = translateMaxY; + } + } else { + translateX = 0; + translateY = 0; + } + gesture.$imageWrapEl.transition(300).transform(`translate3d(${translateX}px, ${translateY}px,0)`); + gesture.$imageEl.transition(300).transform(`translate3d(0,0,0) scale(${zoom.scale})`); + }, + out() { + const swiper = this; + + const zoom = swiper.zoom; + const params = swiper.params.zoom; + const { gesture } = zoom; + + if (!gesture.$slideEl) { + gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(`.${params.containerClass}`); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) return; + + zoom.scale = 1; + zoom.currentScale = 1; + gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)'); + gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)'); + gesture.$slideEl.removeClass(`${params.zoomedSlideClass}`); + gesture.$slideEl = undefined; + }, + // Attach/Detach Events + enable() { + const swiper = this; + const zoom = swiper.zoom; + if (zoom.enabled) return; + zoom.enabled = true; + + const passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false; + + // Scale image + if (Support.gestures) { + swiper.$wrapperEl.on('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.on('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.on('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener); + } else if (swiper.touchEvents.start === 'touchstart') { + swiper.$wrapperEl.on(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.on(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.on(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener); + } + + // Move image + swiper.$wrapperEl.on(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, zoom.onTouchMove); + }, + disable() { + const swiper = this; + const zoom = swiper.zoom; + if (!zoom.enabled) return; + + swiper.zoom.enabled = false; + + const passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false; + + // Scale image + if (Support.gestures) { + swiper.$wrapperEl.off('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.off('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.off('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener); + } else if (swiper.touchEvents.start === 'touchstart') { + swiper.$wrapperEl.off(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.off(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.off(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener); + } + + // Move image + swiper.$wrapperEl.off(swiper.touchEvents.move, `.${swiper.params.zoom.containerClass}`, zoom.onTouchMove); + }, +}; + +var zoom = { + name: 'zoom', + params: { + zoom: { + enabled: false, + maxRatio: 3, + minRatio: 1, + toggle: true, + containerClass: 'swiper-zoom-container', + zoomedSlideClass: 'swiper-slide-zoomed', + }, + }, + create() { + const swiper = this; + const zoom = { + enabled: false, + scale: 1, + currentScale: 1, + isScaling: false, + gesture: { + $slideEl: undefined, + slideWidth: undefined, + slideHeight: undefined, + $imageEl: undefined, + $imageWrapEl: undefined, + maxRatio: 3, + }, + image: { + isTouched: undefined, + isMoved: undefined, + currentX: undefined, + currentY: undefined, + minX: undefined, + minY: undefined, + maxX: undefined, + maxY: undefined, + width: undefined, + height: undefined, + startX: undefined, + startY: undefined, + touchesStart: {}, + touchesCurrent: {}, + }, + velocity: { + x: undefined, + y: undefined, + prevPositionX: undefined, + prevPositionY: undefined, + prevTime: undefined, + }, + }; + + ('onGestureStart onGestureChange onGestureEnd onTouchStart onTouchMove onTouchEnd onTransitionEnd toggle enable disable in out').split(' ').forEach((methodName) => { + zoom[methodName] = Zoom[methodName].bind(swiper); + }); + Utils.extend(swiper, { + zoom, + }); + + let scale = 1; + Object.defineProperty(swiper.zoom, 'scale', { + get() { + return scale; + }, + set(value) { + if (scale !== value) { + const imageEl = swiper.zoom.gesture.$imageEl ? swiper.zoom.gesture.$imageEl[0] : undefined; + const slideEl = swiper.zoom.gesture.$slideEl ? swiper.zoom.gesture.$slideEl[0] : undefined; + swiper.emit('zoomChange', value, imageEl, slideEl); + } + scale = value; + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.zoom.enabled) { + swiper.zoom.enable(); + } + }, + destroy() { + const swiper = this; + swiper.zoom.disable(); + }, + touchStart(e) { + const swiper = this; + if (!swiper.zoom.enabled) return; + swiper.zoom.onTouchStart(e); + }, + touchEnd(e) { + const swiper = this; + if (!swiper.zoom.enabled) return; + swiper.zoom.onTouchEnd(e); + }, + doubleTap(e) { + const swiper = this; + if (swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) { + swiper.zoom.toggle(e); + } + }, + transitionEnd() { + const swiper = this; + if (swiper.zoom.enabled && swiper.params.zoom.enabled) { + swiper.zoom.onTransitionEnd(); + } + }, + }, +}; + +const Lazy = { + loadInSlide(index, loadInDuplicate = true) { + const swiper = this; + const params = swiper.params.lazy; + if (typeof index === 'undefined') return; + if (swiper.slides.length === 0) return; + const isVirtual = swiper.virtual && swiper.params.virtual.enabled; + + const $slideEl = isVirtual + ? swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-swiper-slide-index="${index}"]`) + : swiper.slides.eq(index); + + let $images = $slideEl.find(`.${params.elementClass}:not(.${params.loadedClass}):not(.${params.loadingClass})`); + if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) { + $images = $images.add($slideEl[0]); + } + if ($images.length === 0) return; + + $images.each((imageIndex, imageEl) => { + const $imageEl = $(imageEl); + $imageEl.addClass(params.loadingClass); + + const background = $imageEl.attr('data-background'); + const src = $imageEl.attr('data-src'); + const srcset = $imageEl.attr('data-srcset'); + const sizes = $imageEl.attr('data-sizes'); + + swiper.loadImage($imageEl[0], (src || background), srcset, sizes, false, () => { + if (typeof swiper === 'undefined' || swiper === null || !swiper || (swiper && !swiper.params) || swiper.destroyed) return; + if (background) { + $imageEl.css('background-image', `url("${background}")`); + $imageEl.removeAttr('data-background'); + } else { + if (srcset) { + $imageEl.attr('srcset', srcset); + $imageEl.removeAttr('data-srcset'); + } + if (sizes) { + $imageEl.attr('sizes', sizes); + $imageEl.removeAttr('data-sizes'); + } + if (src) { + $imageEl.attr('src', src); + $imageEl.removeAttr('data-src'); + } + } + + $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass); + $slideEl.find(`.${params.preloaderClass}`).remove(); + if (swiper.params.loop && loadInDuplicate) { + const slideOriginalIndex = $slideEl.attr('data-swiper-slide-index'); + if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) { + const originalSlide = swiper.$wrapperEl.children(`[data-swiper-slide-index="${slideOriginalIndex}"]:not(.${swiper.params.slideDuplicateClass})`); + swiper.lazy.loadInSlide(originalSlide.index(), false); + } else { + const duplicatedSlide = swiper.$wrapperEl.children(`.${swiper.params.slideDuplicateClass}[data-swiper-slide-index="${slideOriginalIndex}"]`); + swiper.lazy.loadInSlide(duplicatedSlide.index(), false); + } + } + swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]); + }); + + swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]); + }); + }, + load() { + const swiper = this; + const { + $wrapperEl, params: swiperParams, slides, activeIndex, + } = swiper; + const isVirtual = swiper.virtual && swiperParams.virtual.enabled; + const params = swiperParams.lazy; + + let slidesPerView = swiperParams.slidesPerView; + if (slidesPerView === 'auto') { + slidesPerView = 0; + } + + function slideExist(index) { + if (isVirtual) { + if ($wrapperEl.children(`.${swiperParams.slideClass}[data-swiper-slide-index="${index}"]`).length) { + return true; + } + } else if (slides[index]) return true; + return false; + } + function slideIndex(slideEl) { + if (isVirtual) { + return $(slideEl).attr('data-swiper-slide-index'); + } + return $(slideEl).index(); + } + + if (!swiper.lazy.initialImageLoaded) swiper.lazy.initialImageLoaded = true; + if (swiper.params.watchSlidesVisibility) { + $wrapperEl.children(`.${swiperParams.slideVisibleClass}`).each((elIndex, slideEl) => { + const index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index(); + swiper.lazy.loadInSlide(index); + }); + } else if (slidesPerView > 1) { + for (let i = activeIndex; i < activeIndex + slidesPerView; i += 1) { + if (slideExist(i)) swiper.lazy.loadInSlide(i); + } + } else { + swiper.lazy.loadInSlide(activeIndex); + } + if (params.loadPrevNext) { + if (slidesPerView > 1 || (params.loadPrevNextAmount && params.loadPrevNextAmount > 1)) { + const amount = params.loadPrevNextAmount; + const spv = slidesPerView; + const maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length); + const minIndex = Math.max(activeIndex - Math.max(spv, amount), 0); + // Next Slides + for (let i = activeIndex + slidesPerView; i < maxIndex; i += 1) { + if (slideExist(i)) swiper.lazy.loadInSlide(i); + } + // Prev Slides + for (let i = minIndex; i < activeIndex; i += 1) { + if (slideExist(i)) swiper.lazy.loadInSlide(i); + } + } else { + const nextSlide = $wrapperEl.children(`.${swiperParams.slideNextClass}`); + if (nextSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(nextSlide)); + + const prevSlide = $wrapperEl.children(`.${swiperParams.slidePrevClass}`); + if (prevSlide.length > 0) swiper.lazy.loadInSlide(slideIndex(prevSlide)); + } + } + }, +}; + +var lazy = { + name: 'lazy', + params: { + lazy: { + enabled: false, + loadPrevNext: false, + loadPrevNextAmount: 1, + loadOnTransitionStart: false, + + elementClass: 'swiper-lazy', + loadingClass: 'swiper-lazy-loading', + loadedClass: 'swiper-lazy-loaded', + preloaderClass: 'swiper-lazy-preloader', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + lazy: { + initialImageLoaded: false, + load: Lazy.load.bind(swiper), + loadInSlide: Lazy.loadInSlide.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.lazy.enabled && swiper.params.preloadImages) { + swiper.params.preloadImages = false; + } + }, + init() { + const swiper = this; + if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) { + swiper.lazy.load(); + } + }, + scroll() { + const swiper = this; + if (swiper.params.freeMode && !swiper.params.freeModeSticky) { + swiper.lazy.load(); + } + }, + resize() { + const swiper = this; + if (swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + }, + scrollbarDragMove() { + const swiper = this; + if (swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + }, + transitionStart() { + const swiper = this; + if (swiper.params.lazy.enabled) { + if (swiper.params.lazy.loadOnTransitionStart || (!swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded)) { + swiper.lazy.load(); + } + } + }, + transitionEnd() { + const swiper = this; + if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) { + swiper.lazy.load(); + } + }, + }, +}; + +/* eslint no-bitwise: ["error", { "allow": [">>"] }] */ + +const Controller = { + LinearSpline: function LinearSpline(x, y) { + const binarySearch = (function search() { + let maxIndex; + let minIndex; + let guess; + return (array, val) => { + minIndex = -1; + maxIndex = array.length; + while (maxIndex - minIndex > 1) { + guess = maxIndex + minIndex >> 1; + if (array[guess] <= val) { + minIndex = guess; + } else { + maxIndex = guess; + } + } + return maxIndex; + }; + }()); + this.x = x; + this.y = y; + this.lastIndex = x.length - 1; + // Given an x value (x2), return the expected y2 value: + // (x1,y1) is the known point before given value, + // (x3,y3) is the known point after given value. + let i1; + let i3; + + this.interpolate = function interpolate(x2) { + if (!x2) return 0; + + // Get the indexes of x1 and x3 (the array indexes before and after given x2): + i3 = binarySearch(this.x, x2); + i1 = i3 - 1; + + // We have our indexes i1 & i3, so we can calculate already: + // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1 + return (((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1])) + this.y[i1]; + }; + return this; + }, + // xxx: for now i will just save one spline function to to + getInterpolateFunction(c) { + const swiper = this; + if (!swiper.controller.spline) { + swiper.controller.spline = swiper.params.loop + ? new Controller.LinearSpline(swiper.slidesGrid, c.slidesGrid) + : new Controller.LinearSpline(swiper.snapGrid, c.snapGrid); + } + }, + setTranslate(setTranslate, byController) { + const swiper = this; + const controlled = swiper.controller.control; + let multiplier; + let controlledTranslate; + function setControlledTranslate(c) { + // this will create an Interpolate function based on the snapGrids + // x is the Grid of the scrolled scroller and y will be the controlled scroller + // it makes sense to create this only once and recall it for the interpolation + // the function does a lot of value caching for performance + const translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate; + if (swiper.params.controller.by === 'slide') { + swiper.controller.getInterpolateFunction(c); + // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid + // but it did not work out + controlledTranslate = -swiper.controller.spline.interpolate(-translate); + } + + if (!controlledTranslate || swiper.params.controller.by === 'container') { + multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate()); + controlledTranslate = ((translate - swiper.minTranslate()) * multiplier) + c.minTranslate(); + } + + if (swiper.params.controller.inverse) { + controlledTranslate = c.maxTranslate() - controlledTranslate; + } + c.updateProgress(controlledTranslate); + c.setTranslate(controlledTranslate, swiper); + c.updateActiveIndex(); + c.updateSlidesClasses(); + } + if (Array.isArray(controlled)) { + for (let i = 0; i < controlled.length; i += 1) { + if (controlled[i] !== byController && controlled[i] instanceof Swiper) { + setControlledTranslate(controlled[i]); + } + } + } else if (controlled instanceof Swiper && byController !== controlled) { + setControlledTranslate(controlled); + } + }, + setTransition(duration, byController) { + const swiper = this; + const controlled = swiper.controller.control; + let i; + function setControlledTransition(c) { + c.setTransition(duration, swiper); + if (duration !== 0) { + c.transitionStart(); + if (c.params.autoHeight) { + Utils.nextTick(() => { + c.updateAutoHeight(); + }); + } + c.$wrapperEl.transitionEnd(() => { + if (!controlled) return; + if (c.params.loop && swiper.params.controller.by === 'slide') { + c.loopFix(); + } + c.transitionEnd(); + }); + } + } + if (Array.isArray(controlled)) { + for (i = 0; i < controlled.length; i += 1) { + if (controlled[i] !== byController && controlled[i] instanceof Swiper) { + setControlledTransition(controlled[i]); + } + } + } else if (controlled instanceof Swiper && byController !== controlled) { + setControlledTransition(controlled); + } + }, +}; +var controller = { + name: 'controller', + params: { + controller: { + control: undefined, + inverse: false, + by: 'slide', // or 'container' + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + controller: { + control: swiper.params.controller.control, + getInterpolateFunction: Controller.getInterpolateFunction.bind(swiper), + setTranslate: Controller.setTranslate.bind(swiper), + setTransition: Controller.setTransition.bind(swiper), + }, + }); + }, + on: { + update() { + const swiper = this; + if (!swiper.controller.control) return; + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + resize() { + const swiper = this; + if (!swiper.controller.control) return; + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + observerUpdate() { + const swiper = this; + if (!swiper.controller.control) return; + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + setTranslate(translate, byController) { + const swiper = this; + if (!swiper.controller.control) return; + swiper.controller.setTranslate(translate, byController); + }, + setTransition(duration, byController) { + const swiper = this; + if (!swiper.controller.control) return; + swiper.controller.setTransition(duration, byController); + }, + }, +}; + +const a11y = { + makeElFocusable($el) { + $el.attr('tabIndex', '0'); + return $el; + }, + addElRole($el, role) { + $el.attr('role', role); + return $el; + }, + addElLabel($el, label) { + $el.attr('aria-label', label); + return $el; + }, + disableEl($el) { + $el.attr('aria-disabled', true); + return $el; + }, + enableEl($el) { + $el.attr('aria-disabled', false); + return $el; + }, + onEnterKey(e) { + const swiper = this; + const params = swiper.params.a11y; + if (e.keyCode !== 13) return; + const $targetEl = $(e.target); + if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) { + if (!(swiper.isEnd && !swiper.params.loop)) { + swiper.slideNext(); + } + if (swiper.isEnd) { + swiper.a11y.notify(params.lastSlideMessage); + } else { + swiper.a11y.notify(params.nextSlideMessage); + } + } + if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) { + if (!(swiper.isBeginning && !swiper.params.loop)) { + swiper.slidePrev(); + } + if (swiper.isBeginning) { + swiper.a11y.notify(params.firstSlideMessage); + } else { + swiper.a11y.notify(params.prevSlideMessage); + } + } + if (swiper.pagination && $targetEl.is(`.${swiper.params.pagination.bulletClass}`)) { + $targetEl[0].click(); + } + }, + notify(message) { + const swiper = this; + const notification = swiper.a11y.liveRegion; + if (notification.length === 0) return; + notification.html(''); + notification.html(message); + }, + updateNavigation() { + const swiper = this; + + if (swiper.params.loop) return; + const { $nextEl, $prevEl } = swiper.navigation; + + if ($prevEl && $prevEl.length > 0) { + if (swiper.isBeginning) { + swiper.a11y.disableEl($prevEl); + } else { + swiper.a11y.enableEl($prevEl); + } + } + if ($nextEl && $nextEl.length > 0) { + if (swiper.isEnd) { + swiper.a11y.disableEl($nextEl); + } else { + swiper.a11y.enableEl($nextEl); + } + } + }, + updatePagination() { + const swiper = this; + const params = swiper.params.a11y; + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.bullets.each((bulletIndex, bulletEl) => { + const $bulletEl = $(bulletEl); + swiper.a11y.makeElFocusable($bulletEl); + swiper.a11y.addElRole($bulletEl, 'button'); + swiper.a11y.addElLabel($bulletEl, params.paginationBulletMessage.replace(/{{index}}/, $bulletEl.index() + 1)); + }); + } + }, + init() { + const swiper = this; + + swiper.$el.append(swiper.a11y.liveRegion); + + // Navigation + const params = swiper.params.a11y; + let $nextEl; + let $prevEl; + if (swiper.navigation && swiper.navigation.$nextEl) { + $nextEl = swiper.navigation.$nextEl; + } + if (swiper.navigation && swiper.navigation.$prevEl) { + $prevEl = swiper.navigation.$prevEl; + } + if ($nextEl) { + swiper.a11y.makeElFocusable($nextEl); + swiper.a11y.addElRole($nextEl, 'button'); + swiper.a11y.addElLabel($nextEl, params.nextSlideMessage); + $nextEl.on('keydown', swiper.a11y.onEnterKey); + } + if ($prevEl) { + swiper.a11y.makeElFocusable($prevEl); + swiper.a11y.addElRole($prevEl, 'button'); + swiper.a11y.addElLabel($prevEl, params.prevSlideMessage); + $prevEl.on('keydown', swiper.a11y.onEnterKey); + } + + // Pagination + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.$el.on('keydown', `.${swiper.params.pagination.bulletClass}`, swiper.a11y.onEnterKey); + } + }, + destroy() { + const swiper = this; + if (swiper.a11y.liveRegion && swiper.a11y.liveRegion.length > 0) swiper.a11y.liveRegion.remove(); + + let $nextEl; + let $prevEl; + if (swiper.navigation && swiper.navigation.$nextEl) { + $nextEl = swiper.navigation.$nextEl; + } + if (swiper.navigation && swiper.navigation.$prevEl) { + $prevEl = swiper.navigation.$prevEl; + } + if ($nextEl) { + $nextEl.off('keydown', swiper.a11y.onEnterKey); + } + if ($prevEl) { + $prevEl.off('keydown', swiper.a11y.onEnterKey); + } + + // Pagination + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.$el.off('keydown', `.${swiper.params.pagination.bulletClass}`, swiper.a11y.onEnterKey); + } + }, +}; +var a11y$1 = { + name: 'a11y', + params: { + a11y: { + enabled: true, + notificationClass: 'swiper-notification', + prevSlideMessage: 'Previous slide', + nextSlideMessage: 'Next slide', + firstSlideMessage: 'This is the first slide', + lastSlideMessage: 'This is the last slide', + paginationBulletMessage: 'Go to slide {{index}}', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + a11y: { + liveRegion: $(``), + }, + }); + Object.keys(a11y).forEach((methodName) => { + swiper.a11y[methodName] = a11y[methodName].bind(swiper); + }); + }, + on: { + init() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.init(); + swiper.a11y.updateNavigation(); + }, + toEdge() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.updateNavigation(); + }, + fromEdge() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.updateNavigation(); + }, + paginationUpdate() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.updatePagination(); + }, + destroy() { + const swiper = this; + if (!swiper.params.a11y.enabled) return; + swiper.a11y.destroy(); + }, + }, +}; + +const History = { + init() { + const swiper = this; + if (!swiper.params.history) return; + if (!window.history || !window.history.pushState) { + swiper.params.history.enabled = false; + swiper.params.hashNavigation.enabled = true; + return; + } + const history = swiper.history; + history.initialized = true; + history.paths = History.getPathValues(); + if (!history.paths.key && !history.paths.value) return; + history.scrollToSlide(0, history.paths.value, swiper.params.runCallbacksOnInit); + if (!swiper.params.history.replaceState) { + window.addEventListener('popstate', swiper.history.setHistoryPopState); + } + }, + destroy() { + const swiper = this; + if (!swiper.params.history.replaceState) { + window.removeEventListener('popstate', swiper.history.setHistoryPopState); + } + }, + setHistoryPopState() { + const swiper = this; + swiper.history.paths = History.getPathValues(); + swiper.history.scrollToSlide(swiper.params.speed, swiper.history.paths.value, false); + }, + getPathValues() { + const pathArray = window.location.pathname.slice(1).split('/').filter(part => part !== ''); + const total = pathArray.length; + const key = pathArray[total - 2]; + const value = pathArray[total - 1]; + return { key, value }; + }, + setHistory(key, index) { + const swiper = this; + if (!swiper.history.initialized || !swiper.params.history.enabled) return; + const slide = swiper.slides.eq(index); + let value = History.slugify(slide.attr('data-history')); + if (!window.location.pathname.includes(key)) { + value = `${key}/${value}`; + } + const currentState = window.history.state; + if (currentState && currentState.value === value) { + return; + } + if (swiper.params.history.replaceState) { + window.history.replaceState({ value }, null, value); + } else { + window.history.pushState({ value }, null, value); + } + }, + slugify(text) { + return text.toString() + .replace(/\s+/g, '-') + .replace(/[^\w-]+/g, '') + .replace(/--+/g, '-') + .replace(/^-+/, '') + .replace(/-+$/, ''); + }, + scrollToSlide(speed, value, runCallbacks) { + const swiper = this; + if (value) { + for (let i = 0, length = swiper.slides.length; i < length; i += 1) { + const slide = swiper.slides.eq(i); + const slideHistory = History.slugify(slide.attr('data-history')); + if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) { + const index = slide.index(); + swiper.slideTo(index, speed, runCallbacks); + } + } + } else { + swiper.slideTo(0, speed, runCallbacks); + } + }, +}; + +var history = { + name: 'history', + params: { + history: { + enabled: false, + replaceState: false, + key: 'slides', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + history: { + init: History.init.bind(swiper), + setHistory: History.setHistory.bind(swiper), + setHistoryPopState: History.setHistoryPopState.bind(swiper), + scrollToSlide: History.scrollToSlide.bind(swiper), + destroy: History.destroy.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.history.enabled) { + swiper.history.init(); + } + }, + destroy() { + const swiper = this; + if (swiper.params.history.enabled) { + swiper.history.destroy(); + } + }, + transitionEnd() { + const swiper = this; + if (swiper.history.initialized) { + swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex); + } + }, + }, +}; + +const HashNavigation = { + onHashCange() { + const swiper = this; + const newHash = document.location.hash.replace('#', ''); + const activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash'); + if (newHash !== activeSlideHash) { + const newIndex = swiper.$wrapperEl.children(`.${swiper.params.slideClass}[data-hash="${newHash}"]`).index(); + if (typeof newIndex === 'undefined') return; + swiper.slideTo(newIndex); + } + }, + setHash() { + const swiper = this; + if (!swiper.hashNavigation.initialized || !swiper.params.hashNavigation.enabled) return; + if (swiper.params.hashNavigation.replaceState && window.history && window.history.replaceState) { + window.history.replaceState(null, null, (`#${swiper.slides.eq(swiper.activeIndex).attr('data-hash')}` || '')); + } else { + const slide = swiper.slides.eq(swiper.activeIndex); + const hash = slide.attr('data-hash') || slide.attr('data-history'); + document.location.hash = hash || ''; + } + }, + init() { + const swiper = this; + if (!swiper.params.hashNavigation.enabled || (swiper.params.history && swiper.params.history.enabled)) return; + swiper.hashNavigation.initialized = true; + const hash = document.location.hash.replace('#', ''); + if (hash) { + const speed = 0; + for (let i = 0, length = swiper.slides.length; i < length; i += 1) { + const slide = swiper.slides.eq(i); + const slideHash = slide.attr('data-hash') || slide.attr('data-history'); + if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) { + const index = slide.index(); + swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true); + } + } + } + if (swiper.params.hashNavigation.watchState) { + $(window).on('hashchange', swiper.hashNavigation.onHashCange); + } + }, + destroy() { + const swiper = this; + if (swiper.params.hashNavigation.watchState) { + $(window).off('hashchange', swiper.hashNavigation.onHashCange); + } + }, +}; +var hashNavigation = { + name: 'hash-navigation', + params: { + hashNavigation: { + enabled: false, + replaceState: false, + watchState: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + hashNavigation: { + initialized: false, + init: HashNavigation.init.bind(swiper), + destroy: HashNavigation.destroy.bind(swiper), + setHash: HashNavigation.setHash.bind(swiper), + onHashCange: HashNavigation.onHashCange.bind(swiper), + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.hashNavigation.enabled) { + swiper.hashNavigation.init(); + } + }, + destroy() { + const swiper = this; + if (swiper.params.hashNavigation.enabled) { + swiper.hashNavigation.destroy(); + } + }, + transitionEnd() { + const swiper = this; + if (swiper.hashNavigation.initialized) { + swiper.hashNavigation.setHash(); + } + }, + }, +}; + +/* eslint no-underscore-dangle: "off" */ + +const Autoplay = { + run() { + const swiper = this; + const $activeSlideEl = swiper.slides.eq(swiper.activeIndex); + let delay = swiper.params.autoplay.delay; + if ($activeSlideEl.attr('data-swiper-autoplay')) { + delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay; + } + swiper.autoplay.timeout = Utils.nextTick(() => { + if (swiper.params.autoplay.reverseDirection) { + if (swiper.params.loop) { + swiper.loopFix(); + swiper.slidePrev(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.isBeginning) { + swiper.slidePrev(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.params.autoplay.stopOnLastSlide) { + swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else { + swiper.autoplay.stop(); + } + } else if (swiper.params.loop) { + swiper.loopFix(); + swiper.slideNext(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.isEnd) { + swiper.slideNext(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.params.autoplay.stopOnLastSlide) { + swiper.slideTo(0, swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else { + swiper.autoplay.stop(); + } + }, delay); + }, + start() { + const swiper = this; + if (typeof swiper.autoplay.timeout !== 'undefined') return false; + if (swiper.autoplay.running) return false; + swiper.autoplay.running = true; + swiper.emit('autoplayStart'); + swiper.autoplay.run(); + return true; + }, + stop() { + const swiper = this; + if (!swiper.autoplay.running) return false; + if (typeof swiper.autoplay.timeout === 'undefined') return false; + + if (swiper.autoplay.timeout) { + clearTimeout(swiper.autoplay.timeout); + swiper.autoplay.timeout = undefined; + } + swiper.autoplay.running = false; + swiper.emit('autoplayStop'); + return true; + }, + pause(speed) { + const swiper = this; + if (!swiper.autoplay.running) return; + if (swiper.autoplay.paused) return; + if (swiper.autoplay.timeout) clearTimeout(swiper.autoplay.timeout); + swiper.autoplay.paused = true; + if (speed === 0 || !swiper.params.autoplay.waitForTransition) { + swiper.autoplay.paused = false; + swiper.autoplay.run(); + } else { + swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd); + swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd); + } + }, +}; + +var autoplay = { + name: 'autoplay', + params: { + autoplay: { + enabled: false, + delay: 3000, + waitForTransition: true, + disableOnInteraction: true, + stopOnLastSlide: false, + reverseDirection: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + autoplay: { + running: false, + paused: false, + run: Autoplay.run.bind(swiper), + start: Autoplay.start.bind(swiper), + stop: Autoplay.stop.bind(swiper), + pause: Autoplay.pause.bind(swiper), + onTransitionEnd(e) { + if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return; + if (e.target !== this) return; + swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd); + swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd); + swiper.autoplay.paused = false; + if (!swiper.autoplay.running) { + swiper.autoplay.stop(); + } else { + swiper.autoplay.run(); + } + }, + }, + }); + }, + on: { + init() { + const swiper = this; + if (swiper.params.autoplay.enabled) { + swiper.autoplay.start(); + } + }, + beforeTransitionStart(speed, internal) { + const swiper = this; + if (swiper.autoplay.running) { + if (internal || !swiper.params.autoplay.disableOnInteraction) { + swiper.autoplay.pause(speed); + } else { + swiper.autoplay.stop(); + } + } + }, + sliderFirstMove() { + const swiper = this; + if (swiper.autoplay.running) { + if (swiper.params.autoplay.disableOnInteraction) { + swiper.autoplay.stop(); + } else { + swiper.autoplay.pause(); + } + } + }, + destroy() { + const swiper = this; + if (swiper.autoplay.running) { + swiper.autoplay.stop(); + } + }, + }, +}; + +const Fade = { + setTranslate() { + const swiper = this; + const { slides } = swiper; + for (let i = 0; i < slides.length; i += 1) { + const $slideEl = swiper.slides.eq(i); + const offset = $slideEl[0].swiperSlideOffset; + let tx = -offset; + if (!swiper.params.virtualTranslate) tx -= swiper.translate; + let ty = 0; + if (!swiper.isHorizontal()) { + ty = tx; + tx = 0; + } + const slideOpacity = swiper.params.fadeEffect.crossFade + ? Math.max(1 - Math.abs($slideEl[0].progress), 0) + : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0); + $slideEl + .css({ + opacity: slideOpacity, + }) + .transform(`translate3d(${tx}px, ${ty}px, 0px)`); + } + }, + setTransition(duration) { + const swiper = this; + const { slides, $wrapperEl } = swiper; + slides.transition(duration); + if (swiper.params.virtualTranslate && duration !== 0) { + let eventTriggered = false; + slides.transitionEnd(() => { + if (eventTriggered) return; + if (!swiper || swiper.destroyed) return; + eventTriggered = true; + swiper.animating = false; + const triggerEvents = ['webkitTransitionEnd', 'transitionend']; + for (let i = 0; i < triggerEvents.length; i += 1) { + $wrapperEl.trigger(triggerEvents[i]); + } + }); + } + }, +}; + +var effectFade = { + name: 'effect-fade', + params: { + fadeEffect: { + crossFade: false, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + fadeEffect: { + setTranslate: Fade.setTranslate.bind(swiper), + setTransition: Fade.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'fade') return; + swiper.classNames.push(`${swiper.params.containerModifierClass}fade`); + const overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + spaceBetween: 0, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'fade') return; + swiper.fadeEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'fade') return; + swiper.fadeEffect.setTransition(duration); + }, + }, +}; + +const Cube = { + setTranslate() { + const swiper = this; + const { + $el, $wrapperEl, slides, width: swiperWidth, height: swiperHeight, rtlTranslate: rtl, size: swiperSize, + } = swiper; + const params = swiper.params.cubeEffect; + const isHorizontal = swiper.isHorizontal(); + const isVirtual = swiper.virtual && swiper.params.virtual.enabled; + let wrapperRotate = 0; + let $cubeShadowEl; + if (params.shadow) { + if (isHorizontal) { + $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow'); + if ($cubeShadowEl.length === 0) { + $cubeShadowEl = $('
            '); + $wrapperEl.append($cubeShadowEl); + } + $cubeShadowEl.css({ height: `${swiperWidth}px` }); + } else { + $cubeShadowEl = $el.find('.swiper-cube-shadow'); + if ($cubeShadowEl.length === 0) { + $cubeShadowEl = $('
            '); + $el.append($cubeShadowEl); + } + } + } + for (let i = 0; i < slides.length; i += 1) { + const $slideEl = slides.eq(i); + let slideIndex = i; + if (isVirtual) { + slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10); + } + let slideAngle = slideIndex * 90; + let round = Math.floor(slideAngle / 360); + if (rtl) { + slideAngle = -slideAngle; + round = Math.floor(-slideAngle / 360); + } + const progress = Math.max(Math.min($slideEl[0].progress, 1), -1); + let tx = 0; + let ty = 0; + let tz = 0; + if (slideIndex % 4 === 0) { + tx = -round * 4 * swiperSize; + tz = 0; + } else if ((slideIndex - 1) % 4 === 0) { + tx = 0; + tz = -round * 4 * swiperSize; + } else if ((slideIndex - 2) % 4 === 0) { + tx = swiperSize + (round * 4 * swiperSize); + tz = swiperSize; + } else if ((slideIndex - 3) % 4 === 0) { + tx = -swiperSize; + tz = (3 * swiperSize) + (swiperSize * 4 * round); + } + if (rtl) { + tx = -tx; + } + + if (!isHorizontal) { + ty = tx; + tx = 0; + } + + const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${isHorizontal ? slideAngle : 0}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`; + if (progress <= 1 && progress > -1) { + wrapperRotate = (slideIndex * 90) + (progress * 90); + if (rtl) wrapperRotate = (-slideIndex * 90) - (progress * 90); + } + $slideEl.transform(transform); + if (params.slideShadows) { + // Set shadows + let shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + let shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if (shadowBefore.length === 0) { + shadowBefore = $(`
            `); + $slideEl.append(shadowBefore); + } + if (shadowAfter.length === 0) { + shadowAfter = $(`
            `); + $slideEl.append(shadowAfter); + } + if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0); + if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0); + } + } + $wrapperEl.css({ + '-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`, + '-moz-transform-origin': `50% 50% -${swiperSize / 2}px`, + '-ms-transform-origin': `50% 50% -${swiperSize / 2}px`, + 'transform-origin': `50% 50% -${swiperSize / 2}px`, + }); + + if (params.shadow) { + if (isHorizontal) { + $cubeShadowEl.transform(`translate3d(0px, ${(swiperWidth / 2) + params.shadowOffset}px, ${-swiperWidth / 2}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`); + } else { + const shadowAngle = Math.abs(wrapperRotate) - (Math.floor(Math.abs(wrapperRotate) / 90) * 90); + const multiplier = 1.5 - ( + (Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2) + + (Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2) + ); + const scale1 = params.shadowScale; + const scale2 = params.shadowScale / multiplier; + const offset = params.shadowOffset; + $cubeShadowEl.transform(`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${(swiperHeight / 2) + offset}px, ${-swiperHeight / 2 / scale2}px) rotateX(-90deg)`); + } + } + const zFactor = (Browser.isSafari || Browser.isUiWebView) ? (-swiperSize / 2) : 0; + $wrapperEl + .transform(`translate3d(0px,0,${zFactor}px) rotateX(${swiper.isHorizontal() ? 0 : wrapperRotate}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`); + }, + setTransition(duration) { + const swiper = this; + const { $el, slides } = swiper; + slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) { + $el.find('.swiper-cube-shadow').transition(duration); + } + }, +}; + +var effectCube = { + name: 'effect-cube', + params: { + cubeEffect: { + slideShadows: true, + shadow: true, + shadowOffset: 20, + shadowScale: 0.94, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + cubeEffect: { + setTranslate: Cube.setTranslate.bind(swiper), + setTransition: Cube.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'cube') return; + swiper.classNames.push(`${swiper.params.containerModifierClass}cube`); + swiper.classNames.push(`${swiper.params.containerModifierClass}3d`); + const overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + resistanceRatio: 0, + spaceBetween: 0, + centeredSlides: false, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'cube') return; + swiper.cubeEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'cube') return; + swiper.cubeEffect.setTransition(duration); + }, + }, +}; + +const Flip = { + setTranslate() { + const swiper = this; + const { slides, rtlTranslate: rtl } = swiper; + for (let i = 0; i < slides.length; i += 1) { + const $slideEl = slides.eq(i); + let progress = $slideEl[0].progress; + if (swiper.params.flipEffect.limitRotation) { + progress = Math.max(Math.min($slideEl[0].progress, 1), -1); + } + const offset = $slideEl[0].swiperSlideOffset; + const rotate = -180 * progress; + let rotateY = rotate; + let rotateX = 0; + let tx = -offset; + let ty = 0; + if (!swiper.isHorizontal()) { + ty = tx; + tx = 0; + rotateX = -rotateY; + rotateY = 0; + } else if (rtl) { + rotateY = -rotateY; + } + + $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length; + + if (swiper.params.flipEffect.slideShadows) { + // Set shadows + let shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + let shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if (shadowBefore.length === 0) { + shadowBefore = $(`
            `); + $slideEl.append(shadowBefore); + } + if (shadowAfter.length === 0) { + shadowAfter = $(`
            `); + $slideEl.append(shadowAfter); + } + if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0); + if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0); + } + $slideEl + .transform(`translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`); + } + }, + setTransition(duration) { + const swiper = this; + const { slides, activeIndex, $wrapperEl } = swiper; + slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + if (swiper.params.virtualTranslate && duration !== 0) { + let eventTriggered = false; + // eslint-disable-next-line + slides.eq(activeIndex).transitionEnd(function onTransitionEnd() { + if (eventTriggered) return; + if (!swiper || swiper.destroyed) return; + // if (!$(this).hasClass(swiper.params.slideActiveClass)) return; + eventTriggered = true; + swiper.animating = false; + const triggerEvents = ['webkitTransitionEnd', 'transitionend']; + for (let i = 0; i < triggerEvents.length; i += 1) { + $wrapperEl.trigger(triggerEvents[i]); + } + }); + } + }, +}; + +var effectFlip = { + name: 'effect-flip', + params: { + flipEffect: { + slideShadows: true, + limitRotation: true, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + flipEffect: { + setTranslate: Flip.setTranslate.bind(swiper), + setTransition: Flip.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'flip') return; + swiper.classNames.push(`${swiper.params.containerModifierClass}flip`); + swiper.classNames.push(`${swiper.params.containerModifierClass}3d`); + const overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + spaceBetween: 0, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'flip') return; + swiper.flipEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'flip') return; + swiper.flipEffect.setTransition(duration); + }, + }, +}; + +const Coverflow = { + setTranslate() { + const swiper = this; + const { + width: swiperWidth, height: swiperHeight, slides, $wrapperEl, slidesSizesGrid, + } = swiper; + const params = swiper.params.coverflowEffect; + const isHorizontal = swiper.isHorizontal(); + const transform = swiper.translate; + const center = isHorizontal ? -transform + (swiperWidth / 2) : -transform + (swiperHeight / 2); + const rotate = isHorizontal ? params.rotate : -params.rotate; + const translate = params.depth; + // Each slide offset from center + for (let i = 0, length = slides.length; i < length; i += 1) { + const $slideEl = slides.eq(i); + const slideSize = slidesSizesGrid[i]; + const slideOffset = $slideEl[0].swiperSlideOffset; + const offsetMultiplier = ((center - slideOffset - (slideSize / 2)) / slideSize) * params.modifier; + + let rotateY = isHorizontal ? rotate * offsetMultiplier : 0; + let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; + // var rotateZ = 0 + let translateZ = -translate * Math.abs(offsetMultiplier); + + let translateY = isHorizontal ? 0 : params.stretch * (offsetMultiplier); + let translateX = isHorizontal ? params.stretch * (offsetMultiplier) : 0; + + // Fix for ultra small values + if (Math.abs(translateX) < 0.001) translateX = 0; + if (Math.abs(translateY) < 0.001) translateY = 0; + if (Math.abs(translateZ) < 0.001) translateZ = 0; + if (Math.abs(rotateY) < 0.001) rotateY = 0; + if (Math.abs(rotateX) < 0.001) rotateX = 0; + + const slideTransform = `translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; + + $slideEl.transform(slideTransform); + $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1; + if (params.slideShadows) { + // Set shadows + let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if ($shadowBeforeEl.length === 0) { + $shadowBeforeEl = $(`
            `); + $slideEl.append($shadowBeforeEl); + } + if ($shadowAfterEl.length === 0) { + $shadowAfterEl = $(`
            `); + $slideEl.append($shadowAfterEl); + } + if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0; + if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0; + } + } + + // Set correct perspective for IE10 + if (Support.pointerEvents || Support.prefixedPointerEvents) { + const ws = $wrapperEl[0].style; + ws.perspectiveOrigin = `${center}px 50%`; + } + }, + setTransition(duration) { + const swiper = this; + swiper.slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + }, +}; + +var effectCoverflow = { + name: 'effect-coverflow', + params: { + coverflowEffect: { + rotate: 50, + stretch: 0, + depth: 100, + modifier: 1, + slideShadows: true, + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + coverflowEffect: { + setTranslate: Coverflow.setTranslate.bind(swiper), + setTransition: Coverflow.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + if (swiper.params.effect !== 'coverflow') return; + + swiper.classNames.push(`${swiper.params.containerModifierClass}coverflow`); + swiper.classNames.push(`${swiper.params.containerModifierClass}3d`); + + swiper.params.watchSlidesProgress = true; + swiper.originalParams.watchSlidesProgress = true; + }, + setTranslate() { + const swiper = this; + if (swiper.params.effect !== 'coverflow') return; + swiper.coverflowEffect.setTranslate(); + }, + setTransition(duration) { + const swiper = this; + if (swiper.params.effect !== 'coverflow') return; + swiper.coverflowEffect.setTransition(duration); + }, + }, +}; + +const Thumbs = { + init() { + const swiper = this; + const { thumbs: thumbsParams } = swiper.params; + const SwiperClass = swiper.constructor; + if (thumbsParams.swiper instanceof SwiperClass) { + swiper.thumbs.swiper = thumbsParams.swiper; + Utils.extend(swiper.thumbs.swiper.originalParams, { + watchSlidesProgress: true, + slideToClickedSlide: false, + }); + Utils.extend(swiper.thumbs.swiper.params, { + watchSlidesProgress: true, + slideToClickedSlide: false, + }); + } else if (Utils.isObject(thumbsParams.swiper)) { + swiper.thumbs.swiper = new SwiperClass(Utils.extend({}, thumbsParams.swiper, { + watchSlidesVisibility: true, + watchSlidesProgress: true, + slideToClickedSlide: false, + })); + swiper.thumbs.swiperCreated = true; + } + swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass); + swiper.thumbs.swiper.on('tap', swiper.thumbs.onThumbClick); + }, + onThumbClick() { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + const clickedIndex = thumbsSwiper.clickedIndex; + const clickedSlide = thumbsSwiper.clickedSlide; + if (clickedSlide && $(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) return; + if (typeof clickedIndex === 'undefined' || clickedIndex === null) return; + let slideToIndex; + if (thumbsSwiper.params.loop) { + slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10); + } else { + slideToIndex = clickedIndex; + } + if (swiper.params.loop) { + let currentIndex = swiper.activeIndex; + if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) { + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + currentIndex = swiper.activeIndex; + } + const prevIndex = swiper.slides.eq(currentIndex).prevAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index(); + const nextIndex = swiper.slides.eq(currentIndex).nextAll(`[data-swiper-slide-index="${slideToIndex}"]`).eq(0).index(); + if (typeof prevIndex === 'undefined') slideToIndex = nextIndex; + else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex; + else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex; + else slideToIndex = prevIndex; + } + swiper.slideTo(slideToIndex); + }, + update(initial) { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + + const slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' + ? thumbsSwiper.slidesPerViewDynamic() + : thumbsSwiper.params.slidesPerView; + + if (swiper.realIndex !== thumbsSwiper.realIndex) { + let currentThumbsIndex = thumbsSwiper.activeIndex; + let newThumbsIndex; + if (thumbsSwiper.params.loop) { + if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) { + thumbsSwiper.loopFix(); + // eslint-disable-next-line + thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft; + currentThumbsIndex = thumbsSwiper.activeIndex; + } + // Find actual thumbs index to slide to + const prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index(); + const nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll(`[data-swiper-slide-index="${swiper.realIndex}"]`).eq(0).index(); + if (typeof prevThumbsIndex === 'undefined') newThumbsIndex = nextThumbsIndex; + else if (typeof nextThumbsIndex === 'undefined') newThumbsIndex = prevThumbsIndex; + else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) newThumbsIndex = currentThumbsIndex; + else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) newThumbsIndex = nextThumbsIndex; + else newThumbsIndex = prevThumbsIndex; + } else { + newThumbsIndex = swiper.realIndex; + } + if (thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) { + if (thumbsSwiper.params.centeredSlides) { + if (newThumbsIndex > currentThumbsIndex) { + newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1; + } else { + newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1; + } + } else if (newThumbsIndex > currentThumbsIndex) { + newThumbsIndex = newThumbsIndex - slidesPerView + 1; + } + thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined); + } + } + + // Activate thumbs + let thumbsToActivate = 1; + const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass; + + if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) { + thumbsToActivate = swiper.params.slidesPerView; + } + + thumbsSwiper.slides.removeClass(thumbActiveClass); + if (thumbsSwiper.params.loop) { + for (let i = 0; i < thumbsToActivate; i += 1) { + thumbsSwiper.$wrapperEl.children(`[data-swiper-slide-index="${swiper.realIndex + i}"]`).addClass(thumbActiveClass); + } + } else { + for (let i = 0; i < thumbsToActivate; i += 1) { + thumbsSwiper.slides.eq(swiper.realIndex + i).addClass(thumbActiveClass); + } + } + }, +}; +var thumbs = { + name: 'thumbs', + params: { + thumbs: { + swiper: null, + slideThumbActiveClass: 'swiper-slide-thumb-active', + thumbsContainerClass: 'swiper-container-thumbs', + }, + }, + create() { + const swiper = this; + Utils.extend(swiper, { + thumbs: { + swiper: null, + init: Thumbs.init.bind(swiper), + update: Thumbs.update.bind(swiper), + onThumbClick: Thumbs.onThumbClick.bind(swiper), + }, + }); + }, + on: { + beforeInit() { + const swiper = this; + const { thumbs } = swiper.params; + if (!thumbs || !thumbs.swiper) return; + swiper.thumbs.init(); + swiper.thumbs.update(true); + }, + slideChange() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + update() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + resize() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + observerUpdate() { + const swiper = this; + if (!swiper.thumbs.swiper) return; + swiper.thumbs.update(); + }, + setTransition(duration) { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + thumbsSwiper.setTransition(duration); + }, + beforeDestroy() { + const swiper = this; + const thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) return; + if (swiper.thumbs.swiperCreated && thumbsSwiper) { + thumbsSwiper.destroy(); + } + }, + }, +}; + +// Swiper Class + +const components = [ + Device$1, + Support$1, + Browser$1, + Resize, + Observer$1, + +]; + +if (typeof Swiper.use === 'undefined') { + Swiper.use = Swiper.Class.use; + Swiper.installModule = Swiper.Class.installModule; +} + +Swiper.use(components); + +export { Swiper, virtual as Virtual, keyboard as Keyboard, mousewheel as Mousewheel, navigation as Navigation, pagination as Pagination, scrollbar as Scrollbar, parallax as Parallax, zoom as Zoom, lazy as Lazy, controller as Controller, a11y$1 as A11y, history as History, hashNavigation as HashNavigation, autoplay as Autoplay, effectFade as EffectFade, effectCube as EffectCube, effectFlip as EffectFlip, effectCoverflow as EffectCoverflow, thumbs as Thumbs }; diff --git a/assets/3rd/swiper/js/swiper.js b/assets/3rd/swiper/js/swiper.js new file mode 100755 index 00000000..54b903a3 --- /dev/null +++ b/assets/3rd/swiper/js/swiper.js @@ -0,0 +1,8124 @@ +/** + * Swiper 4.5.0 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * http://www.idangero.us/swiper/ + * + * Copyright 2014-2019 Vladimir Kharlampidi + * + * Released under the MIT License + * + * Released on: February 22, 2019 + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.Swiper = factory()); +}(this, function () { 'use strict'; + + /** + * SSR Window 1.0.1 + * Better handling for window object in SSR environment + * https://github.com/nolimits4web/ssr-window + * + * Copyright 2018, Vladimir Kharlampidi + * + * Licensed under MIT + * + * Released on: July 18, 2018 + */ + var doc = (typeof document === 'undefined') ? { + body: {}, + addEventListener: function addEventListener() {}, + removeEventListener: function removeEventListener() {}, + activeElement: { + blur: function blur() {}, + nodeName: '', + }, + querySelector: function querySelector() { + return null; + }, + querySelectorAll: function querySelectorAll() { + return []; + }, + getElementById: function getElementById() { + return null; + }, + createEvent: function createEvent() { + return { + initEvent: function initEvent() {}, + }; + }, + createElement: function createElement() { + return { + children: [], + childNodes: [], + style: {}, + setAttribute: function setAttribute() {}, + getElementsByTagName: function getElementsByTagName() { + return []; + }, + }; + }, + location: { hash: '' }, + } : document; // eslint-disable-line + + var win = (typeof window === 'undefined') ? { + document: doc, + navigator: { + userAgent: '', + }, + location: {}, + history: {}, + CustomEvent: function CustomEvent() { + return this; + }, + addEventListener: function addEventListener() {}, + removeEventListener: function removeEventListener() {}, + getComputedStyle: function getComputedStyle() { + return { + getPropertyValue: function getPropertyValue() { + return ''; + }, + }; + }, + Image: function Image() {}, + Date: function Date() {}, + screen: {}, + setTimeout: function setTimeout() {}, + clearTimeout: function clearTimeout() {}, + } : window; // eslint-disable-line + + /** + * Dom7 2.1.3 + * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API + * http://framework7.io/docs/dom.html + * + * Copyright 2019, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: February 11, 2019 + */ + + var Dom7 = function Dom7(arr) { + var self = this; + // Create array-like object + for (var i = 0; i < arr.length; i += 1) { + self[i] = arr[i]; + } + self.length = arr.length; + // Return collection with methods + return this; + }; + + function $(selector, context) { + var arr = []; + var i = 0; + if (selector && !context) { + if (selector instanceof Dom7) { + return selector; + } + } + if (selector) { + // String + if (typeof selector === 'string') { + var els; + var tempParent; + var html = selector.trim(); + if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) { + var toCreate = 'div'; + if (html.indexOf(':~]/)) { + // Pure ID selector + els = [doc.getElementById(selector.trim().split('#')[1])]; + } else { + // Other selectors + els = (context || doc).querySelectorAll(selector.trim()); + } + for (i = 0; i < els.length; i += 1) { + if (els[i]) { arr.push(els[i]); } + } + } + } else if (selector.nodeType || selector === win || selector === doc) { + // Node/element + arr.push(selector); + } else if (selector.length > 0 && selector[0].nodeType) { + // Array of elements or instance of Dom + for (i = 0; i < selector.length; i += 1) { + arr.push(selector[i]); + } + } + } + return new Dom7(arr); + } + + $.fn = Dom7.prototype; + $.Class = Dom7; + $.Dom7 = Dom7; + + function unique(arr) { + var uniqueArray = []; + for (var i = 0; i < arr.length; i += 1) { + if (uniqueArray.indexOf(arr[i]) === -1) { uniqueArray.push(arr[i]); } + } + return uniqueArray; + } + + // Classes and attributes + function addClass(className) { + if (typeof className === 'undefined') { + return this; + } + var classes = className.split(' '); + for (var i = 0; i < classes.length; i += 1) { + for (var j = 0; j < this.length; j += 1) { + if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.add(classes[i]); } + } + } + return this; + } + function removeClass(className) { + var classes = className.split(' '); + for (var i = 0; i < classes.length; i += 1) { + for (var j = 0; j < this.length; j += 1) { + if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.remove(classes[i]); } + } + } + return this; + } + function hasClass(className) { + if (!this[0]) { return false; } + return this[0].classList.contains(className); + } + function toggleClass(className) { + var classes = className.split(' '); + for (var i = 0; i < classes.length; i += 1) { + for (var j = 0; j < this.length; j += 1) { + if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.toggle(classes[i]); } + } + } + return this; + } + function attr(attrs, value) { + var arguments$1 = arguments; + + if (arguments.length === 1 && typeof attrs === 'string') { + // Get attr + if (this[0]) { return this[0].getAttribute(attrs); } + return undefined; + } + + // Set attrs + for (var i = 0; i < this.length; i += 1) { + if (arguments$1.length === 2) { + // String + this[i].setAttribute(attrs, value); + } else { + // Object + // eslint-disable-next-line + for (var attrName in attrs) { + this[i][attrName] = attrs[attrName]; + this[i].setAttribute(attrName, attrs[attrName]); + } + } + } + return this; + } + // eslint-disable-next-line + function removeAttr(attr) { + for (var i = 0; i < this.length; i += 1) { + this[i].removeAttribute(attr); + } + return this; + } + function data(key, value) { + var el; + if (typeof value === 'undefined') { + el = this[0]; + // Get value + if (el) { + if (el.dom7ElementDataStorage && (key in el.dom7ElementDataStorage)) { + return el.dom7ElementDataStorage[key]; + } + + var dataKey = el.getAttribute(("data-" + key)); + if (dataKey) { + return dataKey; + } + return undefined; + } + return undefined; + } + + // Set value + for (var i = 0; i < this.length; i += 1) { + el = this[i]; + if (!el.dom7ElementDataStorage) { el.dom7ElementDataStorage = {}; } + el.dom7ElementDataStorage[key] = value; + } + return this; + } + // Transforms + // eslint-disable-next-line + function transform(transform) { + for (var i = 0; i < this.length; i += 1) { + var elStyle = this[i].style; + elStyle.webkitTransform = transform; + elStyle.transform = transform; + } + return this; + } + function transition(duration) { + if (typeof duration !== 'string') { + duration = duration + "ms"; // eslint-disable-line + } + for (var i = 0; i < this.length; i += 1) { + var elStyle = this[i].style; + elStyle.webkitTransitionDuration = duration; + elStyle.transitionDuration = duration; + } + return this; + } + // Events + function on() { + var assign; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + var eventType = args[0]; + var targetSelector = args[1]; + var listener = args[2]; + var capture = args[3]; + if (typeof args[1] === 'function') { + (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]); + targetSelector = undefined; + } + if (!capture) { capture = false; } + + function handleLiveEvent(e) { + var target = e.target; + if (!target) { return; } + var eventData = e.target.dom7EventData || []; + if (eventData.indexOf(e) < 0) { + eventData.unshift(e); + } + if ($(target).is(targetSelector)) { listener.apply(target, eventData); } + else { + var parents = $(target).parents(); // eslint-disable-line + for (var k = 0; k < parents.length; k += 1) { + if ($(parents[k]).is(targetSelector)) { listener.apply(parents[k], eventData); } + } + } + } + function handleEvent(e) { + var eventData = e && e.target ? e.target.dom7EventData || [] : []; + if (eventData.indexOf(e) < 0) { + eventData.unshift(e); + } + listener.apply(this, eventData); + } + var events = eventType.split(' '); + var j; + for (var i = 0; i < this.length; i += 1) { + var el = this[i]; + if (!targetSelector) { + for (j = 0; j < events.length; j += 1) { + var event = events[j]; + if (!el.dom7Listeners) { el.dom7Listeners = {}; } + if (!el.dom7Listeners[event]) { el.dom7Listeners[event] = []; } + el.dom7Listeners[event].push({ + listener: listener, + proxyListener: handleEvent, + }); + el.addEventListener(event, handleEvent, capture); + } + } else { + // Live events + for (j = 0; j < events.length; j += 1) { + var event$1 = events[j]; + if (!el.dom7LiveListeners) { el.dom7LiveListeners = {}; } + if (!el.dom7LiveListeners[event$1]) { el.dom7LiveListeners[event$1] = []; } + el.dom7LiveListeners[event$1].push({ + listener: listener, + proxyListener: handleLiveEvent, + }); + el.addEventListener(event$1, handleLiveEvent, capture); + } + } + } + return this; + } + function off() { + var assign; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + var eventType = args[0]; + var targetSelector = args[1]; + var listener = args[2]; + var capture = args[3]; + if (typeof args[1] === 'function') { + (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]); + targetSelector = undefined; + } + if (!capture) { capture = false; } + + var events = eventType.split(' '); + for (var i = 0; i < events.length; i += 1) { + var event = events[i]; + for (var j = 0; j < this.length; j += 1) { + var el = this[j]; + var handlers = (void 0); + if (!targetSelector && el.dom7Listeners) { + handlers = el.dom7Listeners[event]; + } else if (targetSelector && el.dom7LiveListeners) { + handlers = el.dom7LiveListeners[event]; + } + if (handlers && handlers.length) { + for (var k = handlers.length - 1; k >= 0; k -= 1) { + var handler = handlers[k]; + if (listener && handler.listener === listener) { + el.removeEventListener(event, handler.proxyListener, capture); + handlers.splice(k, 1); + } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) { + el.removeEventListener(event, handler.proxyListener, capture); + handlers.splice(k, 1); + } else if (!listener) { + el.removeEventListener(event, handler.proxyListener, capture); + handlers.splice(k, 1); + } + } + } + } + } + return this; + } + function trigger() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var events = args[0].split(' '); + var eventData = args[1]; + for (var i = 0; i < events.length; i += 1) { + var event = events[i]; + for (var j = 0; j < this.length; j += 1) { + var el = this[j]; + var evt = (void 0); + try { + evt = new win.CustomEvent(event, { + detail: eventData, + bubbles: true, + cancelable: true, + }); + } catch (e) { + evt = doc.createEvent('Event'); + evt.initEvent(event, true, true); + evt.detail = eventData; + } + // eslint-disable-next-line + el.dom7EventData = args.filter(function (data, dataIndex) { return dataIndex > 0; }); + el.dispatchEvent(evt); + el.dom7EventData = []; + delete el.dom7EventData; + } + } + return this; + } + function transitionEnd(callback) { + var events = ['webkitTransitionEnd', 'transitionend']; + var dom = this; + var i; + function fireCallBack(e) { + /* jshint validthis:true */ + if (e.target !== this) { return; } + callback.call(this, e); + for (i = 0; i < events.length; i += 1) { + dom.off(events[i], fireCallBack); + } + } + if (callback) { + for (i = 0; i < events.length; i += 1) { + dom.on(events[i], fireCallBack); + } + } + return this; + } + function outerWidth(includeMargins) { + if (this.length > 0) { + if (includeMargins) { + // eslint-disable-next-line + var styles = this.styles(); + return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left')); + } + return this[0].offsetWidth; + } + return null; + } + function outerHeight(includeMargins) { + if (this.length > 0) { + if (includeMargins) { + // eslint-disable-next-line + var styles = this.styles(); + return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom')); + } + return this[0].offsetHeight; + } + return null; + } + function offset() { + if (this.length > 0) { + var el = this[0]; + var box = el.getBoundingClientRect(); + var body = doc.body; + var clientTop = el.clientTop || body.clientTop || 0; + var clientLeft = el.clientLeft || body.clientLeft || 0; + var scrollTop = el === win ? win.scrollY : el.scrollTop; + var scrollLeft = el === win ? win.scrollX : el.scrollLeft; + return { + top: (box.top + scrollTop) - clientTop, + left: (box.left + scrollLeft) - clientLeft, + }; + } + + return null; + } + function styles() { + if (this[0]) { return win.getComputedStyle(this[0], null); } + return {}; + } + function css(props, value) { + var i; + if (arguments.length === 1) { + if (typeof props === 'string') { + if (this[0]) { return win.getComputedStyle(this[0], null).getPropertyValue(props); } + } else { + for (i = 0; i < this.length; i += 1) { + // eslint-disable-next-line + for (var prop in props) { + this[i].style[prop] = props[prop]; + } + } + return this; + } + } + if (arguments.length === 2 && typeof props === 'string') { + for (i = 0; i < this.length; i += 1) { + this[i].style[props] = value; + } + return this; + } + return this; + } + // Iterate over the collection passing elements to `callback` + function each(callback) { + // Don't bother continuing without a callback + if (!callback) { return this; } + // Iterate over the current collection + for (var i = 0; i < this.length; i += 1) { + // If the callback returns false + if (callback.call(this[i], i, this[i]) === false) { + // End the loop early + return this; + } + } + // Return `this` to allow chained DOM operations + return this; + } + // eslint-disable-next-line + function html(html) { + if (typeof html === 'undefined') { + return this[0] ? this[0].innerHTML : undefined; + } + + for (var i = 0; i < this.length; i += 1) { + this[i].innerHTML = html; + } + return this; + } + // eslint-disable-next-line + function text(text) { + if (typeof text === 'undefined') { + if (this[0]) { + return this[0].textContent.trim(); + } + return null; + } + + for (var i = 0; i < this.length; i += 1) { + this[i].textContent = text; + } + return this; + } + function is(selector) { + var el = this[0]; + var compareWith; + var i; + if (!el || typeof selector === 'undefined') { return false; } + if (typeof selector === 'string') { + if (el.matches) { return el.matches(selector); } + else if (el.webkitMatchesSelector) { return el.webkitMatchesSelector(selector); } + else if (el.msMatchesSelector) { return el.msMatchesSelector(selector); } + + compareWith = $(selector); + for (i = 0; i < compareWith.length; i += 1) { + if (compareWith[i] === el) { return true; } + } + return false; + } else if (selector === doc) { return el === doc; } + else if (selector === win) { return el === win; } + + if (selector.nodeType || selector instanceof Dom7) { + compareWith = selector.nodeType ? [selector] : selector; + for (i = 0; i < compareWith.length; i += 1) { + if (compareWith[i] === el) { return true; } + } + return false; + } + return false; + } + function index() { + var child = this[0]; + var i; + if (child) { + i = 0; + // eslint-disable-next-line + while ((child = child.previousSibling) !== null) { + if (child.nodeType === 1) { i += 1; } + } + return i; + } + return undefined; + } + // eslint-disable-next-line + function eq(index) { + if (typeof index === 'undefined') { return this; } + var length = this.length; + var returnIndex; + if (index > length - 1) { + return new Dom7([]); + } + if (index < 0) { + returnIndex = length + index; + if (returnIndex < 0) { return new Dom7([]); } + return new Dom7([this[returnIndex]]); + } + return new Dom7([this[index]]); + } + function append() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var newChild; + + for (var k = 0; k < args.length; k += 1) { + newChild = args[k]; + for (var i = 0; i < this.length; i += 1) { + if (typeof newChild === 'string') { + var tempDiv = doc.createElement('div'); + tempDiv.innerHTML = newChild; + while (tempDiv.firstChild) { + this[i].appendChild(tempDiv.firstChild); + } + } else if (newChild instanceof Dom7) { + for (var j = 0; j < newChild.length; j += 1) { + this[i].appendChild(newChild[j]); + } + } else { + this[i].appendChild(newChild); + } + } + } + + return this; + } + function prepend(newChild) { + var i; + var j; + for (i = 0; i < this.length; i += 1) { + if (typeof newChild === 'string') { + var tempDiv = doc.createElement('div'); + tempDiv.innerHTML = newChild; + for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) { + this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]); + } + } else if (newChild instanceof Dom7) { + for (j = 0; j < newChild.length; j += 1) { + this[i].insertBefore(newChild[j], this[i].childNodes[0]); + } + } else { + this[i].insertBefore(newChild, this[i].childNodes[0]); + } + } + return this; + } + function next(selector) { + if (this.length > 0) { + if (selector) { + if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) { + return new Dom7([this[0].nextElementSibling]); + } + return new Dom7([]); + } + + if (this[0].nextElementSibling) { return new Dom7([this[0].nextElementSibling]); } + return new Dom7([]); + } + return new Dom7([]); + } + function nextAll(selector) { + var nextEls = []; + var el = this[0]; + if (!el) { return new Dom7([]); } + while (el.nextElementSibling) { + var next = el.nextElementSibling; // eslint-disable-line + if (selector) { + if ($(next).is(selector)) { nextEls.push(next); } + } else { nextEls.push(next); } + el = next; + } + return new Dom7(nextEls); + } + function prev(selector) { + if (this.length > 0) { + var el = this[0]; + if (selector) { + if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) { + return new Dom7([el.previousElementSibling]); + } + return new Dom7([]); + } + + if (el.previousElementSibling) { return new Dom7([el.previousElementSibling]); } + return new Dom7([]); + } + return new Dom7([]); + } + function prevAll(selector) { + var prevEls = []; + var el = this[0]; + if (!el) { return new Dom7([]); } + while (el.previousElementSibling) { + var prev = el.previousElementSibling; // eslint-disable-line + if (selector) { + if ($(prev).is(selector)) { prevEls.push(prev); } + } else { prevEls.push(prev); } + el = prev; + } + return new Dom7(prevEls); + } + function parent(selector) { + var parents = []; // eslint-disable-line + for (var i = 0; i < this.length; i += 1) { + if (this[i].parentNode !== null) { + if (selector) { + if ($(this[i].parentNode).is(selector)) { parents.push(this[i].parentNode); } + } else { + parents.push(this[i].parentNode); + } + } + } + return $(unique(parents)); + } + function parents(selector) { + var parents = []; // eslint-disable-line + for (var i = 0; i < this.length; i += 1) { + var parent = this[i].parentNode; // eslint-disable-line + while (parent) { + if (selector) { + if ($(parent).is(selector)) { parents.push(parent); } + } else { + parents.push(parent); + } + parent = parent.parentNode; + } + } + return $(unique(parents)); + } + function closest(selector) { + var closest = this; // eslint-disable-line + if (typeof selector === 'undefined') { + return new Dom7([]); + } + if (!closest.is(selector)) { + closest = closest.parents(selector).eq(0); + } + return closest; + } + function find(selector) { + var foundElements = []; + for (var i = 0; i < this.length; i += 1) { + var found = this[i].querySelectorAll(selector); + for (var j = 0; j < found.length; j += 1) { + foundElements.push(found[j]); + } + } + return new Dom7(foundElements); + } + function children(selector) { + var children = []; // eslint-disable-line + for (var i = 0; i < this.length; i += 1) { + var childNodes = this[i].childNodes; + + for (var j = 0; j < childNodes.length; j += 1) { + if (!selector) { + if (childNodes[j].nodeType === 1) { children.push(childNodes[j]); } + } else if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) { + children.push(childNodes[j]); + } + } + } + return new Dom7(unique(children)); + } + function remove() { + for (var i = 0; i < this.length; i += 1) { + if (this[i].parentNode) { this[i].parentNode.removeChild(this[i]); } + } + return this; + } + function add() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var dom = this; + var i; + var j; + for (i = 0; i < args.length; i += 1) { + var toAdd = $(args[i]); + for (j = 0; j < toAdd.length; j += 1) { + dom[dom.length] = toAdd[j]; + dom.length += 1; + } + } + return dom; + } + + var Methods = { + addClass: addClass, + removeClass: removeClass, + hasClass: hasClass, + toggleClass: toggleClass, + attr: attr, + removeAttr: removeAttr, + data: data, + transform: transform, + transition: transition, + on: on, + off: off, + trigger: trigger, + transitionEnd: transitionEnd, + outerWidth: outerWidth, + outerHeight: outerHeight, + offset: offset, + css: css, + each: each, + html: html, + text: text, + is: is, + index: index, + eq: eq, + append: append, + prepend: prepend, + next: next, + nextAll: nextAll, + prev: prev, + prevAll: prevAll, + parent: parent, + parents: parents, + closest: closest, + find: find, + children: children, + remove: remove, + add: add, + styles: styles, + }; + + Object.keys(Methods).forEach(function (methodName) { + $.fn[methodName] = Methods[methodName]; + }); + + var Utils = { + deleteProps: function deleteProps(obj) { + var object = obj; + Object.keys(object).forEach(function (key) { + try { + object[key] = null; + } catch (e) { + // no getter for object + } + try { + delete object[key]; + } catch (e) { + // something got wrong + } + }); + }, + nextTick: function nextTick(callback, delay) { + if ( delay === void 0 ) delay = 0; + + return setTimeout(callback, delay); + }, + now: function now() { + return Date.now(); + }, + getTranslate: function getTranslate(el, axis) { + if ( axis === void 0 ) axis = 'x'; + + var matrix; + var curTransform; + var transformMatrix; + + var curStyle = win.getComputedStyle(el, null); + + if (win.WebKitCSSMatrix) { + curTransform = curStyle.transform || curStyle.webkitTransform; + if (curTransform.split(',').length > 6) { + curTransform = curTransform.split(', ').map(function (a) { return a.replace(',', '.'); }).join(', '); + } + // Some old versions of Webkit choke when 'none' is passed; pass + // empty string instead in this case + transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform); + } else { + transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,'); + matrix = transformMatrix.toString().split(','); + } + + if (axis === 'x') { + // Latest Chrome and webkits Fix + if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m41; } + // Crazy IE10 Matrix + else if (matrix.length === 16) { curTransform = parseFloat(matrix[12]); } + // Normal Browsers + else { curTransform = parseFloat(matrix[4]); } + } + if (axis === 'y') { + // Latest Chrome and webkits Fix + if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m42; } + // Crazy IE10 Matrix + else if (matrix.length === 16) { curTransform = parseFloat(matrix[13]); } + // Normal Browsers + else { curTransform = parseFloat(matrix[5]); } + } + return curTransform || 0; + }, + parseUrlQuery: function parseUrlQuery(url) { + var query = {}; + var urlToParse = url || win.location.href; + var i; + var params; + var param; + var length; + if (typeof urlToParse === 'string' && urlToParse.length) { + urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\S*\?/, '') : ''; + params = urlToParse.split('&').filter(function (paramsPart) { return paramsPart !== ''; }); + length = params.length; + + for (i = 0; i < length; i += 1) { + param = params[i].replace(/#\S+/g, '').split('='); + query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param[1]) || ''; + } + } + return query; + }, + isObject: function isObject(o) { + return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object; + }, + extend: function extend() { + var args = [], len$1 = arguments.length; + while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ]; + + var to = Object(args[0]); + for (var i = 1; i < args.length; i += 1) { + var nextSource = args[i]; + if (nextSource !== undefined && nextSource !== null) { + var keysArray = Object.keys(Object(nextSource)); + for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) { + var nextKey = keysArray[nextIndex]; + var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey); + if (desc !== undefined && desc.enumerable) { + if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) { + Utils.extend(to[nextKey], nextSource[nextKey]); + } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) { + to[nextKey] = {}; + Utils.extend(to[nextKey], nextSource[nextKey]); + } else { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + } + return to; + }, + }; + + var Support = (function Support() { + var testDiv = doc.createElement('div'); + return { + touch: (win.Modernizr && win.Modernizr.touch === true) || (function checkTouch() { + return !!((win.navigator.maxTouchPoints > 0) || ('ontouchstart' in win) || (win.DocumentTouch && doc instanceof win.DocumentTouch)); + }()), + + pointerEvents: !!(win.navigator.pointerEnabled || win.PointerEvent || ('maxTouchPoints' in win.navigator && win.navigator.maxTouchPoints > 0)), + prefixedPointerEvents: !!win.navigator.msPointerEnabled, + + transition: (function checkTransition() { + var style = testDiv.style; + return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style); + }()), + transforms3d: (win.Modernizr && win.Modernizr.csstransforms3d === true) || (function checkTransforms3d() { + var style = testDiv.style; + return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style); + }()), + + flexbox: (function checkFlexbox() { + var style = testDiv.style; + var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' '); + for (var i = 0; i < styles.length; i += 1) { + if (styles[i] in style) { return true; } + } + return false; + }()), + + observer: (function checkObserver() { + return ('MutationObserver' in win || 'WebkitMutationObserver' in win); + }()), + + passiveListener: (function checkPassiveListener() { + var supportsPassive = false; + try { + var opts = Object.defineProperty({}, 'passive', { + // eslint-disable-next-line + get: function get() { + supportsPassive = true; + }, + }); + win.addEventListener('testPassiveListener', null, opts); + } catch (e) { + // No support + } + return supportsPassive; + }()), + + gestures: (function checkGestures() { + return 'ongesturestart' in win; + }()), + }; + }()); + + var Browser = (function Browser() { + function isSafari() { + var ua = win.navigator.userAgent.toLowerCase(); + return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0); + } + return { + isIE: !!win.navigator.userAgent.match(/Trident/g) || !!win.navigator.userAgent.match(/MSIE/g), + isEdge: !!win.navigator.userAgent.match(/Edge/g), + isSafari: isSafari(), + isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(win.navigator.userAgent), + }; + }()); + + var SwiperClass = function SwiperClass(params) { + if ( params === void 0 ) params = {}; + + var self = this; + self.params = params; + + // Events + self.eventsListeners = {}; + + if (self.params && self.params.on) { + Object.keys(self.params.on).forEach(function (eventName) { + self.on(eventName, self.params.on[eventName]); + }); + } + }; + + var staticAccessors = { components: { configurable: true } }; + + SwiperClass.prototype.on = function on (events, handler, priority) { + var self = this; + if (typeof handler !== 'function') { return self; } + var method = priority ? 'unshift' : 'push'; + events.split(' ').forEach(function (event) { + if (!self.eventsListeners[event]) { self.eventsListeners[event] = []; } + self.eventsListeners[event][method](handler); + }); + return self; + }; + + SwiperClass.prototype.once = function once (events, handler, priority) { + var self = this; + if (typeof handler !== 'function') { return self; } + function onceHandler() { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + handler.apply(self, args); + self.off(events, onceHandler); + if (onceHandler.f7proxy) { + delete onceHandler.f7proxy; + } + } + onceHandler.f7proxy = handler; + return self.on(events, onceHandler, priority); + }; + + SwiperClass.prototype.off = function off (events, handler) { + var self = this; + if (!self.eventsListeners) { return self; } + events.split(' ').forEach(function (event) { + if (typeof handler === 'undefined') { + self.eventsListeners[event] = []; + } else if (self.eventsListeners[event] && self.eventsListeners[event].length) { + self.eventsListeners[event].forEach(function (eventHandler, index) { + if (eventHandler === handler || (eventHandler.f7proxy && eventHandler.f7proxy === handler)) { + self.eventsListeners[event].splice(index, 1); + } + }); + } + }); + return self; + }; + + SwiperClass.prototype.emit = function emit () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var self = this; + if (!self.eventsListeners) { return self; } + var events; + var data; + var context; + if (typeof args[0] === 'string' || Array.isArray(args[0])) { + events = args[0]; + data = args.slice(1, args.length); + context = self; + } else { + events = args[0].events; + data = args[0].data; + context = args[0].context || self; + } + var eventsArray = Array.isArray(events) ? events : events.split(' '); + eventsArray.forEach(function (event) { + if (self.eventsListeners && self.eventsListeners[event]) { + var handlers = []; + self.eventsListeners[event].forEach(function (eventHandler) { + handlers.push(eventHandler); + }); + handlers.forEach(function (eventHandler) { + eventHandler.apply(context, data); + }); + } + }); + return self; + }; + + SwiperClass.prototype.useModulesParams = function useModulesParams (instanceParams) { + var instance = this; + if (!instance.modules) { return; } + Object.keys(instance.modules).forEach(function (moduleName) { + var module = instance.modules[moduleName]; + // Extend params + if (module.params) { + Utils.extend(instanceParams, module.params); + } + }); + }; + + SwiperClass.prototype.useModules = function useModules (modulesParams) { + if ( modulesParams === void 0 ) modulesParams = {}; + + var instance = this; + if (!instance.modules) { return; } + Object.keys(instance.modules).forEach(function (moduleName) { + var module = instance.modules[moduleName]; + var moduleParams = modulesParams[moduleName] || {}; + // Extend instance methods and props + if (module.instance) { + Object.keys(module.instance).forEach(function (modulePropName) { + var moduleProp = module.instance[modulePropName]; + if (typeof moduleProp === 'function') { + instance[modulePropName] = moduleProp.bind(instance); + } else { + instance[modulePropName] = moduleProp; + } + }); + } + // Add event listeners + if (module.on && instance.on) { + Object.keys(module.on).forEach(function (moduleEventName) { + instance.on(moduleEventName, module.on[moduleEventName]); + }); + } + + // Module create callback + if (module.create) { + module.create.bind(instance)(moduleParams); + } + }); + }; + + staticAccessors.components.set = function (components) { + var Class = this; + if (!Class.use) { return; } + Class.use(components); + }; + + SwiperClass.installModule = function installModule (module) { + var params = [], len = arguments.length - 1; + while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ]; + + var Class = this; + if (!Class.prototype.modules) { Class.prototype.modules = {}; } + var name = module.name || (((Object.keys(Class.prototype.modules).length) + "_" + (Utils.now()))); + Class.prototype.modules[name] = module; + // Prototype + if (module.proto) { + Object.keys(module.proto).forEach(function (key) { + Class.prototype[key] = module.proto[key]; + }); + } + // Class + if (module.static) { + Object.keys(module.static).forEach(function (key) { + Class[key] = module.static[key]; + }); + } + // Callback + if (module.install) { + module.install.apply(Class, params); + } + return Class; + }; + + SwiperClass.use = function use (module) { + var params = [], len = arguments.length - 1; + while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ]; + + var Class = this; + if (Array.isArray(module)) { + module.forEach(function (m) { return Class.installModule(m); }); + return Class; + } + return Class.installModule.apply(Class, [ module ].concat( params )); + }; + + Object.defineProperties( SwiperClass, staticAccessors ); + + function updateSize () { + var swiper = this; + var width; + var height; + var $el = swiper.$el; + if (typeof swiper.params.width !== 'undefined') { + width = swiper.params.width; + } else { + width = $el[0].clientWidth; + } + if (typeof swiper.params.height !== 'undefined') { + height = swiper.params.height; + } else { + height = $el[0].clientHeight; + } + if ((width === 0 && swiper.isHorizontal()) || (height === 0 && swiper.isVertical())) { + return; + } + + // Subtract paddings + width = width - parseInt($el.css('padding-left'), 10) - parseInt($el.css('padding-right'), 10); + height = height - parseInt($el.css('padding-top'), 10) - parseInt($el.css('padding-bottom'), 10); + + Utils.extend(swiper, { + width: width, + height: height, + size: swiper.isHorizontal() ? width : height, + }); + } + + function updateSlides () { + var swiper = this; + var params = swiper.params; + + var $wrapperEl = swiper.$wrapperEl; + var swiperSize = swiper.size; + var rtl = swiper.rtlTranslate; + var wrongRTL = swiper.wrongRTL; + var isVirtual = swiper.virtual && params.virtual.enabled; + var previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length; + var slides = $wrapperEl.children(("." + (swiper.params.slideClass))); + var slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length; + var snapGrid = []; + var slidesGrid = []; + var slidesSizesGrid = []; + + var offsetBefore = params.slidesOffsetBefore; + if (typeof offsetBefore === 'function') { + offsetBefore = params.slidesOffsetBefore.call(swiper); + } + + var offsetAfter = params.slidesOffsetAfter; + if (typeof offsetAfter === 'function') { + offsetAfter = params.slidesOffsetAfter.call(swiper); + } + + var previousSnapGridLength = swiper.snapGrid.length; + var previousSlidesGridLength = swiper.snapGrid.length; + + var spaceBetween = params.spaceBetween; + var slidePosition = -offsetBefore; + var prevSlideSize = 0; + var index = 0; + if (typeof swiperSize === 'undefined') { + return; + } + if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) { + spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiperSize; + } + + swiper.virtualSize = -spaceBetween; + + // reset margins + if (rtl) { slides.css({ marginLeft: '', marginTop: '' }); } + else { slides.css({ marginRight: '', marginBottom: '' }); } + + var slidesNumberEvenToRows; + if (params.slidesPerColumn > 1) { + if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) { + slidesNumberEvenToRows = slidesLength; + } else { + slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn; + } + if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') { + slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, params.slidesPerView * params.slidesPerColumn); + } + } + + // Calc slides + var slideSize; + var slidesPerColumn = params.slidesPerColumn; + var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn; + var numFullColumns = Math.floor(slidesLength / params.slidesPerColumn); + for (var i = 0; i < slidesLength; i += 1) { + slideSize = 0; + var slide = slides.eq(i); + if (params.slidesPerColumn > 1) { + // Set slides order + var newSlideOrderIndex = (void 0); + var column = (void 0); + var row = (void 0); + if (params.slidesPerColumnFill === 'column') { + column = Math.floor(i / slidesPerColumn); + row = i - (column * slidesPerColumn); + if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) { + row += 1; + if (row >= slidesPerColumn) { + row = 0; + column += 1; + } + } + newSlideOrderIndex = column + ((row * slidesNumberEvenToRows) / slidesPerColumn); + slide + .css({ + '-webkit-box-ordinal-group': newSlideOrderIndex, + '-moz-box-ordinal-group': newSlideOrderIndex, + '-ms-flex-order': newSlideOrderIndex, + '-webkit-order': newSlideOrderIndex, + order: newSlideOrderIndex, + }); + } else { + row = Math.floor(i / slidesPerRow); + column = i - (row * slidesPerRow); + } + slide + .css( + ("margin-" + (swiper.isHorizontal() ? 'top' : 'left')), + (row !== 0 && params.spaceBetween) && (((params.spaceBetween) + "px")) + ) + .attr('data-swiper-column', column) + .attr('data-swiper-row', row); + } + if (slide.css('display') === 'none') { continue; } // eslint-disable-line + + if (params.slidesPerView === 'auto') { + var slideStyles = win.getComputedStyle(slide[0], null); + var currentTransform = slide[0].style.transform; + var currentWebKitTransform = slide[0].style.webkitTransform; + if (currentTransform) { + slide[0].style.transform = 'none'; + } + if (currentWebKitTransform) { + slide[0].style.webkitTransform = 'none'; + } + if (params.roundLengths) { + slideSize = swiper.isHorizontal() + ? slide.outerWidth(true) + : slide.outerHeight(true); + } else { + // eslint-disable-next-line + if (swiper.isHorizontal()) { + var width = parseFloat(slideStyles.getPropertyValue('width')); + var paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left')); + var paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right')); + var marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left')); + var marginRight = parseFloat(slideStyles.getPropertyValue('margin-right')); + var boxSizing = slideStyles.getPropertyValue('box-sizing'); + if (boxSizing && boxSizing === 'border-box') { + slideSize = width + marginLeft + marginRight; + } else { + slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight; + } + } else { + var height = parseFloat(slideStyles.getPropertyValue('height')); + var paddingTop = parseFloat(slideStyles.getPropertyValue('padding-top')); + var paddingBottom = parseFloat(slideStyles.getPropertyValue('padding-bottom')); + var marginTop = parseFloat(slideStyles.getPropertyValue('margin-top')); + var marginBottom = parseFloat(slideStyles.getPropertyValue('margin-bottom')); + var boxSizing$1 = slideStyles.getPropertyValue('box-sizing'); + if (boxSizing$1 && boxSizing$1 === 'border-box') { + slideSize = height + marginTop + marginBottom; + } else { + slideSize = height + paddingTop + paddingBottom + marginTop + marginBottom; + } + } + } + if (currentTransform) { + slide[0].style.transform = currentTransform; + } + if (currentWebKitTransform) { + slide[0].style.webkitTransform = currentWebKitTransform; + } + if (params.roundLengths) { slideSize = Math.floor(slideSize); } + } else { + slideSize = (swiperSize - ((params.slidesPerView - 1) * spaceBetween)) / params.slidesPerView; + if (params.roundLengths) { slideSize = Math.floor(slideSize); } + + if (slides[i]) { + if (swiper.isHorizontal()) { + slides[i].style.width = slideSize + "px"; + } else { + slides[i].style.height = slideSize + "px"; + } + } + } + if (slides[i]) { + slides[i].swiperSlideSize = slideSize; + } + slidesSizesGrid.push(slideSize); + + + if (params.centeredSlides) { + slidePosition = slidePosition + (slideSize / 2) + (prevSlideSize / 2) + spaceBetween; + if (prevSlideSize === 0 && i !== 0) { slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; } + if (i === 0) { slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; } + if (Math.abs(slidePosition) < 1 / 1000) { slidePosition = 0; } + if (params.roundLengths) { slidePosition = Math.floor(slidePosition); } + if ((index) % params.slidesPerGroup === 0) { snapGrid.push(slidePosition); } + slidesGrid.push(slidePosition); + } else { + if (params.roundLengths) { slidePosition = Math.floor(slidePosition); } + if ((index) % params.slidesPerGroup === 0) { snapGrid.push(slidePosition); } + slidesGrid.push(slidePosition); + slidePosition = slidePosition + slideSize + spaceBetween; + } + + swiper.virtualSize += slideSize + spaceBetween; + + prevSlideSize = slideSize; + + index += 1; + } + swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter; + var newSlidesGrid; + + if ( + rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) { + $wrapperEl.css({ width: ((swiper.virtualSize + params.spaceBetween) + "px") }); + } + if (!Support.flexbox || params.setWrapperSize) { + if (swiper.isHorizontal()) { $wrapperEl.css({ width: ((swiper.virtualSize + params.spaceBetween) + "px") }); } + else { $wrapperEl.css({ height: ((swiper.virtualSize + params.spaceBetween) + "px") }); } + } + + if (params.slidesPerColumn > 1) { + swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumberEvenToRows; + swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween; + if (swiper.isHorizontal()) { $wrapperEl.css({ width: ((swiper.virtualSize + params.spaceBetween) + "px") }); } + else { $wrapperEl.css({ height: ((swiper.virtualSize + params.spaceBetween) + "px") }); } + if (params.centeredSlides) { + newSlidesGrid = []; + for (var i$1 = 0; i$1 < snapGrid.length; i$1 += 1) { + var slidesGridItem = snapGrid[i$1]; + if (params.roundLengths) { slidesGridItem = Math.floor(slidesGridItem); } + if (snapGrid[i$1] < swiper.virtualSize + snapGrid[0]) { newSlidesGrid.push(slidesGridItem); } + } + snapGrid = newSlidesGrid; + } + } + + // Remove last grid elements depending on width + if (!params.centeredSlides) { + newSlidesGrid = []; + for (var i$2 = 0; i$2 < snapGrid.length; i$2 += 1) { + var slidesGridItem$1 = snapGrid[i$2]; + if (params.roundLengths) { slidesGridItem$1 = Math.floor(slidesGridItem$1); } + if (snapGrid[i$2] <= swiper.virtualSize - swiperSize) { + newSlidesGrid.push(slidesGridItem$1); + } + } + snapGrid = newSlidesGrid; + if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) { + snapGrid.push(swiper.virtualSize - swiperSize); + } + } + if (snapGrid.length === 0) { snapGrid = [0]; } + + if (params.spaceBetween !== 0) { + if (swiper.isHorizontal()) { + if (rtl) { slides.css({ marginLeft: (spaceBetween + "px") }); } + else { slides.css({ marginRight: (spaceBetween + "px") }); } + } else { slides.css({ marginBottom: (spaceBetween + "px") }); } + } + + if (params.centerInsufficientSlides) { + var allSlidesSize = 0; + slidesSizesGrid.forEach(function (slideSizeValue) { + allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0); + }); + allSlidesSize -= params.spaceBetween; + if (allSlidesSize < swiperSize) { + var allSlidesOffset = (swiperSize - allSlidesSize) / 2; + snapGrid.forEach(function (snap, snapIndex) { + snapGrid[snapIndex] = snap - allSlidesOffset; + }); + slidesGrid.forEach(function (snap, snapIndex) { + slidesGrid[snapIndex] = snap + allSlidesOffset; + }); + } + } + + Utils.extend(swiper, { + slides: slides, + snapGrid: snapGrid, + slidesGrid: slidesGrid, + slidesSizesGrid: slidesSizesGrid, + }); + + if (slidesLength !== previousSlidesLength) { + swiper.emit('slidesLengthChange'); + } + if (snapGrid.length !== previousSnapGridLength) { + if (swiper.params.watchOverflow) { swiper.checkOverflow(); } + swiper.emit('snapGridLengthChange'); + } + if (slidesGrid.length !== previousSlidesGridLength) { + swiper.emit('slidesGridLengthChange'); + } + + if (params.watchSlidesProgress || params.watchSlidesVisibility) { + swiper.updateSlidesOffset(); + } + } + + function updateAutoHeight (speed) { + var swiper = this; + var activeSlides = []; + var newHeight = 0; + var i; + if (typeof speed === 'number') { + swiper.setTransition(speed); + } else if (speed === true) { + swiper.setTransition(swiper.params.speed); + } + // Find slides currently in view + if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) { + for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) { + var index = swiper.activeIndex + i; + if (index > swiper.slides.length) { break; } + activeSlides.push(swiper.slides.eq(index)[0]); + } + } else { + activeSlides.push(swiper.slides.eq(swiper.activeIndex)[0]); + } + + // Find new height from highest slide in view + for (i = 0; i < activeSlides.length; i += 1) { + if (typeof activeSlides[i] !== 'undefined') { + var height = activeSlides[i].offsetHeight; + newHeight = height > newHeight ? height : newHeight; + } + } + + // Update Height + if (newHeight) { swiper.$wrapperEl.css('height', (newHeight + "px")); } + } + + function updateSlidesOffset () { + var swiper = this; + var slides = swiper.slides; + for (var i = 0; i < slides.length; i += 1) { + slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop; + } + } + + function updateSlidesProgress (translate) { + if ( translate === void 0 ) translate = (this && this.translate) || 0; + + var swiper = this; + var params = swiper.params; + + var slides = swiper.slides; + var rtl = swiper.rtlTranslate; + + if (slides.length === 0) { return; } + if (typeof slides[0].swiperSlideOffset === 'undefined') { swiper.updateSlidesOffset(); } + + var offsetCenter = -translate; + if (rtl) { offsetCenter = translate; } + + // Visible Slides + slides.removeClass(params.slideVisibleClass); + + swiper.visibleSlidesIndexes = []; + swiper.visibleSlides = []; + + for (var i = 0; i < slides.length; i += 1) { + var slide = slides[i]; + var slideProgress = ( + (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0)) - slide.swiperSlideOffset + ) / (slide.swiperSlideSize + params.spaceBetween); + if (params.watchSlidesVisibility) { + var slideBefore = -(offsetCenter - slide.swiperSlideOffset); + var slideAfter = slideBefore + swiper.slidesSizesGrid[i]; + var isVisible = (slideBefore >= 0 && slideBefore < swiper.size) + || (slideAfter > 0 && slideAfter <= swiper.size) + || (slideBefore <= 0 && slideAfter >= swiper.size); + if (isVisible) { + swiper.visibleSlides.push(slide); + swiper.visibleSlidesIndexes.push(i); + slides.eq(i).addClass(params.slideVisibleClass); + } + } + slide.progress = rtl ? -slideProgress : slideProgress; + } + swiper.visibleSlides = $(swiper.visibleSlides); + } + + function updateProgress (translate) { + if ( translate === void 0 ) translate = (this && this.translate) || 0; + + var swiper = this; + var params = swiper.params; + + var translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); + var progress = swiper.progress; + var isBeginning = swiper.isBeginning; + var isEnd = swiper.isEnd; + var wasBeginning = isBeginning; + var wasEnd = isEnd; + if (translatesDiff === 0) { + progress = 0; + isBeginning = true; + isEnd = true; + } else { + progress = (translate - swiper.minTranslate()) / (translatesDiff); + isBeginning = progress <= 0; + isEnd = progress >= 1; + } + Utils.extend(swiper, { + progress: progress, + isBeginning: isBeginning, + isEnd: isEnd, + }); + + if (params.watchSlidesProgress || params.watchSlidesVisibility) { swiper.updateSlidesProgress(translate); } + + if (isBeginning && !wasBeginning) { + swiper.emit('reachBeginning toEdge'); + } + if (isEnd && !wasEnd) { + swiper.emit('reachEnd toEdge'); + } + if ((wasBeginning && !isBeginning) || (wasEnd && !isEnd)) { + swiper.emit('fromEdge'); + } + + swiper.emit('progress', progress); + } + + function updateSlidesClasses () { + var swiper = this; + + var slides = swiper.slides; + var params = swiper.params; + var $wrapperEl = swiper.$wrapperEl; + var activeIndex = swiper.activeIndex; + var realIndex = swiper.realIndex; + var isVirtual = swiper.virtual && params.virtual.enabled; + + slides.removeClass(((params.slideActiveClass) + " " + (params.slideNextClass) + " " + (params.slidePrevClass) + " " + (params.slideDuplicateActiveClass) + " " + (params.slideDuplicateNextClass) + " " + (params.slideDuplicatePrevClass))); + + var activeSlide; + if (isVirtual) { + activeSlide = swiper.$wrapperEl.find(("." + (params.slideClass) + "[data-swiper-slide-index=\"" + activeIndex + "\"]")); + } else { + activeSlide = slides.eq(activeIndex); + } + + // Active classes + activeSlide.addClass(params.slideActiveClass); + + if (params.loop) { + // Duplicate to all looped slides + if (activeSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(("." + (params.slideClass) + ":not(." + (params.slideDuplicateClass) + ")[data-swiper-slide-index=\"" + realIndex + "\"]")) + .addClass(params.slideDuplicateActiveClass); + } else { + $wrapperEl + .children(("." + (params.slideClass) + "." + (params.slideDuplicateClass) + "[data-swiper-slide-index=\"" + realIndex + "\"]")) + .addClass(params.slideDuplicateActiveClass); + } + } + // Next Slide + var nextSlide = activeSlide.nextAll(("." + (params.slideClass))).eq(0).addClass(params.slideNextClass); + if (params.loop && nextSlide.length === 0) { + nextSlide = slides.eq(0); + nextSlide.addClass(params.slideNextClass); + } + // Prev Slide + var prevSlide = activeSlide.prevAll(("." + (params.slideClass))).eq(0).addClass(params.slidePrevClass); + if (params.loop && prevSlide.length === 0) { + prevSlide = slides.eq(-1); + prevSlide.addClass(params.slidePrevClass); + } + if (params.loop) { + // Duplicate to all looped slides + if (nextSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(("." + (params.slideClass) + ":not(." + (params.slideDuplicateClass) + ")[data-swiper-slide-index=\"" + (nextSlide.attr('data-swiper-slide-index')) + "\"]")) + .addClass(params.slideDuplicateNextClass); + } else { + $wrapperEl + .children(("." + (params.slideClass) + "." + (params.slideDuplicateClass) + "[data-swiper-slide-index=\"" + (nextSlide.attr('data-swiper-slide-index')) + "\"]")) + .addClass(params.slideDuplicateNextClass); + } + if (prevSlide.hasClass(params.slideDuplicateClass)) { + $wrapperEl + .children(("." + (params.slideClass) + ":not(." + (params.slideDuplicateClass) + ")[data-swiper-slide-index=\"" + (prevSlide.attr('data-swiper-slide-index')) + "\"]")) + .addClass(params.slideDuplicatePrevClass); + } else { + $wrapperEl + .children(("." + (params.slideClass) + "." + (params.slideDuplicateClass) + "[data-swiper-slide-index=\"" + (prevSlide.attr('data-swiper-slide-index')) + "\"]")) + .addClass(params.slideDuplicatePrevClass); + } + } + } + + function updateActiveIndex (newActiveIndex) { + var swiper = this; + var translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; + var slidesGrid = swiper.slidesGrid; + var snapGrid = swiper.snapGrid; + var params = swiper.params; + var previousIndex = swiper.activeIndex; + var previousRealIndex = swiper.realIndex; + var previousSnapIndex = swiper.snapIndex; + var activeIndex = newActiveIndex; + var snapIndex; + if (typeof activeIndex === 'undefined') { + for (var i = 0; i < slidesGrid.length; i += 1) { + if (typeof slidesGrid[i + 1] !== 'undefined') { + if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - ((slidesGrid[i + 1] - slidesGrid[i]) / 2)) { + activeIndex = i; + } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) { + activeIndex = i + 1; + } + } else if (translate >= slidesGrid[i]) { + activeIndex = i; + } + } + // Normalize slideIndex + if (params.normalizeSlideIndex) { + if (activeIndex < 0 || typeof activeIndex === 'undefined') { activeIndex = 0; } + } + } + if (snapGrid.indexOf(translate) >= 0) { + snapIndex = snapGrid.indexOf(translate); + } else { + snapIndex = Math.floor(activeIndex / params.slidesPerGroup); + } + if (snapIndex >= snapGrid.length) { snapIndex = snapGrid.length - 1; } + if (activeIndex === previousIndex) { + if (snapIndex !== previousSnapIndex) { + swiper.snapIndex = snapIndex; + swiper.emit('snapIndexChange'); + } + return; + } + + // Get real index + var realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10); + + Utils.extend(swiper, { + snapIndex: snapIndex, + realIndex: realIndex, + previousIndex: previousIndex, + activeIndex: activeIndex, + }); + swiper.emit('activeIndexChange'); + swiper.emit('snapIndexChange'); + if (previousRealIndex !== realIndex) { + swiper.emit('realIndexChange'); + } + swiper.emit('slideChange'); + } + + function updateClickedSlide (e) { + var swiper = this; + var params = swiper.params; + var slide = $(e.target).closest(("." + (params.slideClass)))[0]; + var slideFound = false; + if (slide) { + for (var i = 0; i < swiper.slides.length; i += 1) { + if (swiper.slides[i] === slide) { slideFound = true; } + } + } + + if (slide && slideFound) { + swiper.clickedSlide = slide; + if (swiper.virtual && swiper.params.virtual.enabled) { + swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10); + } else { + swiper.clickedIndex = $(slide).index(); + } + } else { + swiper.clickedSlide = undefined; + swiper.clickedIndex = undefined; + return; + } + if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) { + swiper.slideToClickedSlide(); + } + } + + var update = { + updateSize: updateSize, + updateSlides: updateSlides, + updateAutoHeight: updateAutoHeight, + updateSlidesOffset: updateSlidesOffset, + updateSlidesProgress: updateSlidesProgress, + updateProgress: updateProgress, + updateSlidesClasses: updateSlidesClasses, + updateActiveIndex: updateActiveIndex, + updateClickedSlide: updateClickedSlide, + }; + + function getTranslate (axis) { + if ( axis === void 0 ) axis = this.isHorizontal() ? 'x' : 'y'; + + var swiper = this; + + var params = swiper.params; + var rtl = swiper.rtlTranslate; + var translate = swiper.translate; + var $wrapperEl = swiper.$wrapperEl; + + if (params.virtualTranslate) { + return rtl ? -translate : translate; + } + + var currentTranslate = Utils.getTranslate($wrapperEl[0], axis); + if (rtl) { currentTranslate = -currentTranslate; } + + return currentTranslate || 0; + } + + function setTranslate (translate, byController) { + var swiper = this; + var rtl = swiper.rtlTranslate; + var params = swiper.params; + var $wrapperEl = swiper.$wrapperEl; + var progress = swiper.progress; + var x = 0; + var y = 0; + var z = 0; + + if (swiper.isHorizontal()) { + x = rtl ? -translate : translate; + } else { + y = translate; + } + + if (params.roundLengths) { + x = Math.floor(x); + y = Math.floor(y); + } + + if (!params.virtualTranslate) { + if (Support.transforms3d) { $wrapperEl.transform(("translate3d(" + x + "px, " + y + "px, " + z + "px)")); } + else { $wrapperEl.transform(("translate(" + x + "px, " + y + "px)")); } + } + swiper.previousTranslate = swiper.translate; + swiper.translate = swiper.isHorizontal() ? x : y; + + // Check if we need to update progress + var newProgress; + var translatesDiff = swiper.maxTranslate() - swiper.minTranslate(); + if (translatesDiff === 0) { + newProgress = 0; + } else { + newProgress = (translate - swiper.minTranslate()) / (translatesDiff); + } + if (newProgress !== progress) { + swiper.updateProgress(translate); + } + + swiper.emit('setTranslate', swiper.translate, byController); + } + + function minTranslate () { + return (-this.snapGrid[0]); + } + + function maxTranslate () { + return (-this.snapGrid[this.snapGrid.length - 1]); + } + + var translate = { + getTranslate: getTranslate, + setTranslate: setTranslate, + minTranslate: minTranslate, + maxTranslate: maxTranslate, + }; + + function setTransition (duration, byController) { + var swiper = this; + + swiper.$wrapperEl.transition(duration); + + swiper.emit('setTransition', duration, byController); + } + + function transitionStart (runCallbacks, direction) { + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + var activeIndex = swiper.activeIndex; + var params = swiper.params; + var previousIndex = swiper.previousIndex; + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + + var dir = direction; + if (!dir) { + if (activeIndex > previousIndex) { dir = 'next'; } + else if (activeIndex < previousIndex) { dir = 'prev'; } + else { dir = 'reset'; } + } + + swiper.emit('transitionStart'); + + if (runCallbacks && activeIndex !== previousIndex) { + if (dir === 'reset') { + swiper.emit('slideResetTransitionStart'); + return; + } + swiper.emit('slideChangeTransitionStart'); + if (dir === 'next') { + swiper.emit('slideNextTransitionStart'); + } else { + swiper.emit('slidePrevTransitionStart'); + } + } + } + + function transitionEnd$1 (runCallbacks, direction) { + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + var activeIndex = swiper.activeIndex; + var previousIndex = swiper.previousIndex; + swiper.animating = false; + swiper.setTransition(0); + + var dir = direction; + if (!dir) { + if (activeIndex > previousIndex) { dir = 'next'; } + else if (activeIndex < previousIndex) { dir = 'prev'; } + else { dir = 'reset'; } + } + + swiper.emit('transitionEnd'); + + if (runCallbacks && activeIndex !== previousIndex) { + if (dir === 'reset') { + swiper.emit('slideResetTransitionEnd'); + return; + } + swiper.emit('slideChangeTransitionEnd'); + if (dir === 'next') { + swiper.emit('slideNextTransitionEnd'); + } else { + swiper.emit('slidePrevTransitionEnd'); + } + } + } + + var transition$1 = { + setTransition: setTransition, + transitionStart: transitionStart, + transitionEnd: transitionEnd$1, + }; + + function slideTo (index, speed, runCallbacks, internal) { + if ( index === void 0 ) index = 0; + if ( speed === void 0 ) speed = this.params.speed; + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + var slideIndex = index; + if (slideIndex < 0) { slideIndex = 0; } + + var params = swiper.params; + var snapGrid = swiper.snapGrid; + var slidesGrid = swiper.slidesGrid; + var previousIndex = swiper.previousIndex; + var activeIndex = swiper.activeIndex; + var rtl = swiper.rtlTranslate; + if (swiper.animating && params.preventInteractionOnTransition) { + return false; + } + + var snapIndex = Math.floor(slideIndex / params.slidesPerGroup); + if (snapIndex >= snapGrid.length) { snapIndex = snapGrid.length - 1; } + + if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) { + swiper.emit('beforeSlideChangeStart'); + } + + var translate = -snapGrid[snapIndex]; + + // Update progress + swiper.updateProgress(translate); + + // Normalize slideIndex + if (params.normalizeSlideIndex) { + for (var i = 0; i < slidesGrid.length; i += 1) { + if (-Math.floor(translate * 100) >= Math.floor(slidesGrid[i] * 100)) { + slideIndex = i; + } + } + } + // Directions locks + if (swiper.initialized && slideIndex !== activeIndex) { + if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) { + return false; + } + if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) { + if ((activeIndex || 0) !== slideIndex) { return false; } + } + } + + var direction; + if (slideIndex > activeIndex) { direction = 'next'; } + else if (slideIndex < activeIndex) { direction = 'prev'; } + else { direction = 'reset'; } + + + // Update Index + if ((rtl && -translate === swiper.translate) || (!rtl && translate === swiper.translate)) { + swiper.updateActiveIndex(slideIndex); + // Update Height + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + swiper.updateSlidesClasses(); + if (params.effect !== 'slide') { + swiper.setTranslate(translate); + } + if (direction !== 'reset') { + swiper.transitionStart(runCallbacks, direction); + swiper.transitionEnd(runCallbacks, direction); + } + return false; + } + + if (speed === 0 || !Support.transition) { + swiper.setTransition(0); + swiper.setTranslate(translate); + swiper.updateActiveIndex(slideIndex); + swiper.updateSlidesClasses(); + swiper.emit('beforeTransitionStart', speed, internal); + swiper.transitionStart(runCallbacks, direction); + swiper.transitionEnd(runCallbacks, direction); + } else { + swiper.setTransition(speed); + swiper.setTranslate(translate); + swiper.updateActiveIndex(slideIndex); + swiper.updateSlidesClasses(); + swiper.emit('beforeTransitionStart', speed, internal); + swiper.transitionStart(runCallbacks, direction); + if (!swiper.animating) { + swiper.animating = true; + if (!swiper.onSlideToWrapperTransitionEnd) { + swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) { + if (!swiper || swiper.destroyed) { return; } + if (e.target !== this) { return; } + swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); + swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); + swiper.onSlideToWrapperTransitionEnd = null; + delete swiper.onSlideToWrapperTransitionEnd; + swiper.transitionEnd(runCallbacks, direction); + }; + } + swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd); + swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd); + } + } + + return true; + } + + function slideToLoop (index, speed, runCallbacks, internal) { + if ( index === void 0 ) index = 0; + if ( speed === void 0 ) speed = this.params.speed; + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + var newIndex = index; + if (swiper.params.loop) { + newIndex += swiper.loopedSlides; + } + + return swiper.slideTo(newIndex, speed, runCallbacks, internal); + } + + /* eslint no-unused-vars: "off" */ + function slideNext (speed, runCallbacks, internal) { + if ( speed === void 0 ) speed = this.params.speed; + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + var params = swiper.params; + var animating = swiper.animating; + if (params.loop) { + if (animating) { return false; } + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal); + } + return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal); + } + + /* eslint no-unused-vars: "off" */ + function slidePrev (speed, runCallbacks, internal) { + if ( speed === void 0 ) speed = this.params.speed; + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + var params = swiper.params; + var animating = swiper.animating; + var snapGrid = swiper.snapGrid; + var slidesGrid = swiper.slidesGrid; + var rtlTranslate = swiper.rtlTranslate; + + if (params.loop) { + if (animating) { return false; } + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + } + var translate = rtlTranslate ? swiper.translate : -swiper.translate; + function normalize(val) { + if (val < 0) { return -Math.floor(Math.abs(val)); } + return Math.floor(val); + } + var normalizedTranslate = normalize(translate); + var normalizedSnapGrid = snapGrid.map(function (val) { return normalize(val); }); + var normalizedSlidesGrid = slidesGrid.map(function (val) { return normalize(val); }); + + var currentSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate)]; + var prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1]; + var prevIndex; + if (typeof prevSnap !== 'undefined') { + prevIndex = slidesGrid.indexOf(prevSnap); + if (prevIndex < 0) { prevIndex = swiper.activeIndex - 1; } + } + return swiper.slideTo(prevIndex, speed, runCallbacks, internal); + } + + /* eslint no-unused-vars: "off" */ + function slideReset (speed, runCallbacks, internal) { + if ( speed === void 0 ) speed = this.params.speed; + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal); + } + + /* eslint no-unused-vars: "off" */ + function slideToClosest (speed, runCallbacks, internal) { + if ( speed === void 0 ) speed = this.params.speed; + if ( runCallbacks === void 0 ) runCallbacks = true; + + var swiper = this; + var index = swiper.activeIndex; + var snapIndex = Math.floor(index / swiper.params.slidesPerGroup); + + if (snapIndex < swiper.snapGrid.length - 1) { + var translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate; + + var currentSnap = swiper.snapGrid[snapIndex]; + var nextSnap = swiper.snapGrid[snapIndex + 1]; + + if ((translate - currentSnap) > (nextSnap - currentSnap) / 2) { + index = swiper.params.slidesPerGroup; + } + } + + return swiper.slideTo(index, speed, runCallbacks, internal); + } + + function slideToClickedSlide () { + var swiper = this; + var params = swiper.params; + var $wrapperEl = swiper.$wrapperEl; + + var slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView; + var slideToIndex = swiper.clickedIndex; + var realIndex; + if (params.loop) { + if (swiper.animating) { return; } + realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10); + if (params.centeredSlides) { + if ( + (slideToIndex < swiper.loopedSlides - (slidesPerView / 2)) + || (slideToIndex > (swiper.slides.length - swiper.loopedSlides) + (slidesPerView / 2)) + ) { + swiper.loopFix(); + slideToIndex = $wrapperEl + .children(("." + (params.slideClass) + "[data-swiper-slide-index=\"" + realIndex + "\"]:not(." + (params.slideDuplicateClass) + ")")) + .eq(0) + .index(); + + Utils.nextTick(function () { + swiper.slideTo(slideToIndex); + }); + } else { + swiper.slideTo(slideToIndex); + } + } else if (slideToIndex > swiper.slides.length - slidesPerView) { + swiper.loopFix(); + slideToIndex = $wrapperEl + .children(("." + (params.slideClass) + "[data-swiper-slide-index=\"" + realIndex + "\"]:not(." + (params.slideDuplicateClass) + ")")) + .eq(0) + .index(); + + Utils.nextTick(function () { + swiper.slideTo(slideToIndex); + }); + } else { + swiper.slideTo(slideToIndex); + } + } else { + swiper.slideTo(slideToIndex); + } + } + + var slide = { + slideTo: slideTo, + slideToLoop: slideToLoop, + slideNext: slideNext, + slidePrev: slidePrev, + slideReset: slideReset, + slideToClosest: slideToClosest, + slideToClickedSlide: slideToClickedSlide, + }; + + function loopCreate () { + var swiper = this; + var params = swiper.params; + var $wrapperEl = swiper.$wrapperEl; + // Remove duplicated slides + $wrapperEl.children(("." + (params.slideClass) + "." + (params.slideDuplicateClass))).remove(); + + var slides = $wrapperEl.children(("." + (params.slideClass))); + + if (params.loopFillGroupWithBlank) { + var blankSlidesNum = params.slidesPerGroup - (slides.length % params.slidesPerGroup); + if (blankSlidesNum !== params.slidesPerGroup) { + for (var i = 0; i < blankSlidesNum; i += 1) { + var blankNode = $(doc.createElement('div')).addClass(((params.slideClass) + " " + (params.slideBlankClass))); + $wrapperEl.append(blankNode); + } + slides = $wrapperEl.children(("." + (params.slideClass))); + } + } + + if (params.slidesPerView === 'auto' && !params.loopedSlides) { params.loopedSlides = slides.length; } + + swiper.loopedSlides = parseInt(params.loopedSlides || params.slidesPerView, 10); + swiper.loopedSlides += params.loopAdditionalSlides; + if (swiper.loopedSlides > slides.length) { + swiper.loopedSlides = slides.length; + } + + var prependSlides = []; + var appendSlides = []; + slides.each(function (index, el) { + var slide = $(el); + if (index < swiper.loopedSlides) { appendSlides.push(el); } + if (index < slides.length && index >= slides.length - swiper.loopedSlides) { prependSlides.push(el); } + slide.attr('data-swiper-slide-index', index); + }); + for (var i$1 = 0; i$1 < appendSlides.length; i$1 += 1) { + $wrapperEl.append($(appendSlides[i$1].cloneNode(true)).addClass(params.slideDuplicateClass)); + } + for (var i$2 = prependSlides.length - 1; i$2 >= 0; i$2 -= 1) { + $wrapperEl.prepend($(prependSlides[i$2].cloneNode(true)).addClass(params.slideDuplicateClass)); + } + } + + function loopFix () { + var swiper = this; + var params = swiper.params; + var activeIndex = swiper.activeIndex; + var slides = swiper.slides; + var loopedSlides = swiper.loopedSlides; + var allowSlidePrev = swiper.allowSlidePrev; + var allowSlideNext = swiper.allowSlideNext; + var snapGrid = swiper.snapGrid; + var rtl = swiper.rtlTranslate; + var newIndex; + swiper.allowSlidePrev = true; + swiper.allowSlideNext = true; + + var snapTranslate = -snapGrid[activeIndex]; + var diff = snapTranslate - swiper.getTranslate(); + + + // Fix For Negative Oversliding + if (activeIndex < loopedSlides) { + newIndex = (slides.length - (loopedSlides * 3)) + activeIndex; + newIndex += loopedSlides; + var slideChanged = swiper.slideTo(newIndex, 0, false, true); + if (slideChanged && diff !== 0) { + swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); + } + } else if ((params.slidesPerView === 'auto' && activeIndex >= loopedSlides * 2) || (activeIndex >= slides.length - loopedSlides)) { + // Fix For Positive Oversliding + newIndex = -slides.length + activeIndex + loopedSlides; + newIndex += loopedSlides; + var slideChanged$1 = swiper.slideTo(newIndex, 0, false, true); + if (slideChanged$1 && diff !== 0) { + swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff); + } + } + swiper.allowSlidePrev = allowSlidePrev; + swiper.allowSlideNext = allowSlideNext; + } + + function loopDestroy () { + var swiper = this; + var $wrapperEl = swiper.$wrapperEl; + var params = swiper.params; + var slides = swiper.slides; + $wrapperEl.children(("." + (params.slideClass) + "." + (params.slideDuplicateClass) + ",." + (params.slideClass) + "." + (params.slideBlankClass))).remove(); + slides.removeAttr('data-swiper-slide-index'); + } + + var loop = { + loopCreate: loopCreate, + loopFix: loopFix, + loopDestroy: loopDestroy, + }; + + function setGrabCursor (moving) { + var swiper = this; + if (Support.touch || !swiper.params.simulateTouch || (swiper.params.watchOverflow && swiper.isLocked)) { return; } + var el = swiper.el; + el.style.cursor = 'move'; + el.style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab'; + el.style.cursor = moving ? '-moz-grabbin' : '-moz-grab'; + el.style.cursor = moving ? 'grabbing' : 'grab'; + } + + function unsetGrabCursor () { + var swiper = this; + if (Support.touch || (swiper.params.watchOverflow && swiper.isLocked)) { return; } + swiper.el.style.cursor = ''; + } + + var grabCursor = { + setGrabCursor: setGrabCursor, + unsetGrabCursor: unsetGrabCursor, + }; + + function appendSlide (slides) { + var swiper = this; + var $wrapperEl = swiper.$wrapperEl; + var params = swiper.params; + if (params.loop) { + swiper.loopDestroy(); + } + if (typeof slides === 'object' && 'length' in slides) { + for (var i = 0; i < slides.length; i += 1) { + if (slides[i]) { $wrapperEl.append(slides[i]); } + } + } else { + $wrapperEl.append(slides); + } + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } + } + + function prependSlide (slides) { + var swiper = this; + var params = swiper.params; + var $wrapperEl = swiper.$wrapperEl; + var activeIndex = swiper.activeIndex; + + if (params.loop) { + swiper.loopDestroy(); + } + var newActiveIndex = activeIndex + 1; + if (typeof slides === 'object' && 'length' in slides) { + for (var i = 0; i < slides.length; i += 1) { + if (slides[i]) { $wrapperEl.prepend(slides[i]); } + } + newActiveIndex = activeIndex + slides.length; + } else { + $wrapperEl.prepend(slides); + } + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } + swiper.slideTo(newActiveIndex, 0, false); + } + + function addSlide (index, slides) { + var swiper = this; + var $wrapperEl = swiper.$wrapperEl; + var params = swiper.params; + var activeIndex = swiper.activeIndex; + var activeIndexBuffer = activeIndex; + if (params.loop) { + activeIndexBuffer -= swiper.loopedSlides; + swiper.loopDestroy(); + swiper.slides = $wrapperEl.children(("." + (params.slideClass))); + } + var baseLength = swiper.slides.length; + if (index <= 0) { + swiper.prependSlide(slides); + return; + } + if (index >= baseLength) { + swiper.appendSlide(slides); + return; + } + var newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer; + + var slidesBuffer = []; + for (var i = baseLength - 1; i >= index; i -= 1) { + var currentSlide = swiper.slides.eq(i); + currentSlide.remove(); + slidesBuffer.unshift(currentSlide); + } + + if (typeof slides === 'object' && 'length' in slides) { + for (var i$1 = 0; i$1 < slides.length; i$1 += 1) { + if (slides[i$1]) { $wrapperEl.append(slides[i$1]); } + } + newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer; + } else { + $wrapperEl.append(slides); + } + + for (var i$2 = 0; i$2 < slidesBuffer.length; i$2 += 1) { + $wrapperEl.append(slidesBuffer[i$2]); + } + + if (params.loop) { + swiper.loopCreate(); + } + if (!(params.observer && Support.observer)) { + swiper.update(); + } + if (params.loop) { + swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); + } else { + swiper.slideTo(newActiveIndex, 0, false); + } + } + + function removeSlide (slidesIndexes) { + var swiper = this; + var params = swiper.params; + var $wrapperEl = swiper.$wrapperEl; + var activeIndex = swiper.activeIndex; + + var activeIndexBuffer = activeIndex; + if (params.loop) { + activeIndexBuffer -= swiper.loopedSlides; + swiper.loopDestroy(); + swiper.slides = $wrapperEl.children(("." + (params.slideClass))); + } + var newActiveIndex = activeIndexBuffer; + var indexToRemove; + + if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) { + for (var i = 0; i < slidesIndexes.length; i += 1) { + indexToRemove = slidesIndexes[i]; + if (swiper.slides[indexToRemove]) { swiper.slides.eq(indexToRemove).remove(); } + if (indexToRemove < newActiveIndex) { newActiveIndex -= 1; } + } + newActiveIndex = Math.max(newActiveIndex, 0); + } else { + indexToRemove = slidesIndexes; + if (swiper.slides[indexToRemove]) { swiper.slides.eq(indexToRemove).remove(); } + if (indexToRemove < newActiveIndex) { newActiveIndex -= 1; } + newActiveIndex = Math.max(newActiveIndex, 0); + } + + if (params.loop) { + swiper.loopCreate(); + } + + if (!(params.observer && Support.observer)) { + swiper.update(); + } + if (params.loop) { + swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false); + } else { + swiper.slideTo(newActiveIndex, 0, false); + } + } + + function removeAllSlides () { + var swiper = this; + + var slidesIndexes = []; + for (var i = 0; i < swiper.slides.length; i += 1) { + slidesIndexes.push(i); + } + swiper.removeSlide(slidesIndexes); + } + + var manipulation = { + appendSlide: appendSlide, + prependSlide: prependSlide, + addSlide: addSlide, + removeSlide: removeSlide, + removeAllSlides: removeAllSlides, + }; + + var Device = (function Device() { + var ua = win.navigator.userAgent; + + var device = { + ios: false, + android: false, + androidChrome: false, + desktop: false, + windows: false, + iphone: false, + ipod: false, + ipad: false, + cordova: win.cordova || win.phonegap, + phonegap: win.cordova || win.phonegap, + }; + + var windows = ua.match(/(Windows Phone);?[\s\/]+([\d.]+)?/); // eslint-disable-line + var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line + var ipad = ua.match(/(iPad).*OS\s([\d_]+)/); + var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/); + var iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/); + + + // Windows + if (windows) { + device.os = 'windows'; + device.osVersion = windows[2]; + device.windows = true; + } + // Android + if (android && !windows) { + device.os = 'android'; + device.osVersion = android[2]; + device.android = true; + device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0; + } + if (ipad || iphone || ipod) { + device.os = 'ios'; + device.ios = true; + } + // iOS + if (iphone && !ipod) { + device.osVersion = iphone[2].replace(/_/g, '.'); + device.iphone = true; + } + if (ipad) { + device.osVersion = ipad[2].replace(/_/g, '.'); + device.ipad = true; + } + if (ipod) { + device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null; + device.iphone = true; + } + // iOS 8+ changed UA + if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) { + if (device.osVersion.split('.')[0] === '10') { + device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0]; + } + } + + // Desktop + device.desktop = !(device.os || device.android || device.webView); + + // Webview + device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i); + + // Minimal UI + if (device.os && device.os === 'ios') { + var osVersionArr = device.osVersion.split('.'); + var metaViewport = doc.querySelector('meta[name="viewport"]'); + device.minimalUi = !device.webView + && (ipod || iphone) + && (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7) + && metaViewport && metaViewport.getAttribute('content').indexOf('minimal-ui') >= 0; + } + + // Pixel Ratio + device.pixelRatio = win.devicePixelRatio || 1; + + // Export object + return device; + }()); + + function onTouchStart (event) { + var swiper = this; + var data = swiper.touchEventsData; + var params = swiper.params; + var touches = swiper.touches; + if (swiper.animating && params.preventInteractionOnTransition) { + return; + } + var e = event; + if (e.originalEvent) { e = e.originalEvent; } + data.isTouchEvent = e.type === 'touchstart'; + if (!data.isTouchEvent && 'which' in e && e.which === 3) { return; } + if (!data.isTouchEvent && 'button' in e && e.button > 0) { return; } + if (data.isTouched && data.isMoved) { return; } + if (params.noSwiping && $(e.target).closest(params.noSwipingSelector ? params.noSwipingSelector : ("." + (params.noSwipingClass)))[0]) { + swiper.allowClick = true; + return; + } + if (params.swipeHandler) { + if (!$(e).closest(params.swipeHandler)[0]) { return; } + } + + touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; + touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; + var startX = touches.currentX; + var startY = touches.currentY; + + // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore + + var edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection; + var edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold; + if ( + edgeSwipeDetection + && ((startX <= edgeSwipeThreshold) + || (startX >= win.screen.width - edgeSwipeThreshold)) + ) { + return; + } + + Utils.extend(data, { + isTouched: true, + isMoved: false, + allowTouchCallbacks: true, + isScrolling: undefined, + startMoving: undefined, + }); + + touches.startX = startX; + touches.startY = startY; + data.touchStartTime = Utils.now(); + swiper.allowClick = true; + swiper.updateSize(); + swiper.swipeDirection = undefined; + if (params.threshold > 0) { data.allowThresholdMove = false; } + if (e.type !== 'touchstart') { + var preventDefault = true; + if ($(e.target).is(data.formElements)) { preventDefault = false; } + if ( + doc.activeElement + && $(doc.activeElement).is(data.formElements) + && doc.activeElement !== e.target + ) { + doc.activeElement.blur(); + } + + var shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault; + if (params.touchStartForcePreventDefault || shouldPreventDefault) { + e.preventDefault(); + } + } + swiper.emit('touchStart', e); + } + + function onTouchMove (event) { + var swiper = this; + var data = swiper.touchEventsData; + var params = swiper.params; + var touches = swiper.touches; + var rtl = swiper.rtlTranslate; + var e = event; + if (e.originalEvent) { e = e.originalEvent; } + if (!data.isTouched) { + if (data.startMoving && data.isScrolling) { + swiper.emit('touchMoveOpposite', e); + } + return; + } + if (data.isTouchEvent && e.type === 'mousemove') { return; } + var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; + var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; + if (e.preventedByNestedSwiper) { + touches.startX = pageX; + touches.startY = pageY; + return; + } + if (!swiper.allowTouchMove) { + // isMoved = true; + swiper.allowClick = false; + if (data.isTouched) { + Utils.extend(touches, { + startX: pageX, + startY: pageY, + currentX: pageX, + currentY: pageY, + }); + data.touchStartTime = Utils.now(); + } + return; + } + if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) { + if (swiper.isVertical()) { + // Vertical + if ( + (pageY < touches.startY && swiper.translate <= swiper.maxTranslate()) + || (pageY > touches.startY && swiper.translate >= swiper.minTranslate()) + ) { + data.isTouched = false; + data.isMoved = false; + return; + } + } else if ( + (pageX < touches.startX && swiper.translate <= swiper.maxTranslate()) + || (pageX > touches.startX && swiper.translate >= swiper.minTranslate()) + ) { + return; + } + } + if (data.isTouchEvent && doc.activeElement) { + if (e.target === doc.activeElement && $(e.target).is(data.formElements)) { + data.isMoved = true; + swiper.allowClick = false; + return; + } + } + if (data.allowTouchCallbacks) { + swiper.emit('touchMove', e); + } + if (e.targetTouches && e.targetTouches.length > 1) { return; } + + touches.currentX = pageX; + touches.currentY = pageY; + + var diffX = touches.currentX - touches.startX; + var diffY = touches.currentY - touches.startY; + if (swiper.params.threshold && Math.sqrt((Math.pow( diffX, 2 )) + (Math.pow( diffY, 2 ))) < swiper.params.threshold) { return; } + + if (typeof data.isScrolling === 'undefined') { + var touchAngle; + if ((swiper.isHorizontal() && touches.currentY === touches.startY) || (swiper.isVertical() && touches.currentX === touches.startX)) { + data.isScrolling = false; + } else { + // eslint-disable-next-line + if ((diffX * diffX) + (diffY * diffY) >= 25) { + touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI; + data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : (90 - touchAngle > params.touchAngle); + } + } + } + if (data.isScrolling) { + swiper.emit('touchMoveOpposite', e); + } + if (typeof data.startMoving === 'undefined') { + if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) { + data.startMoving = true; + } + } + if (data.isScrolling) { + data.isTouched = false; + return; + } + if (!data.startMoving) { + return; + } + swiper.allowClick = false; + e.preventDefault(); + if (params.touchMoveStopPropagation && !params.nested) { + e.stopPropagation(); + } + + if (!data.isMoved) { + if (params.loop) { + swiper.loopFix(); + } + data.startTranslate = swiper.getTranslate(); + swiper.setTransition(0); + if (swiper.animating) { + swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend'); + } + data.allowMomentumBounce = false; + // Grab Cursor + if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { + swiper.setGrabCursor(true); + } + swiper.emit('sliderFirstMove', e); + } + swiper.emit('sliderMove', e); + data.isMoved = true; + + var diff = swiper.isHorizontal() ? diffX : diffY; + touches.diff = diff; + + diff *= params.touchRatio; + if (rtl) { diff = -diff; } + + swiper.swipeDirection = diff > 0 ? 'prev' : 'next'; + data.currentTranslate = diff + data.startTranslate; + + var disableParentSwiper = true; + var resistanceRatio = params.resistanceRatio; + if (params.touchReleaseOnEdges) { + resistanceRatio = 0; + } + if ((diff > 0 && data.currentTranslate > swiper.minTranslate())) { + disableParentSwiper = false; + if (params.resistance) { data.currentTranslate = (swiper.minTranslate() - 1) + (Math.pow( (-swiper.minTranslate() + data.startTranslate + diff), resistanceRatio )); } + } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) { + disableParentSwiper = false; + if (params.resistance) { data.currentTranslate = (swiper.maxTranslate() + 1) - (Math.pow( (swiper.maxTranslate() - data.startTranslate - diff), resistanceRatio )); } + } + + if (disableParentSwiper) { + e.preventedByNestedSwiper = true; + } + + // Directions locks + if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) { + data.currentTranslate = data.startTranslate; + } + if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) { + data.currentTranslate = data.startTranslate; + } + + + // Threshold + if (params.threshold > 0) { + if (Math.abs(diff) > params.threshold || data.allowThresholdMove) { + if (!data.allowThresholdMove) { + data.allowThresholdMove = true; + touches.startX = touches.currentX; + touches.startY = touches.currentY; + data.currentTranslate = data.startTranslate; + touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY; + return; + } + } else { + data.currentTranslate = data.startTranslate; + return; + } + } + + if (!params.followFinger) { return; } + + // Update active index in free mode + if (params.freeMode || params.watchSlidesProgress || params.watchSlidesVisibility) { + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + if (params.freeMode) { + // Velocity + if (data.velocities.length === 0) { + data.velocities.push({ + position: touches[swiper.isHorizontal() ? 'startX' : 'startY'], + time: data.touchStartTime, + }); + } + data.velocities.push({ + position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'], + time: Utils.now(), + }); + } + // Update progress + swiper.updateProgress(data.currentTranslate); + // Update translate + swiper.setTranslate(data.currentTranslate); + } + + function onTouchEnd (event) { + var swiper = this; + var data = swiper.touchEventsData; + + var params = swiper.params; + var touches = swiper.touches; + var rtl = swiper.rtlTranslate; + var $wrapperEl = swiper.$wrapperEl; + var slidesGrid = swiper.slidesGrid; + var snapGrid = swiper.snapGrid; + var e = event; + if (e.originalEvent) { e = e.originalEvent; } + if (data.allowTouchCallbacks) { + swiper.emit('touchEnd', e); + } + data.allowTouchCallbacks = false; + if (!data.isTouched) { + if (data.isMoved && params.grabCursor) { + swiper.setGrabCursor(false); + } + data.isMoved = false; + data.startMoving = false; + return; + } + // Return Grab Cursor + if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) { + swiper.setGrabCursor(false); + } + + // Time diff + var touchEndTime = Utils.now(); + var timeDiff = touchEndTime - data.touchStartTime; + + // Tap, doubleTap, Click + if (swiper.allowClick) { + swiper.updateClickedSlide(e); + swiper.emit('tap', e); + if (timeDiff < 300 && (touchEndTime - data.lastClickTime) > 300) { + if (data.clickTimeout) { clearTimeout(data.clickTimeout); } + data.clickTimeout = Utils.nextTick(function () { + if (!swiper || swiper.destroyed) { return; } + swiper.emit('click', e); + }, 300); + } + if (timeDiff < 300 && (touchEndTime - data.lastClickTime) < 300) { + if (data.clickTimeout) { clearTimeout(data.clickTimeout); } + swiper.emit('doubleTap', e); + } + } + + data.lastClickTime = Utils.now(); + Utils.nextTick(function () { + if (!swiper.destroyed) { swiper.allowClick = true; } + }); + + if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) { + data.isTouched = false; + data.isMoved = false; + data.startMoving = false; + return; + } + data.isTouched = false; + data.isMoved = false; + data.startMoving = false; + + var currentPos; + if (params.followFinger) { + currentPos = rtl ? swiper.translate : -swiper.translate; + } else { + currentPos = -data.currentTranslate; + } + + if (params.freeMode) { + if (currentPos < -swiper.minTranslate()) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (currentPos > -swiper.maxTranslate()) { + if (swiper.slides.length < snapGrid.length) { + swiper.slideTo(snapGrid.length - 1); + } else { + swiper.slideTo(swiper.slides.length - 1); + } + return; + } + + if (params.freeModeMomentum) { + if (data.velocities.length > 1) { + var lastMoveEvent = data.velocities.pop(); + var velocityEvent = data.velocities.pop(); + + var distance = lastMoveEvent.position - velocityEvent.position; + var time = lastMoveEvent.time - velocityEvent.time; + swiper.velocity = distance / time; + swiper.velocity /= 2; + if (Math.abs(swiper.velocity) < params.freeModeMinimumVelocity) { + swiper.velocity = 0; + } + // this implies that the user stopped moving a finger then released. + // There would be no events with distance zero, so the last event is stale. + if (time > 150 || (Utils.now() - lastMoveEvent.time) > 300) { + swiper.velocity = 0; + } + } else { + swiper.velocity = 0; + } + swiper.velocity *= params.freeModeMomentumVelocityRatio; + + data.velocities.length = 0; + var momentumDuration = 1000 * params.freeModeMomentumRatio; + var momentumDistance = swiper.velocity * momentumDuration; + + var newPosition = swiper.translate + momentumDistance; + if (rtl) { newPosition = -newPosition; } + + var doBounce = false; + var afterBouncePosition; + var bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeModeMomentumBounceRatio; + var needsLoopFix; + if (newPosition < swiper.maxTranslate()) { + if (params.freeModeMomentumBounce) { + if (newPosition + swiper.maxTranslate() < -bounceAmount) { + newPosition = swiper.maxTranslate() - bounceAmount; + } + afterBouncePosition = swiper.maxTranslate(); + doBounce = true; + data.allowMomentumBounce = true; + } else { + newPosition = swiper.maxTranslate(); + } + if (params.loop && params.centeredSlides) { needsLoopFix = true; } + } else if (newPosition > swiper.minTranslate()) { + if (params.freeModeMomentumBounce) { + if (newPosition - swiper.minTranslate() > bounceAmount) { + newPosition = swiper.minTranslate() + bounceAmount; + } + afterBouncePosition = swiper.minTranslate(); + doBounce = true; + data.allowMomentumBounce = true; + } else { + newPosition = swiper.minTranslate(); + } + if (params.loop && params.centeredSlides) { needsLoopFix = true; } + } else if (params.freeModeSticky) { + var nextSlide; + for (var j = 0; j < snapGrid.length; j += 1) { + if (snapGrid[j] > -newPosition) { + nextSlide = j; + break; + } + } + + if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') { + newPosition = snapGrid[nextSlide]; + } else { + newPosition = snapGrid[nextSlide - 1]; + } + newPosition = -newPosition; + } + if (needsLoopFix) { + swiper.once('transitionEnd', function () { + swiper.loopFix(); + }); + } + // Fix duration + if (swiper.velocity !== 0) { + if (rtl) { + momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity); + } else { + momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity); + } + } else if (params.freeModeSticky) { + swiper.slideToClosest(); + return; + } + + if (params.freeModeMomentumBounce && doBounce) { + swiper.updateProgress(afterBouncePosition); + swiper.setTransition(momentumDuration); + swiper.setTranslate(newPosition); + swiper.transitionStart(true, swiper.swipeDirection); + swiper.animating = true; + $wrapperEl.transitionEnd(function () { + if (!swiper || swiper.destroyed || !data.allowMomentumBounce) { return; } + swiper.emit('momentumBounce'); + + swiper.setTransition(params.speed); + swiper.setTranslate(afterBouncePosition); + $wrapperEl.transitionEnd(function () { + if (!swiper || swiper.destroyed) { return; } + swiper.transitionEnd(); + }); + }); + } else if (swiper.velocity) { + swiper.updateProgress(newPosition); + swiper.setTransition(momentumDuration); + swiper.setTranslate(newPosition); + swiper.transitionStart(true, swiper.swipeDirection); + if (!swiper.animating) { + swiper.animating = true; + $wrapperEl.transitionEnd(function () { + if (!swiper || swiper.destroyed) { return; } + swiper.transitionEnd(); + }); + } + } else { + swiper.updateProgress(newPosition); + } + + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } else if (params.freeModeSticky) { + swiper.slideToClosest(); + return; + } + + if (!params.freeModeMomentum || timeDiff >= params.longSwipesMs) { + swiper.updateProgress(); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + return; + } + + // Find current slide + var stopIndex = 0; + var groupSize = swiper.slidesSizesGrid[0]; + for (var i = 0; i < slidesGrid.length; i += params.slidesPerGroup) { + if (typeof slidesGrid[i + params.slidesPerGroup] !== 'undefined') { + if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + params.slidesPerGroup]) { + stopIndex = i; + groupSize = slidesGrid[i + params.slidesPerGroup] - slidesGrid[i]; + } + } else if (currentPos >= slidesGrid[i]) { + stopIndex = i; + groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2]; + } + } + + // Find current slide size + var ratio = (currentPos - slidesGrid[stopIndex]) / groupSize; + + if (timeDiff > params.longSwipesMs) { + // Long touches + if (!params.longSwipes) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (swiper.swipeDirection === 'next') { + if (ratio >= params.longSwipesRatio) { swiper.slideTo(stopIndex + params.slidesPerGroup); } + else { swiper.slideTo(stopIndex); } + } + if (swiper.swipeDirection === 'prev') { + if (ratio > (1 - params.longSwipesRatio)) { swiper.slideTo(stopIndex + params.slidesPerGroup); } + else { swiper.slideTo(stopIndex); } + } + } else { + // Short swipes + if (!params.shortSwipes) { + swiper.slideTo(swiper.activeIndex); + return; + } + if (swiper.swipeDirection === 'next') { + swiper.slideTo(stopIndex + params.slidesPerGroup); + } + if (swiper.swipeDirection === 'prev') { + swiper.slideTo(stopIndex); + } + } + } + + function onResize () { + var swiper = this; + + var params = swiper.params; + var el = swiper.el; + + if (el && el.offsetWidth === 0) { return; } + + // Breakpoints + if (params.breakpoints) { + swiper.setBreakpoint(); + } + + // Save locks + var allowSlideNext = swiper.allowSlideNext; + var allowSlidePrev = swiper.allowSlidePrev; + var snapGrid = swiper.snapGrid; + + // Disable locks on resize + swiper.allowSlideNext = true; + swiper.allowSlidePrev = true; + + swiper.updateSize(); + swiper.updateSlides(); + + if (params.freeMode) { + var newTranslate = Math.min(Math.max(swiper.translate, swiper.maxTranslate()), swiper.minTranslate()); + swiper.setTranslate(newTranslate); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + + if (params.autoHeight) { + swiper.updateAutoHeight(); + } + } else { + swiper.updateSlidesClasses(); + if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) { + swiper.slideTo(swiper.slides.length - 1, 0, false, true); + } else { + swiper.slideTo(swiper.activeIndex, 0, false, true); + } + } + // Return locks after resize + swiper.allowSlidePrev = allowSlidePrev; + swiper.allowSlideNext = allowSlideNext; + + if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) { + swiper.checkOverflow(); + } + } + + function onClick (e) { + var swiper = this; + if (!swiper.allowClick) { + if (swiper.params.preventClicks) { e.preventDefault(); } + if (swiper.params.preventClicksPropagation && swiper.animating) { + e.stopPropagation(); + e.stopImmediatePropagation(); + } + } + } + + function attachEvents() { + var swiper = this; + var params = swiper.params; + var touchEvents = swiper.touchEvents; + var el = swiper.el; + var wrapperEl = swiper.wrapperEl; + + { + swiper.onTouchStart = onTouchStart.bind(swiper); + swiper.onTouchMove = onTouchMove.bind(swiper); + swiper.onTouchEnd = onTouchEnd.bind(swiper); + } + + swiper.onClick = onClick.bind(swiper); + + var target = params.touchEventsTarget === 'container' ? el : wrapperEl; + var capture = !!params.nested; + + // Touch Events + { + if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) { + target.addEventListener(touchEvents.start, swiper.onTouchStart, false); + doc.addEventListener(touchEvents.move, swiper.onTouchMove, capture); + doc.addEventListener(touchEvents.end, swiper.onTouchEnd, false); + } else { + if (Support.touch) { + var passiveListener = touchEvents.start === 'touchstart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + target.addEventListener(touchEvents.start, swiper.onTouchStart, passiveListener); + target.addEventListener(touchEvents.move, swiper.onTouchMove, Support.passiveListener ? { passive: false, capture: capture } : capture); + target.addEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener); + } + if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) { + target.addEventListener('mousedown', swiper.onTouchStart, false); + doc.addEventListener('mousemove', swiper.onTouchMove, capture); + doc.addEventListener('mouseup', swiper.onTouchEnd, false); + } + } + // Prevent Links Clicks + if (params.preventClicks || params.preventClicksPropagation) { + target.addEventListener('click', swiper.onClick, true); + } + } + + // Resize handler + swiper.on((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize, true); + } + + function detachEvents() { + var swiper = this; + + var params = swiper.params; + var touchEvents = swiper.touchEvents; + var el = swiper.el; + var wrapperEl = swiper.wrapperEl; + + var target = params.touchEventsTarget === 'container' ? el : wrapperEl; + var capture = !!params.nested; + + // Touch Events + { + if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) { + target.removeEventListener(touchEvents.start, swiper.onTouchStart, false); + doc.removeEventListener(touchEvents.move, swiper.onTouchMove, capture); + doc.removeEventListener(touchEvents.end, swiper.onTouchEnd, false); + } else { + if (Support.touch) { + var passiveListener = touchEvents.start === 'onTouchStart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + target.removeEventListener(touchEvents.start, swiper.onTouchStart, passiveListener); + target.removeEventListener(touchEvents.move, swiper.onTouchMove, capture); + target.removeEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener); + } + if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) { + target.removeEventListener('mousedown', swiper.onTouchStart, false); + doc.removeEventListener('mousemove', swiper.onTouchMove, capture); + doc.removeEventListener('mouseup', swiper.onTouchEnd, false); + } + } + // Prevent Links Clicks + if (params.preventClicks || params.preventClicksPropagation) { + target.removeEventListener('click', swiper.onClick, true); + } + } + + // Resize handler + swiper.off((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize); + } + + var events = { + attachEvents: attachEvents, + detachEvents: detachEvents, + }; + + function setBreakpoint () { + var swiper = this; + var activeIndex = swiper.activeIndex; + var initialized = swiper.initialized; + var loopedSlides = swiper.loopedSlides; if ( loopedSlides === void 0 ) loopedSlides = 0; + var params = swiper.params; + var breakpoints = params.breakpoints; + if (!breakpoints || (breakpoints && Object.keys(breakpoints).length === 0)) { return; } + + // Set breakpoint for window width and update parameters + var breakpoint = swiper.getBreakpoint(breakpoints); + + if (breakpoint && swiper.currentBreakpoint !== breakpoint) { + var breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined; + if (breakpointOnlyParams) { + ['slidesPerView', 'spaceBetween', 'slidesPerGroup'].forEach(function (param) { + var paramValue = breakpointOnlyParams[param]; + if (typeof paramValue === 'undefined') { return; } + if (param === 'slidesPerView' && (paramValue === 'AUTO' || paramValue === 'auto')) { + breakpointOnlyParams[param] = 'auto'; + } else if (param === 'slidesPerView') { + breakpointOnlyParams[param] = parseFloat(paramValue); + } else { + breakpointOnlyParams[param] = parseInt(paramValue, 10); + } + }); + } + + var breakpointParams = breakpointOnlyParams || swiper.originalParams; + var directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction; + var needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged); + + if (directionChanged && initialized) { + swiper.changeDirection(); + } + + Utils.extend(swiper.params, breakpointParams); + + Utils.extend(swiper, { + allowTouchMove: swiper.params.allowTouchMove, + allowSlideNext: swiper.params.allowSlideNext, + allowSlidePrev: swiper.params.allowSlidePrev, + }); + + swiper.currentBreakpoint = breakpoint; + + if (needsReLoop && initialized) { + swiper.loopDestroy(); + swiper.loopCreate(); + swiper.updateSlides(); + swiper.slideTo((activeIndex - loopedSlides) + swiper.loopedSlides, 0, false); + } + + swiper.emit('breakpoint', breakpointParams); + } + } + + function getBreakpoint (breakpoints) { + var swiper = this; + // Get breakpoint for window width + if (!breakpoints) { return undefined; } + var breakpoint = false; + var points = []; + Object.keys(breakpoints).forEach(function (point) { + points.push(point); + }); + points.sort(function (a, b) { return parseInt(a, 10) - parseInt(b, 10); }); + for (var i = 0; i < points.length; i += 1) { + var point = points[i]; + if (swiper.params.breakpointsInverse) { + if (point <= win.innerWidth) { + breakpoint = point; + } + } else if (point >= win.innerWidth && !breakpoint) { + breakpoint = point; + } + } + return breakpoint || 'max'; + } + + var breakpoints = { setBreakpoint: setBreakpoint, getBreakpoint: getBreakpoint }; + + function addClasses () { + var swiper = this; + var classNames = swiper.classNames; + var params = swiper.params; + var rtl = swiper.rtl; + var $el = swiper.$el; + var suffixes = []; + + suffixes.push('initialized'); + suffixes.push(params.direction); + + if (params.freeMode) { + suffixes.push('free-mode'); + } + if (!Support.flexbox) { + suffixes.push('no-flexbox'); + } + if (params.autoHeight) { + suffixes.push('autoheight'); + } + if (rtl) { + suffixes.push('rtl'); + } + if (params.slidesPerColumn > 1) { + suffixes.push('multirow'); + } + if (Device.android) { + suffixes.push('android'); + } + if (Device.ios) { + suffixes.push('ios'); + } + // WP8 Touch Events Fix + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + suffixes.push(("wp8-" + (params.direction))); + } + + suffixes.forEach(function (suffix) { + classNames.push(params.containerModifierClass + suffix); + }); + + $el.addClass(classNames.join(' ')); + } + + function removeClasses () { + var swiper = this; + var $el = swiper.$el; + var classNames = swiper.classNames; + + $el.removeClass(classNames.join(' ')); + } + + var classes = { addClasses: addClasses, removeClasses: removeClasses }; + + function loadImage (imageEl, src, srcset, sizes, checkForComplete, callback) { + var image; + function onReady() { + if (callback) { callback(); } + } + if (!imageEl.complete || !checkForComplete) { + if (src) { + image = new win.Image(); + image.onload = onReady; + image.onerror = onReady; + if (sizes) { + image.sizes = sizes; + } + if (srcset) { + image.srcset = srcset; + } + if (src) { + image.src = src; + } + } else { + onReady(); + } + } else { + // image already loaded... + onReady(); + } + } + + function preloadImages () { + var swiper = this; + swiper.imagesToLoad = swiper.$el.find('img'); + function onReady() { + if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) { return; } + if (swiper.imagesLoaded !== undefined) { swiper.imagesLoaded += 1; } + if (swiper.imagesLoaded === swiper.imagesToLoad.length) { + if (swiper.params.updateOnImagesReady) { swiper.update(); } + swiper.emit('imagesReady'); + } + } + for (var i = 0; i < swiper.imagesToLoad.length; i += 1) { + var imageEl = swiper.imagesToLoad[i]; + swiper.loadImage( + imageEl, + imageEl.currentSrc || imageEl.getAttribute('src'), + imageEl.srcset || imageEl.getAttribute('srcset'), + imageEl.sizes || imageEl.getAttribute('sizes'), + true, + onReady + ); + } + } + + var images = { + loadImage: loadImage, + preloadImages: preloadImages, + }; + + function checkOverflow() { + var swiper = this; + var wasLocked = swiper.isLocked; + + swiper.isLocked = swiper.snapGrid.length === 1; + swiper.allowSlideNext = !swiper.isLocked; + swiper.allowSlidePrev = !swiper.isLocked; + + // events + if (wasLocked !== swiper.isLocked) { swiper.emit(swiper.isLocked ? 'lock' : 'unlock'); } + + if (wasLocked && wasLocked !== swiper.isLocked) { + swiper.isEnd = false; + swiper.navigation.update(); + } + } + + var checkOverflow$1 = { checkOverflow: checkOverflow }; + + var defaults = { + init: true, + direction: 'horizontal', + touchEventsTarget: 'container', + initialSlide: 0, + speed: 300, + // + preventInteractionOnTransition: false, + + // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView). + edgeSwipeDetection: false, + edgeSwipeThreshold: 20, + + // Free mode + freeMode: false, + freeModeMomentum: true, + freeModeMomentumRatio: 1, + freeModeMomentumBounce: true, + freeModeMomentumBounceRatio: 1, + freeModeMomentumVelocityRatio: 1, + freeModeSticky: false, + freeModeMinimumVelocity: 0.02, + + // Autoheight + autoHeight: false, + + // Set wrapper width + setWrapperSize: false, + + // Virtual Translate + virtualTranslate: false, + + // Effects + effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip' + + // Breakpoints + breakpoints: undefined, + breakpointsInverse: false, + + // Slides grid + spaceBetween: 0, + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerColumnFill: 'column', + slidesPerGroup: 1, + centeredSlides: false, + slidesOffsetBefore: 0, // in px + slidesOffsetAfter: 0, // in px + normalizeSlideIndex: true, + centerInsufficientSlides: false, + + // Disable swiper and hide navigation when container not overflow + watchOverflow: false, + + // Round length + roundLengths: false, + + // Touches + touchRatio: 1, + touchAngle: 45, + simulateTouch: true, + shortSwipes: true, + longSwipes: true, + longSwipesRatio: 0.5, + longSwipesMs: 300, + followFinger: true, + allowTouchMove: true, + threshold: 0, + touchMoveStopPropagation: true, + touchStartPreventDefault: true, + touchStartForcePreventDefault: false, + touchReleaseOnEdges: false, + + // Unique Navigation Elements + uniqueNavElements: true, + + // Resistance + resistance: true, + resistanceRatio: 0.85, + + // Progress + watchSlidesProgress: false, + watchSlidesVisibility: false, + + // Cursor + grabCursor: false, + + // Clicks + preventClicks: true, + preventClicksPropagation: true, + slideToClickedSlide: false, + + // Images + preloadImages: true, + updateOnImagesReady: true, + + // loop + loop: false, + loopAdditionalSlides: 0, + loopedSlides: null, + loopFillGroupWithBlank: false, + + // Swiping/no swiping + allowSlidePrev: true, + allowSlideNext: true, + swipeHandler: null, // '.swipe-handler', + noSwiping: true, + noSwipingClass: 'swiper-no-swiping', + noSwipingSelector: null, + + // Passive Listeners + passiveListeners: true, + + // NS + containerModifierClass: 'swiper-container-', // NEW + slideClass: 'swiper-slide', + slideBlankClass: 'swiper-slide-invisible-blank', + slideActiveClass: 'swiper-slide-active', + slideDuplicateActiveClass: 'swiper-slide-duplicate-active', + slideVisibleClass: 'swiper-slide-visible', + slideDuplicateClass: 'swiper-slide-duplicate', + slideNextClass: 'swiper-slide-next', + slideDuplicateNextClass: 'swiper-slide-duplicate-next', + slidePrevClass: 'swiper-slide-prev', + slideDuplicatePrevClass: 'swiper-slide-duplicate-prev', + wrapperClass: 'swiper-wrapper', + + // Callbacks + runCallbacksOnInit: true, + }; + + /* eslint no-param-reassign: "off" */ + + var prototypes = { + update: update, + translate: translate, + transition: transition$1, + slide: slide, + loop: loop, + grabCursor: grabCursor, + manipulation: manipulation, + events: events, + breakpoints: breakpoints, + checkOverflow: checkOverflow$1, + classes: classes, + images: images, + }; + + var extendedDefaults = {}; + + var Swiper = /*@__PURE__*/(function (SwiperClass) { + function Swiper() { + var assign; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + var el; + var params; + if (args.length === 1 && args[0].constructor && args[0].constructor === Object) { + params = args[0]; + } else { + (assign = args, el = assign[0], params = assign[1]); + } + if (!params) { params = {}; } + + params = Utils.extend({}, params); + if (el && !params.el) { params.el = el; } + + SwiperClass.call(this, params); + + Object.keys(prototypes).forEach(function (prototypeGroup) { + Object.keys(prototypes[prototypeGroup]).forEach(function (protoMethod) { + if (!Swiper.prototype[protoMethod]) { + Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod]; + } + }); + }); + + // Swiper Instance + var swiper = this; + if (typeof swiper.modules === 'undefined') { + swiper.modules = {}; + } + Object.keys(swiper.modules).forEach(function (moduleName) { + var module = swiper.modules[moduleName]; + if (module.params) { + var moduleParamName = Object.keys(module.params)[0]; + var moduleParams = module.params[moduleParamName]; + if (typeof moduleParams !== 'object' || moduleParams === null) { return; } + if (!(moduleParamName in params && 'enabled' in moduleParams)) { return; } + if (params[moduleParamName] === true) { + params[moduleParamName] = { enabled: true }; + } + if ( + typeof params[moduleParamName] === 'object' + && !('enabled' in params[moduleParamName]) + ) { + params[moduleParamName].enabled = true; + } + if (!params[moduleParamName]) { params[moduleParamName] = { enabled: false }; } + } + }); + + // Extend defaults with modules params + var swiperParams = Utils.extend({}, defaults); + swiper.useModulesParams(swiperParams); + + // Extend defaults with passed params + swiper.params = Utils.extend({}, swiperParams, extendedDefaults, params); + swiper.originalParams = Utils.extend({}, swiper.params); + swiper.passedParams = Utils.extend({}, params); + + // Save Dom lib + swiper.$ = $; + + // Find el + var $el = $(swiper.params.el); + el = $el[0]; + + if (!el) { + return undefined; + } + + if ($el.length > 1) { + var swipers = []; + $el.each(function (index, containerEl) { + var newParams = Utils.extend({}, params, { el: containerEl }); + swipers.push(new Swiper(newParams)); + }); + return swipers; + } + + el.swiper = swiper; + $el.data('swiper', swiper); + + // Find Wrapper + var $wrapperEl = $el.children(("." + (swiper.params.wrapperClass))); + + // Extend Swiper + Utils.extend(swiper, { + $el: $el, + el: el, + $wrapperEl: $wrapperEl, + wrapperEl: $wrapperEl[0], + + // Classes + classNames: [], + + // Slides + slides: $(), + slidesGrid: [], + snapGrid: [], + slidesSizesGrid: [], + + // isDirection + isHorizontal: function isHorizontal() { + return swiper.params.direction === 'horizontal'; + }, + isVertical: function isVertical() { + return swiper.params.direction === 'vertical'; + }, + // RTL + rtl: (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'), + rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'), + wrongRTL: $wrapperEl.css('display') === '-webkit-box', + + // Indexes + activeIndex: 0, + realIndex: 0, + + // + isBeginning: true, + isEnd: false, + + // Props + translate: 0, + previousTranslate: 0, + progress: 0, + velocity: 0, + animating: false, + + // Locks + allowSlideNext: swiper.params.allowSlideNext, + allowSlidePrev: swiper.params.allowSlidePrev, + + // Touch Events + touchEvents: (function touchEvents() { + var touch = ['touchstart', 'touchmove', 'touchend']; + var desktop = ['mousedown', 'mousemove', 'mouseup']; + if (Support.pointerEvents) { + desktop = ['pointerdown', 'pointermove', 'pointerup']; + } else if (Support.prefixedPointerEvents) { + desktop = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp']; + } + swiper.touchEventsTouch = { + start: touch[0], + move: touch[1], + end: touch[2], + }; + swiper.touchEventsDesktop = { + start: desktop[0], + move: desktop[1], + end: desktop[2], + }; + return Support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop; + }()), + touchEventsData: { + isTouched: undefined, + isMoved: undefined, + allowTouchCallbacks: undefined, + touchStartTime: undefined, + isScrolling: undefined, + currentTranslate: undefined, + startTranslate: undefined, + allowThresholdMove: undefined, + // Form elements to match + formElements: 'input, select, option, textarea, button, video', + // Last click time + lastClickTime: Utils.now(), + clickTimeout: undefined, + // Velocities + velocities: [], + allowMomentumBounce: undefined, + isTouchEvent: undefined, + startMoving: undefined, + }, + + // Clicks + allowClick: true, + + // Touches + allowTouchMove: swiper.params.allowTouchMove, + + touches: { + startX: 0, + startY: 0, + currentX: 0, + currentY: 0, + diff: 0, + }, + + // Images + imagesToLoad: [], + imagesLoaded: 0, + + }); + + // Install Modules + swiper.useModules(); + + // Init + if (swiper.params.init) { + swiper.init(); + } + + // Return app instance + return swiper; + } + + if ( SwiperClass ) Swiper.__proto__ = SwiperClass; + Swiper.prototype = Object.create( SwiperClass && SwiperClass.prototype ); + Swiper.prototype.constructor = Swiper; + + var staticAccessors = { extendedDefaults: { configurable: true },defaults: { configurable: true },Class: { configurable: true },$: { configurable: true } }; + + Swiper.prototype.slidesPerViewDynamic = function slidesPerViewDynamic () { + var swiper = this; + var params = swiper.params; + var slides = swiper.slides; + var slidesGrid = swiper.slidesGrid; + var swiperSize = swiper.size; + var activeIndex = swiper.activeIndex; + var spv = 1; + if (params.centeredSlides) { + var slideSize = slides[activeIndex].swiperSlideSize; + var breakLoop; + for (var i = activeIndex + 1; i < slides.length; i += 1) { + if (slides[i] && !breakLoop) { + slideSize += slides[i].swiperSlideSize; + spv += 1; + if (slideSize > swiperSize) { breakLoop = true; } + } + } + for (var i$1 = activeIndex - 1; i$1 >= 0; i$1 -= 1) { + if (slides[i$1] && !breakLoop) { + slideSize += slides[i$1].swiperSlideSize; + spv += 1; + if (slideSize > swiperSize) { breakLoop = true; } + } + } + } else { + for (var i$2 = activeIndex + 1; i$2 < slides.length; i$2 += 1) { + if (slidesGrid[i$2] - slidesGrid[activeIndex] < swiperSize) { + spv += 1; + } + } + } + return spv; + }; + + Swiper.prototype.update = function update () { + var swiper = this; + if (!swiper || swiper.destroyed) { return; } + var snapGrid = swiper.snapGrid; + var params = swiper.params; + // Breakpoints + if (params.breakpoints) { + swiper.setBreakpoint(); + } + swiper.updateSize(); + swiper.updateSlides(); + swiper.updateProgress(); + swiper.updateSlidesClasses(); + + function setTranslate() { + var translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate; + var newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate()); + swiper.setTranslate(newTranslate); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + } + var translated; + if (swiper.params.freeMode) { + setTranslate(); + if (swiper.params.autoHeight) { + swiper.updateAutoHeight(); + } + } else { + if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) { + translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true); + } else { + translated = swiper.slideTo(swiper.activeIndex, 0, false, true); + } + if (!translated) { + setTranslate(); + } + } + if (params.watchOverflow && snapGrid !== swiper.snapGrid) { + swiper.checkOverflow(); + } + swiper.emit('update'); + }; + + Swiper.prototype.changeDirection = function changeDirection (newDirection, needUpdate) { + if ( needUpdate === void 0 ) needUpdate = true; + + var swiper = this; + var currentDirection = swiper.params.direction; + if (!newDirection) { + // eslint-disable-next-line + newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal'; + } + if ((newDirection === currentDirection) || (newDirection !== 'horizontal' && newDirection !== 'vertical')) { + return swiper; + } + + if (currentDirection === 'vertical') { + swiper.$el + .removeClass(((swiper.params.containerModifierClass) + "vertical wp8-vertical")) + .addClass(("" + (swiper.params.containerModifierClass) + newDirection)); + + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + swiper.$el.addClass(((swiper.params.containerModifierClass) + "wp8-" + newDirection)); + } + } + if (currentDirection === 'horizontal') { + swiper.$el + .removeClass(((swiper.params.containerModifierClass) + "horizontal wp8-horizontal")) + .addClass(("" + (swiper.params.containerModifierClass) + newDirection)); + + if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) { + swiper.$el.addClass(((swiper.params.containerModifierClass) + "wp8-" + newDirection)); + } + } + + swiper.params.direction = newDirection; + + swiper.slides.each(function (slideIndex, slideEl) { + if (newDirection === 'vertical') { + slideEl.style.width = ''; + } else { + slideEl.style.height = ''; + } + }); + + swiper.emit('changeDirection'); + if (needUpdate) { swiper.update(); } + + return swiper; + }; + + Swiper.prototype.init = function init () { + var swiper = this; + if (swiper.initialized) { return; } + + swiper.emit('beforeInit'); + + // Set breakpoint + if (swiper.params.breakpoints) { + swiper.setBreakpoint(); + } + + // Add Classes + swiper.addClasses(); + + // Create loop + if (swiper.params.loop) { + swiper.loopCreate(); + } + + // Update size + swiper.updateSize(); + + // Update slides + swiper.updateSlides(); + + if (swiper.params.watchOverflow) { + swiper.checkOverflow(); + } + + // Set Grab Cursor + if (swiper.params.grabCursor) { + swiper.setGrabCursor(); + } + + if (swiper.params.preloadImages) { + swiper.preloadImages(); + } + + // Slide To Initial Slide + if (swiper.params.loop) { + swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit); + } else { + swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit); + } + + // Attach events + swiper.attachEvents(); + + // Init Flag + swiper.initialized = true; + + // Emit + swiper.emit('init'); + }; + + Swiper.prototype.destroy = function destroy (deleteInstance, cleanStyles) { + if ( deleteInstance === void 0 ) deleteInstance = true; + if ( cleanStyles === void 0 ) cleanStyles = true; + + var swiper = this; + var params = swiper.params; + var $el = swiper.$el; + var $wrapperEl = swiper.$wrapperEl; + var slides = swiper.slides; + + if (typeof swiper.params === 'undefined' || swiper.destroyed) { + return null; + } + + swiper.emit('beforeDestroy'); + + // Init Flag + swiper.initialized = false; + + // Detach events + swiper.detachEvents(); + + // Destroy loop + if (params.loop) { + swiper.loopDestroy(); + } + + // Cleanup styles + if (cleanStyles) { + swiper.removeClasses(); + $el.removeAttr('style'); + $wrapperEl.removeAttr('style'); + if (slides && slides.length) { + slides + .removeClass([ + params.slideVisibleClass, + params.slideActiveClass, + params.slideNextClass, + params.slidePrevClass ].join(' ')) + .removeAttr('style') + .removeAttr('data-swiper-slide-index') + .removeAttr('data-swiper-column') + .removeAttr('data-swiper-row'); + } + } + + swiper.emit('destroy'); + + // Detach emitter events + Object.keys(swiper.eventsListeners).forEach(function (eventName) { + swiper.off(eventName); + }); + + if (deleteInstance !== false) { + swiper.$el[0].swiper = null; + swiper.$el.data('swiper', null); + Utils.deleteProps(swiper); + } + swiper.destroyed = true; + + return null; + }; + + Swiper.extendDefaults = function extendDefaults (newDefaults) { + Utils.extend(extendedDefaults, newDefaults); + }; + + staticAccessors.extendedDefaults.get = function () { + return extendedDefaults; + }; + + staticAccessors.defaults.get = function () { + return defaults; + }; + + staticAccessors.Class.get = function () { + return SwiperClass; + }; + + staticAccessors.$.get = function () { + return $; + }; + + Object.defineProperties( Swiper, staticAccessors ); + + return Swiper; + }(SwiperClass)); + + var Device$1 = { + name: 'device', + proto: { + device: Device, + }, + static: { + device: Device, + }, + }; + + var Support$1 = { + name: 'support', + proto: { + support: Support, + }, + static: { + support: Support, + }, + }; + + var Browser$1 = { + name: 'browser', + proto: { + browser: Browser, + }, + static: { + browser: Browser, + }, + }; + + var Resize = { + name: 'resize', + create: function create() { + var swiper = this; + Utils.extend(swiper, { + resize: { + resizeHandler: function resizeHandler() { + if (!swiper || swiper.destroyed || !swiper.initialized) { return; } + swiper.emit('beforeResize'); + swiper.emit('resize'); + }, + orientationChangeHandler: function orientationChangeHandler() { + if (!swiper || swiper.destroyed || !swiper.initialized) { return; } + swiper.emit('orientationchange'); + }, + }, + }); + }, + on: { + init: function init() { + var swiper = this; + // Emit resize + win.addEventListener('resize', swiper.resize.resizeHandler); + + // Emit orientationchange + win.addEventListener('orientationchange', swiper.resize.orientationChangeHandler); + }, + destroy: function destroy() { + var swiper = this; + win.removeEventListener('resize', swiper.resize.resizeHandler); + win.removeEventListener('orientationchange', swiper.resize.orientationChangeHandler); + }, + }, + }; + + var Observer = { + func: win.MutationObserver || win.WebkitMutationObserver, + attach: function attach(target, options) { + if ( options === void 0 ) options = {}; + + var swiper = this; + + var ObserverFunc = Observer.func; + var observer = new ObserverFunc(function (mutations) { + // The observerUpdate event should only be triggered + // once despite the number of mutations. Additional + // triggers are redundant and are very costly + if (mutations.length === 1) { + swiper.emit('observerUpdate', mutations[0]); + return; + } + var observerUpdate = function observerUpdate() { + swiper.emit('observerUpdate', mutations[0]); + }; + + if (win.requestAnimationFrame) { + win.requestAnimationFrame(observerUpdate); + } else { + win.setTimeout(observerUpdate, 0); + } + }); + + observer.observe(target, { + attributes: typeof options.attributes === 'undefined' ? true : options.attributes, + childList: typeof options.childList === 'undefined' ? true : options.childList, + characterData: typeof options.characterData === 'undefined' ? true : options.characterData, + }); + + swiper.observer.observers.push(observer); + }, + init: function init() { + var swiper = this; + if (!Support.observer || !swiper.params.observer) { return; } + if (swiper.params.observeParents) { + var containerParents = swiper.$el.parents(); + for (var i = 0; i < containerParents.length; i += 1) { + swiper.observer.attach(containerParents[i]); + } + } + // Observe container + swiper.observer.attach(swiper.$el[0], { childList: swiper.params.observeSlideChildren }); + + // Observe wrapper + swiper.observer.attach(swiper.$wrapperEl[0], { attributes: false }); + }, + destroy: function destroy() { + var swiper = this; + swiper.observer.observers.forEach(function (observer) { + observer.disconnect(); + }); + swiper.observer.observers = []; + }, + }; + + var Observer$1 = { + name: 'observer', + params: { + observer: false, + observeParents: false, + observeSlideChildren: false, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + observer: { + init: Observer.init.bind(swiper), + attach: Observer.attach.bind(swiper), + destroy: Observer.destroy.bind(swiper), + observers: [], + }, + }); + }, + on: { + init: function init() { + var swiper = this; + swiper.observer.init(); + }, + destroy: function destroy() { + var swiper = this; + swiper.observer.destroy(); + }, + }, + }; + + var Virtual = { + update: function update(force) { + var swiper = this; + var ref = swiper.params; + var slidesPerView = ref.slidesPerView; + var slidesPerGroup = ref.slidesPerGroup; + var centeredSlides = ref.centeredSlides; + var ref$1 = swiper.params.virtual; + var addSlidesBefore = ref$1.addSlidesBefore; + var addSlidesAfter = ref$1.addSlidesAfter; + var ref$2 = swiper.virtual; + var previousFrom = ref$2.from; + var previousTo = ref$2.to; + var slides = ref$2.slides; + var previousSlidesGrid = ref$2.slidesGrid; + var renderSlide = ref$2.renderSlide; + var previousOffset = ref$2.offset; + swiper.updateActiveIndex(); + var activeIndex = swiper.activeIndex || 0; + + var offsetProp; + if (swiper.rtlTranslate) { offsetProp = 'right'; } + else { offsetProp = swiper.isHorizontal() ? 'left' : 'top'; } + + var slidesAfter; + var slidesBefore; + if (centeredSlides) { + slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore; + slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter; + } else { + slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesBefore; + slidesBefore = slidesPerGroup + addSlidesAfter; + } + var from = Math.max((activeIndex || 0) - slidesBefore, 0); + var to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1); + var offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0); + + Utils.extend(swiper.virtual, { + from: from, + to: to, + offset: offset, + slidesGrid: swiper.slidesGrid, + }); + + function onRendered() { + swiper.updateSlides(); + swiper.updateProgress(); + swiper.updateSlidesClasses(); + if (swiper.lazy && swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + } + + if (previousFrom === from && previousTo === to && !force) { + if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) { + swiper.slides.css(offsetProp, (offset + "px")); + } + swiper.updateProgress(); + return; + } + if (swiper.params.virtual.renderExternal) { + swiper.params.virtual.renderExternal.call(swiper, { + offset: offset, + from: from, + to: to, + slides: (function getSlides() { + var slidesToRender = []; + for (var i = from; i <= to; i += 1) { + slidesToRender.push(slides[i]); + } + return slidesToRender; + }()), + }); + onRendered(); + return; + } + var prependIndexes = []; + var appendIndexes = []; + if (force) { + swiper.$wrapperEl.find(("." + (swiper.params.slideClass))).remove(); + } else { + for (var i = previousFrom; i <= previousTo; i += 1) { + if (i < from || i > to) { + swiper.$wrapperEl.find(("." + (swiper.params.slideClass) + "[data-swiper-slide-index=\"" + i + "\"]")).remove(); + } + } + } + for (var i$1 = 0; i$1 < slides.length; i$1 += 1) { + if (i$1 >= from && i$1 <= to) { + if (typeof previousTo === 'undefined' || force) { + appendIndexes.push(i$1); + } else { + if (i$1 > previousTo) { appendIndexes.push(i$1); } + if (i$1 < previousFrom) { prependIndexes.push(i$1); } + } + } + } + appendIndexes.forEach(function (index) { + swiper.$wrapperEl.append(renderSlide(slides[index], index)); + }); + prependIndexes.sort(function (a, b) { return b - a; }).forEach(function (index) { + swiper.$wrapperEl.prepend(renderSlide(slides[index], index)); + }); + swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, (offset + "px")); + onRendered(); + }, + renderSlide: function renderSlide(slide, index) { + var swiper = this; + var params = swiper.params.virtual; + if (params.cache && swiper.virtual.cache[index]) { + return swiper.virtual.cache[index]; + } + var $slideEl = params.renderSlide + ? $(params.renderSlide.call(swiper, slide, index)) + : $(("
            " + slide + "
            ")); + if (!$slideEl.attr('data-swiper-slide-index')) { $slideEl.attr('data-swiper-slide-index', index); } + if (params.cache) { swiper.virtual.cache[index] = $slideEl; } + return $slideEl; + }, + appendSlide: function appendSlide(slides) { + var swiper = this; + if (typeof slides === 'object' && 'length' in slides) { + for (var i = 0; i < slides.length; i += 1) { + if (slides[i]) { swiper.virtual.slides.push(slides[i]); } + } + } else { + swiper.virtual.slides.push(slides); + } + swiper.virtual.update(true); + }, + prependSlide: function prependSlide(slides) { + var swiper = this; + var activeIndex = swiper.activeIndex; + var newActiveIndex = activeIndex + 1; + var numberOfNewSlides = 1; + + if (Array.isArray(slides)) { + for (var i = 0; i < slides.length; i += 1) { + if (slides[i]) { swiper.virtual.slides.unshift(slides[i]); } + } + newActiveIndex = activeIndex + slides.length; + numberOfNewSlides = slides.length; + } else { + swiper.virtual.slides.unshift(slides); + } + if (swiper.params.virtual.cache) { + var cache = swiper.virtual.cache; + var newCache = {}; + Object.keys(cache).forEach(function (cachedIndex) { + newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cache[cachedIndex]; + }); + swiper.virtual.cache = newCache; + } + swiper.virtual.update(true); + swiper.slideTo(newActiveIndex, 0); + }, + removeSlide: function removeSlide(slidesIndexes) { + var swiper = this; + if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) { return; } + var activeIndex = swiper.activeIndex; + if (Array.isArray(slidesIndexes)) { + for (var i = slidesIndexes.length - 1; i >= 0; i -= 1) { + swiper.virtual.slides.splice(slidesIndexes[i], 1); + if (swiper.params.virtual.cache) { + delete swiper.virtual.cache[slidesIndexes[i]]; + } + if (slidesIndexes[i] < activeIndex) { activeIndex -= 1; } + activeIndex = Math.max(activeIndex, 0); + } + } else { + swiper.virtual.slides.splice(slidesIndexes, 1); + if (swiper.params.virtual.cache) { + delete swiper.virtual.cache[slidesIndexes]; + } + if (slidesIndexes < activeIndex) { activeIndex -= 1; } + activeIndex = Math.max(activeIndex, 0); + } + swiper.virtual.update(true); + swiper.slideTo(activeIndex, 0); + }, + removeAllSlides: function removeAllSlides() { + var swiper = this; + swiper.virtual.slides = []; + if (swiper.params.virtual.cache) { + swiper.virtual.cache = {}; + } + swiper.virtual.update(true); + swiper.slideTo(0, 0); + }, + }; + + var Virtual$1 = { + name: 'virtual', + params: { + virtual: { + enabled: false, + slides: [], + cache: true, + renderSlide: null, + renderExternal: null, + addSlidesBefore: 0, + addSlidesAfter: 0, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + virtual: { + update: Virtual.update.bind(swiper), + appendSlide: Virtual.appendSlide.bind(swiper), + prependSlide: Virtual.prependSlide.bind(swiper), + removeSlide: Virtual.removeSlide.bind(swiper), + removeAllSlides: Virtual.removeAllSlides.bind(swiper), + renderSlide: Virtual.renderSlide.bind(swiper), + slides: swiper.params.virtual.slides, + cache: {}, + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + if (!swiper.params.virtual.enabled) { return; } + swiper.classNames.push(((swiper.params.containerModifierClass) + "virtual")); + var overwriteParams = { + watchSlidesProgress: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + + if (!swiper.params.initialSlide) { + swiper.virtual.update(); + } + }, + setTranslate: function setTranslate() { + var swiper = this; + if (!swiper.params.virtual.enabled) { return; } + swiper.virtual.update(); + }, + }, + }; + + var Keyboard = { + handle: function handle(event) { + var swiper = this; + var rtl = swiper.rtlTranslate; + var e = event; + if (e.originalEvent) { e = e.originalEvent; } // jquery fix + var kc = e.keyCode || e.charCode; + // Directions locks + if (!swiper.allowSlideNext && ((swiper.isHorizontal() && kc === 39) || (swiper.isVertical() && kc === 40))) { + return false; + } + if (!swiper.allowSlidePrev && ((swiper.isHorizontal() && kc === 37) || (swiper.isVertical() && kc === 38))) { + return false; + } + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { + return undefined; + } + if (doc.activeElement && doc.activeElement.nodeName && (doc.activeElement.nodeName.toLowerCase() === 'input' || doc.activeElement.nodeName.toLowerCase() === 'textarea')) { + return undefined; + } + if (swiper.params.keyboard.onlyInViewport && (kc === 37 || kc === 39 || kc === 38 || kc === 40)) { + var inView = false; + // Check that swiper should be inside of visible area of window + if (swiper.$el.parents(("." + (swiper.params.slideClass))).length > 0 && swiper.$el.parents(("." + (swiper.params.slideActiveClass))).length === 0) { + return undefined; + } + var windowWidth = win.innerWidth; + var windowHeight = win.innerHeight; + var swiperOffset = swiper.$el.offset(); + if (rtl) { swiperOffset.left -= swiper.$el[0].scrollLeft; } + var swiperCoord = [ + [swiperOffset.left, swiperOffset.top], + [swiperOffset.left + swiper.width, swiperOffset.top], + [swiperOffset.left, swiperOffset.top + swiper.height], + [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height] ]; + for (var i = 0; i < swiperCoord.length; i += 1) { + var point = swiperCoord[i]; + if ( + point[0] >= 0 && point[0] <= windowWidth + && point[1] >= 0 && point[1] <= windowHeight + ) { + inView = true; + } + } + if (!inView) { return undefined; } + } + if (swiper.isHorizontal()) { + if (kc === 37 || kc === 39) { + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } + } + if ((kc === 39 && !rtl) || (kc === 37 && rtl)) { swiper.slideNext(); } + if ((kc === 37 && !rtl) || (kc === 39 && rtl)) { swiper.slidePrev(); } + } else { + if (kc === 38 || kc === 40) { + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } + } + if (kc === 40) { swiper.slideNext(); } + if (kc === 38) { swiper.slidePrev(); } + } + swiper.emit('keyPress', kc); + return undefined; + }, + enable: function enable() { + var swiper = this; + if (swiper.keyboard.enabled) { return; } + $(doc).on('keydown', swiper.keyboard.handle); + swiper.keyboard.enabled = true; + }, + disable: function disable() { + var swiper = this; + if (!swiper.keyboard.enabled) { return; } + $(doc).off('keydown', swiper.keyboard.handle); + swiper.keyboard.enabled = false; + }, + }; + + var Keyboard$1 = { + name: 'keyboard', + params: { + keyboard: { + enabled: false, + onlyInViewport: true, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + keyboard: { + enabled: false, + enable: Keyboard.enable.bind(swiper), + disable: Keyboard.disable.bind(swiper), + handle: Keyboard.handle.bind(swiper), + }, + }); + }, + on: { + init: function init() { + var swiper = this; + if (swiper.params.keyboard.enabled) { + swiper.keyboard.enable(); + } + }, + destroy: function destroy() { + var swiper = this; + if (swiper.keyboard.enabled) { + swiper.keyboard.disable(); + } + }, + }, + }; + + function isEventSupported() { + var eventName = 'onwheel'; + var isSupported = eventName in doc; + + if (!isSupported) { + var element = doc.createElement('div'); + element.setAttribute(eventName, 'return;'); + isSupported = typeof element[eventName] === 'function'; + } + + if (!isSupported + && doc.implementation + && doc.implementation.hasFeature + // always returns true in newer browsers as per the standard. + // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature + && doc.implementation.hasFeature('', '') !== true + ) { + // This is the only way to test support for the `wheel` event in IE9+. + isSupported = doc.implementation.hasFeature('Events.wheel', '3.0'); + } + + return isSupported; + } + var Mousewheel = { + lastScrollTime: Utils.now(), + event: (function getEvent() { + if (win.navigator.userAgent.indexOf('firefox') > -1) { return 'DOMMouseScroll'; } + return isEventSupported() ? 'wheel' : 'mousewheel'; + }()), + normalize: function normalize(e) { + // Reasonable defaults + var PIXEL_STEP = 10; + var LINE_HEIGHT = 40; + var PAGE_HEIGHT = 800; + + var sX = 0; + var sY = 0; // spinX, spinY + var pX = 0; + var pY = 0; // pixelX, pixelY + + // Legacy + if ('detail' in e) { + sY = e.detail; + } + if ('wheelDelta' in e) { + sY = -e.wheelDelta / 120; + } + if ('wheelDeltaY' in e) { + sY = -e.wheelDeltaY / 120; + } + if ('wheelDeltaX' in e) { + sX = -e.wheelDeltaX / 120; + } + + // side scrolling on FF with DOMMouseScroll + if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) { + sX = sY; + sY = 0; + } + + pX = sX * PIXEL_STEP; + pY = sY * PIXEL_STEP; + + if ('deltaY' in e) { + pY = e.deltaY; + } + if ('deltaX' in e) { + pX = e.deltaX; + } + + if ((pX || pY) && e.deltaMode) { + if (e.deltaMode === 1) { // delta in LINE units + pX *= LINE_HEIGHT; + pY *= LINE_HEIGHT; + } else { // delta in PAGE units + pX *= PAGE_HEIGHT; + pY *= PAGE_HEIGHT; + } + } + + // Fall-back if spin cannot be determined + if (pX && !sX) { + sX = (pX < 1) ? -1 : 1; + } + if (pY && !sY) { + sY = (pY < 1) ? -1 : 1; + } + + return { + spinX: sX, + spinY: sY, + pixelX: pX, + pixelY: pY, + }; + }, + handleMouseEnter: function handleMouseEnter() { + var swiper = this; + swiper.mouseEntered = true; + }, + handleMouseLeave: function handleMouseLeave() { + var swiper = this; + swiper.mouseEntered = false; + }, + handle: function handle(event) { + var e = event; + var swiper = this; + var params = swiper.params.mousewheel; + + if (!swiper.mouseEntered && !params.releaseOnEdges) { return true; } + + if (e.originalEvent) { e = e.originalEvent; } // jquery fix + var delta = 0; + var rtlFactor = swiper.rtlTranslate ? -1 : 1; + + var data = Mousewheel.normalize(e); + + if (params.forceToAxis) { + if (swiper.isHorizontal()) { + if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) { delta = data.pixelX * rtlFactor; } + else { return true; } + } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) { delta = data.pixelY; } + else { return true; } + } else { + delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY; + } + + if (delta === 0) { return true; } + + if (params.invert) { delta = -delta; } + + if (!swiper.params.freeMode) { + if (Utils.now() - swiper.mousewheel.lastScrollTime > 60) { + if (delta < 0) { + if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) { + swiper.slideNext(); + swiper.emit('scroll', e); + } else if (params.releaseOnEdges) { return true; } + } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) { + swiper.slidePrev(); + swiper.emit('scroll', e); + } else if (params.releaseOnEdges) { return true; } + } + swiper.mousewheel.lastScrollTime = (new win.Date()).getTime(); + } else { + // Freemode or scrollContainer: + if (swiper.params.loop) { + swiper.loopFix(); + } + var position = swiper.getTranslate() + (delta * params.sensitivity); + var wasBeginning = swiper.isBeginning; + var wasEnd = swiper.isEnd; + + if (position >= swiper.minTranslate()) { position = swiper.minTranslate(); } + if (position <= swiper.maxTranslate()) { position = swiper.maxTranslate(); } + + swiper.setTransition(0); + swiper.setTranslate(position); + swiper.updateProgress(); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + + if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) { + swiper.updateSlidesClasses(); + } + + if (swiper.params.freeModeSticky) { + clearTimeout(swiper.mousewheel.timeout); + swiper.mousewheel.timeout = Utils.nextTick(function () { + swiper.slideToClosest(); + }, 300); + } + // Emit event + swiper.emit('scroll', e); + + // Stop autoplay + if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) { swiper.autoplay.stop(); } + // Return page scroll on edge positions + if (position === swiper.minTranslate() || position === swiper.maxTranslate()) { return true; } + } + + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } + return false; + }, + enable: function enable() { + var swiper = this; + if (!Mousewheel.event) { return false; } + if (swiper.mousewheel.enabled) { return false; } + var target = swiper.$el; + if (swiper.params.mousewheel.eventsTarged !== 'container') { + target = $(swiper.params.mousewheel.eventsTarged); + } + target.on('mouseenter', swiper.mousewheel.handleMouseEnter); + target.on('mouseleave', swiper.mousewheel.handleMouseLeave); + target.on(Mousewheel.event, swiper.mousewheel.handle); + swiper.mousewheel.enabled = true; + return true; + }, + disable: function disable() { + var swiper = this; + if (!Mousewheel.event) { return false; } + if (!swiper.mousewheel.enabled) { return false; } + var target = swiper.$el; + if (swiper.params.mousewheel.eventsTarged !== 'container') { + target = $(swiper.params.mousewheel.eventsTarged); + } + target.off(Mousewheel.event, swiper.mousewheel.handle); + swiper.mousewheel.enabled = false; + return true; + }, + }; + + var Mousewheel$1 = { + name: 'mousewheel', + params: { + mousewheel: { + enabled: false, + releaseOnEdges: false, + invert: false, + forceToAxis: false, + sensitivity: 1, + eventsTarged: 'container', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + mousewheel: { + enabled: false, + enable: Mousewheel.enable.bind(swiper), + disable: Mousewheel.disable.bind(swiper), + handle: Mousewheel.handle.bind(swiper), + handleMouseEnter: Mousewheel.handleMouseEnter.bind(swiper), + handleMouseLeave: Mousewheel.handleMouseLeave.bind(swiper), + lastScrollTime: Utils.now(), + }, + }); + }, + on: { + init: function init() { + var swiper = this; + if (swiper.params.mousewheel.enabled) { swiper.mousewheel.enable(); } + }, + destroy: function destroy() { + var swiper = this; + if (swiper.mousewheel.enabled) { swiper.mousewheel.disable(); } + }, + }, + }; + + var Navigation = { + update: function update() { + // Update Navigation Buttons + var swiper = this; + var params = swiper.params.navigation; + + if (swiper.params.loop) { return; } + var ref = swiper.navigation; + var $nextEl = ref.$nextEl; + var $prevEl = ref.$prevEl; + + if ($prevEl && $prevEl.length > 0) { + if (swiper.isBeginning) { + $prevEl.addClass(params.disabledClass); + } else { + $prevEl.removeClass(params.disabledClass); + } + $prevEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + } + if ($nextEl && $nextEl.length > 0) { + if (swiper.isEnd) { + $nextEl.addClass(params.disabledClass); + } else { + $nextEl.removeClass(params.disabledClass); + } + $nextEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + } + }, + onPrevClick: function onPrevClick(e) { + var swiper = this; + e.preventDefault(); + if (swiper.isBeginning && !swiper.params.loop) { return; } + swiper.slidePrev(); + }, + onNextClick: function onNextClick(e) { + var swiper = this; + e.preventDefault(); + if (swiper.isEnd && !swiper.params.loop) { return; } + swiper.slideNext(); + }, + init: function init() { + var swiper = this; + var params = swiper.params.navigation; + if (!(params.nextEl || params.prevEl)) { return; } + + var $nextEl; + var $prevEl; + if (params.nextEl) { + $nextEl = $(params.nextEl); + if ( + swiper.params.uniqueNavElements + && typeof params.nextEl === 'string' + && $nextEl.length > 1 + && swiper.$el.find(params.nextEl).length === 1 + ) { + $nextEl = swiper.$el.find(params.nextEl); + } + } + if (params.prevEl) { + $prevEl = $(params.prevEl); + if ( + swiper.params.uniqueNavElements + && typeof params.prevEl === 'string' + && $prevEl.length > 1 + && swiper.$el.find(params.prevEl).length === 1 + ) { + $prevEl = swiper.$el.find(params.prevEl); + } + } + + if ($nextEl && $nextEl.length > 0) { + $nextEl.on('click', swiper.navigation.onNextClick); + } + if ($prevEl && $prevEl.length > 0) { + $prevEl.on('click', swiper.navigation.onPrevClick); + } + + Utils.extend(swiper.navigation, { + $nextEl: $nextEl, + nextEl: $nextEl && $nextEl[0], + $prevEl: $prevEl, + prevEl: $prevEl && $prevEl[0], + }); + }, + destroy: function destroy() { + var swiper = this; + var ref = swiper.navigation; + var $nextEl = ref.$nextEl; + var $prevEl = ref.$prevEl; + if ($nextEl && $nextEl.length) { + $nextEl.off('click', swiper.navigation.onNextClick); + $nextEl.removeClass(swiper.params.navigation.disabledClass); + } + if ($prevEl && $prevEl.length) { + $prevEl.off('click', swiper.navigation.onPrevClick); + $prevEl.removeClass(swiper.params.navigation.disabledClass); + } + }, + }; + + var Navigation$1 = { + name: 'navigation', + params: { + navigation: { + nextEl: null, + prevEl: null, + + hideOnClick: false, + disabledClass: 'swiper-button-disabled', + hiddenClass: 'swiper-button-hidden', + lockClass: 'swiper-button-lock', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + navigation: { + init: Navigation.init.bind(swiper), + update: Navigation.update.bind(swiper), + destroy: Navigation.destroy.bind(swiper), + onNextClick: Navigation.onNextClick.bind(swiper), + onPrevClick: Navigation.onPrevClick.bind(swiper), + }, + }); + }, + on: { + init: function init() { + var swiper = this; + swiper.navigation.init(); + swiper.navigation.update(); + }, + toEdge: function toEdge() { + var swiper = this; + swiper.navigation.update(); + }, + fromEdge: function fromEdge() { + var swiper = this; + swiper.navigation.update(); + }, + destroy: function destroy() { + var swiper = this; + swiper.navigation.destroy(); + }, + click: function click(e) { + var swiper = this; + var ref = swiper.navigation; + var $nextEl = ref.$nextEl; + var $prevEl = ref.$prevEl; + if ( + swiper.params.navigation.hideOnClick + && !$(e.target).is($prevEl) + && !$(e.target).is($nextEl) + ) { + var isHidden; + if ($nextEl) { + isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass); + } else if ($prevEl) { + isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass); + } + if (isHidden === true) { + swiper.emit('navigationShow', swiper); + } else { + swiper.emit('navigationHide', swiper); + } + if ($nextEl) { + $nextEl.toggleClass(swiper.params.navigation.hiddenClass); + } + if ($prevEl) { + $prevEl.toggleClass(swiper.params.navigation.hiddenClass); + } + } + }, + }, + }; + + var Pagination = { + update: function update() { + // Render || Update Pagination bullets/items + var swiper = this; + var rtl = swiper.rtl; + var params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) { return; } + var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; + var $el = swiper.pagination.$el; + // Current/Total + var current; + var total = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; + if (swiper.params.loop) { + current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup); + if (current > slidesLength - 1 - (swiper.loopedSlides * 2)) { + current -= (slidesLength - (swiper.loopedSlides * 2)); + } + if (current > total - 1) { current -= total; } + if (current < 0 && swiper.params.paginationType !== 'bullets') { current = total + current; } + } else if (typeof swiper.snapIndex !== 'undefined') { + current = swiper.snapIndex; + } else { + current = swiper.activeIndex || 0; + } + // Types + if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) { + var bullets = swiper.pagination.bullets; + var firstIndex; + var lastIndex; + var midIndex; + if (params.dynamicBullets) { + swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true); + $el.css(swiper.isHorizontal() ? 'width' : 'height', ((swiper.pagination.bulletSize * (params.dynamicMainBullets + 4)) + "px")); + if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) { + swiper.pagination.dynamicBulletIndex += (current - swiper.previousIndex); + if (swiper.pagination.dynamicBulletIndex > (params.dynamicMainBullets - 1)) { + swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1; + } else if (swiper.pagination.dynamicBulletIndex < 0) { + swiper.pagination.dynamicBulletIndex = 0; + } + } + firstIndex = current - swiper.pagination.dynamicBulletIndex; + lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1); + midIndex = (lastIndex + firstIndex) / 2; + } + bullets.removeClass(((params.bulletActiveClass) + " " + (params.bulletActiveClass) + "-next " + (params.bulletActiveClass) + "-next-next " + (params.bulletActiveClass) + "-prev " + (params.bulletActiveClass) + "-prev-prev " + (params.bulletActiveClass) + "-main")); + if ($el.length > 1) { + bullets.each(function (index, bullet) { + var $bullet = $(bullet); + var bulletIndex = $bullet.index(); + if (bulletIndex === current) { + $bullet.addClass(params.bulletActiveClass); + } + if (params.dynamicBullets) { + if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) { + $bullet.addClass(((params.bulletActiveClass) + "-main")); + } + if (bulletIndex === firstIndex) { + $bullet + .prev() + .addClass(((params.bulletActiveClass) + "-prev")) + .prev() + .addClass(((params.bulletActiveClass) + "-prev-prev")); + } + if (bulletIndex === lastIndex) { + $bullet + .next() + .addClass(((params.bulletActiveClass) + "-next")) + .next() + .addClass(((params.bulletActiveClass) + "-next-next")); + } + } + }); + } else { + var $bullet = bullets.eq(current); + $bullet.addClass(params.bulletActiveClass); + if (params.dynamicBullets) { + var $firstDisplayedBullet = bullets.eq(firstIndex); + var $lastDisplayedBullet = bullets.eq(lastIndex); + for (var i = firstIndex; i <= lastIndex; i += 1) { + bullets.eq(i).addClass(((params.bulletActiveClass) + "-main")); + } + $firstDisplayedBullet + .prev() + .addClass(((params.bulletActiveClass) + "-prev")) + .prev() + .addClass(((params.bulletActiveClass) + "-prev-prev")); + $lastDisplayedBullet + .next() + .addClass(((params.bulletActiveClass) + "-next")) + .next() + .addClass(((params.bulletActiveClass) + "-next-next")); + } + } + if (params.dynamicBullets) { + var dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4); + var bulletsOffset = (((swiper.pagination.bulletSize * dynamicBulletsLength) - (swiper.pagination.bulletSize)) / 2) - (midIndex * swiper.pagination.bulletSize); + var offsetProp = rtl ? 'right' : 'left'; + bullets.css(swiper.isHorizontal() ? offsetProp : 'top', (bulletsOffset + "px")); + } + } + if (params.type === 'fraction') { + $el.find(("." + (params.currentClass))).text(params.formatFractionCurrent(current + 1)); + $el.find(("." + (params.totalClass))).text(params.formatFractionTotal(total)); + } + if (params.type === 'progressbar') { + var progressbarDirection; + if (params.progressbarOpposite) { + progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal'; + } else { + progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical'; + } + var scale = (current + 1) / total; + var scaleX = 1; + var scaleY = 1; + if (progressbarDirection === 'horizontal') { + scaleX = scale; + } else { + scaleY = scale; + } + $el.find(("." + (params.progressbarFillClass))).transform(("translate3d(0,0,0) scaleX(" + scaleX + ") scaleY(" + scaleY + ")")).transition(swiper.params.speed); + } + if (params.type === 'custom' && params.renderCustom) { + $el.html(params.renderCustom(swiper, current + 1, total)); + swiper.emit('paginationRender', swiper, $el[0]); + } else { + swiper.emit('paginationUpdate', swiper, $el[0]); + } + $el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass); + }, + render: function render() { + // Render Container + var swiper = this; + var params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) { return; } + var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length; + + var $el = swiper.pagination.$el; + var paginationHTML = ''; + if (params.type === 'bullets') { + var numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length; + for (var i = 0; i < numberOfBullets; i += 1) { + if (params.renderBullet) { + paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass); + } else { + paginationHTML += "<" + (params.bulletElement) + " class=\"" + (params.bulletClass) + "\">"; + } + } + $el.html(paginationHTML); + swiper.pagination.bullets = $el.find(("." + (params.bulletClass))); + } + if (params.type === 'fraction') { + if (params.renderFraction) { + paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass); + } else { + paginationHTML = "" + + ' / ' + + ""; + } + $el.html(paginationHTML); + } + if (params.type === 'progressbar') { + if (params.renderProgressbar) { + paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass); + } else { + paginationHTML = ""; + } + $el.html(paginationHTML); + } + if (params.type !== 'custom') { + swiper.emit('paginationRender', swiper.pagination.$el[0]); + } + }, + init: function init() { + var swiper = this; + var params = swiper.params.pagination; + if (!params.el) { return; } + + var $el = $(params.el); + if ($el.length === 0) { return; } + + if ( + swiper.params.uniqueNavElements + && typeof params.el === 'string' + && $el.length > 1 + && swiper.$el.find(params.el).length === 1 + ) { + $el = swiper.$el.find(params.el); + } + + if (params.type === 'bullets' && params.clickable) { + $el.addClass(params.clickableClass); + } + + $el.addClass(params.modifierClass + params.type); + + if (params.type === 'bullets' && params.dynamicBullets) { + $el.addClass(("" + (params.modifierClass) + (params.type) + "-dynamic")); + swiper.pagination.dynamicBulletIndex = 0; + if (params.dynamicMainBullets < 1) { + params.dynamicMainBullets = 1; + } + } + if (params.type === 'progressbar' && params.progressbarOpposite) { + $el.addClass(params.progressbarOppositeClass); + } + + if (params.clickable) { + $el.on('click', ("." + (params.bulletClass)), function onClick(e) { + e.preventDefault(); + var index = $(this).index() * swiper.params.slidesPerGroup; + if (swiper.params.loop) { index += swiper.loopedSlides; } + swiper.slideTo(index); + }); + } + + Utils.extend(swiper.pagination, { + $el: $el, + el: $el[0], + }); + }, + destroy: function destroy() { + var swiper = this; + var params = swiper.params.pagination; + if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) { return; } + var $el = swiper.pagination.$el; + + $el.removeClass(params.hiddenClass); + $el.removeClass(params.modifierClass + params.type); + if (swiper.pagination.bullets) { swiper.pagination.bullets.removeClass(params.bulletActiveClass); } + if (params.clickable) { + $el.off('click', ("." + (params.bulletClass))); + } + }, + }; + + var Pagination$1 = { + name: 'pagination', + params: { + pagination: { + el: null, + bulletElement: 'span', + clickable: false, + hideOnClick: false, + renderBullet: null, + renderProgressbar: null, + renderFraction: null, + renderCustom: null, + progressbarOpposite: false, + type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom' + dynamicBullets: false, + dynamicMainBullets: 1, + formatFractionCurrent: function (number) { return number; }, + formatFractionTotal: function (number) { return number; }, + bulletClass: 'swiper-pagination-bullet', + bulletActiveClass: 'swiper-pagination-bullet-active', + modifierClass: 'swiper-pagination-', // NEW + currentClass: 'swiper-pagination-current', + totalClass: 'swiper-pagination-total', + hiddenClass: 'swiper-pagination-hidden', + progressbarFillClass: 'swiper-pagination-progressbar-fill', + progressbarOppositeClass: 'swiper-pagination-progressbar-opposite', + clickableClass: 'swiper-pagination-clickable', // NEW + lockClass: 'swiper-pagination-lock', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + pagination: { + init: Pagination.init.bind(swiper), + render: Pagination.render.bind(swiper), + update: Pagination.update.bind(swiper), + destroy: Pagination.destroy.bind(swiper), + dynamicBulletIndex: 0, + }, + }); + }, + on: { + init: function init() { + var swiper = this; + swiper.pagination.init(); + swiper.pagination.render(); + swiper.pagination.update(); + }, + activeIndexChange: function activeIndexChange() { + var swiper = this; + if (swiper.params.loop) { + swiper.pagination.update(); + } else if (typeof swiper.snapIndex === 'undefined') { + swiper.pagination.update(); + } + }, + snapIndexChange: function snapIndexChange() { + var swiper = this; + if (!swiper.params.loop) { + swiper.pagination.update(); + } + }, + slidesLengthChange: function slidesLengthChange() { + var swiper = this; + if (swiper.params.loop) { + swiper.pagination.render(); + swiper.pagination.update(); + } + }, + snapGridLengthChange: function snapGridLengthChange() { + var swiper = this; + if (!swiper.params.loop) { + swiper.pagination.render(); + swiper.pagination.update(); + } + }, + destroy: function destroy() { + var swiper = this; + swiper.pagination.destroy(); + }, + click: function click(e) { + var swiper = this; + if ( + swiper.params.pagination.el + && swiper.params.pagination.hideOnClick + && swiper.pagination.$el.length > 0 + && !$(e.target).hasClass(swiper.params.pagination.bulletClass) + ) { + var isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass); + if (isHidden === true) { + swiper.emit('paginationShow', swiper); + } else { + swiper.emit('paginationHide', swiper); + } + swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass); + } + }, + }, + }; + + var Scrollbar = { + setTranslate: function setTranslate() { + var swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) { return; } + var scrollbar = swiper.scrollbar; + var rtl = swiper.rtlTranslate; + var progress = swiper.progress; + var dragSize = scrollbar.dragSize; + var trackSize = scrollbar.trackSize; + var $dragEl = scrollbar.$dragEl; + var $el = scrollbar.$el; + var params = swiper.params.scrollbar; + + var newSize = dragSize; + var newPos = (trackSize - dragSize) * progress; + if (rtl) { + newPos = -newPos; + if (newPos > 0) { + newSize = dragSize - newPos; + newPos = 0; + } else if (-newPos + dragSize > trackSize) { + newSize = trackSize + newPos; + } + } else if (newPos < 0) { + newSize = dragSize + newPos; + newPos = 0; + } else if (newPos + dragSize > trackSize) { + newSize = trackSize - newPos; + } + if (swiper.isHorizontal()) { + if (Support.transforms3d) { + $dragEl.transform(("translate3d(" + newPos + "px, 0, 0)")); + } else { + $dragEl.transform(("translateX(" + newPos + "px)")); + } + $dragEl[0].style.width = newSize + "px"; + } else { + if (Support.transforms3d) { + $dragEl.transform(("translate3d(0px, " + newPos + "px, 0)")); + } else { + $dragEl.transform(("translateY(" + newPos + "px)")); + } + $dragEl[0].style.height = newSize + "px"; + } + if (params.hide) { + clearTimeout(swiper.scrollbar.timeout); + $el[0].style.opacity = 1; + swiper.scrollbar.timeout = setTimeout(function () { + $el[0].style.opacity = 0; + $el.transition(400); + }, 1000); + } + }, + setTransition: function setTransition(duration) { + var swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) { return; } + swiper.scrollbar.$dragEl.transition(duration); + }, + updateSize: function updateSize() { + var swiper = this; + if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) { return; } + + var scrollbar = swiper.scrollbar; + var $dragEl = scrollbar.$dragEl; + var $el = scrollbar.$el; + + $dragEl[0].style.width = ''; + $dragEl[0].style.height = ''; + var trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight; + + var divider = swiper.size / swiper.virtualSize; + var moveDivider = divider * (trackSize / swiper.size); + var dragSize; + if (swiper.params.scrollbar.dragSize === 'auto') { + dragSize = trackSize * divider; + } else { + dragSize = parseInt(swiper.params.scrollbar.dragSize, 10); + } + + if (swiper.isHorizontal()) { + $dragEl[0].style.width = dragSize + "px"; + } else { + $dragEl[0].style.height = dragSize + "px"; + } + + if (divider >= 1) { + $el[0].style.display = 'none'; + } else { + $el[0].style.display = ''; + } + if (swiper.params.scrollbar.hide) { + $el[0].style.opacity = 0; + } + Utils.extend(scrollbar, { + trackSize: trackSize, + divider: divider, + moveDivider: moveDivider, + dragSize: dragSize, + }); + scrollbar.$el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass); + }, + setDragPosition: function setDragPosition(e) { + var swiper = this; + var scrollbar = swiper.scrollbar; + var rtl = swiper.rtlTranslate; + var $el = scrollbar.$el; + var dragSize = scrollbar.dragSize; + var trackSize = scrollbar.trackSize; + + var pointerPosition; + if (swiper.isHorizontal()) { + pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX); + } else { + pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY); + } + var positionRatio; + positionRatio = ((pointerPosition) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragSize / 2)) / (trackSize - dragSize); + positionRatio = Math.max(Math.min(positionRatio, 1), 0); + if (rtl) { + positionRatio = 1 - positionRatio; + } + + var position = swiper.minTranslate() + ((swiper.maxTranslate() - swiper.minTranslate()) * positionRatio); + + swiper.updateProgress(position); + swiper.setTranslate(position); + swiper.updateActiveIndex(); + swiper.updateSlidesClasses(); + }, + onDragStart: function onDragStart(e) { + var swiper = this; + var params = swiper.params.scrollbar; + var scrollbar = swiper.scrollbar; + var $wrapperEl = swiper.$wrapperEl; + var $el = scrollbar.$el; + var $dragEl = scrollbar.$dragEl; + swiper.scrollbar.isTouched = true; + e.preventDefault(); + e.stopPropagation(); + + $wrapperEl.transition(100); + $dragEl.transition(100); + scrollbar.setDragPosition(e); + + clearTimeout(swiper.scrollbar.dragTimeout); + + $el.transition(0); + if (params.hide) { + $el.css('opacity', 1); + } + swiper.emit('scrollbarDragStart', e); + }, + onDragMove: function onDragMove(e) { + var swiper = this; + var scrollbar = swiper.scrollbar; + var $wrapperEl = swiper.$wrapperEl; + var $el = scrollbar.$el; + var $dragEl = scrollbar.$dragEl; + + if (!swiper.scrollbar.isTouched) { return; } + if (e.preventDefault) { e.preventDefault(); } + else { e.returnValue = false; } + scrollbar.setDragPosition(e); + $wrapperEl.transition(0); + $el.transition(0); + $dragEl.transition(0); + swiper.emit('scrollbarDragMove', e); + }, + onDragEnd: function onDragEnd(e) { + var swiper = this; + + var params = swiper.params.scrollbar; + var scrollbar = swiper.scrollbar; + var $el = scrollbar.$el; + + if (!swiper.scrollbar.isTouched) { return; } + swiper.scrollbar.isTouched = false; + if (params.hide) { + clearTimeout(swiper.scrollbar.dragTimeout); + swiper.scrollbar.dragTimeout = Utils.nextTick(function () { + $el.css('opacity', 0); + $el.transition(400); + }, 1000); + } + swiper.emit('scrollbarDragEnd', e); + if (params.snapOnRelease) { + swiper.slideToClosest(); + } + }, + enableDraggable: function enableDraggable() { + var swiper = this; + if (!swiper.params.scrollbar.el) { return; } + var scrollbar = swiper.scrollbar; + var touchEventsTouch = swiper.touchEventsTouch; + var touchEventsDesktop = swiper.touchEventsDesktop; + var params = swiper.params; + var $el = scrollbar.$el; + var target = $el[0]; + var activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false; + var passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + if (!Support.touch) { + target.addEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener); + doc.addEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener); + doc.addEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener); + } else { + target.addEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener); + target.addEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener); + target.addEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener); + } + }, + disableDraggable: function disableDraggable() { + var swiper = this; + if (!swiper.params.scrollbar.el) { return; } + var scrollbar = swiper.scrollbar; + var touchEventsTouch = swiper.touchEventsTouch; + var touchEventsDesktop = swiper.touchEventsDesktop; + var params = swiper.params; + var $el = scrollbar.$el; + var target = $el[0]; + var activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false; + var passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false; + if (!Support.touch) { + target.removeEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener); + doc.removeEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener); + doc.removeEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener); + } else { + target.removeEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener); + target.removeEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener); + target.removeEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener); + } + }, + init: function init() { + var swiper = this; + if (!swiper.params.scrollbar.el) { return; } + var scrollbar = swiper.scrollbar; + var $swiperEl = swiper.$el; + var params = swiper.params.scrollbar; + + var $el = $(params.el); + if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) { + $el = $swiperEl.find(params.el); + } + + var $dragEl = $el.find(("." + (swiper.params.scrollbar.dragClass))); + if ($dragEl.length === 0) { + $dragEl = $(("
            ")); + $el.append($dragEl); + } + + Utils.extend(scrollbar, { + $el: $el, + el: $el[0], + $dragEl: $dragEl, + dragEl: $dragEl[0], + }); + + if (params.draggable) { + scrollbar.enableDraggable(); + } + }, + destroy: function destroy() { + var swiper = this; + swiper.scrollbar.disableDraggable(); + }, + }; + + var Scrollbar$1 = { + name: 'scrollbar', + params: { + scrollbar: { + el: null, + dragSize: 'auto', + hide: false, + draggable: false, + snapOnRelease: true, + lockClass: 'swiper-scrollbar-lock', + dragClass: 'swiper-scrollbar-drag', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + scrollbar: { + init: Scrollbar.init.bind(swiper), + destroy: Scrollbar.destroy.bind(swiper), + updateSize: Scrollbar.updateSize.bind(swiper), + setTranslate: Scrollbar.setTranslate.bind(swiper), + setTransition: Scrollbar.setTransition.bind(swiper), + enableDraggable: Scrollbar.enableDraggable.bind(swiper), + disableDraggable: Scrollbar.disableDraggable.bind(swiper), + setDragPosition: Scrollbar.setDragPosition.bind(swiper), + onDragStart: Scrollbar.onDragStart.bind(swiper), + onDragMove: Scrollbar.onDragMove.bind(swiper), + onDragEnd: Scrollbar.onDragEnd.bind(swiper), + isTouched: false, + timeout: null, + dragTimeout: null, + }, + }); + }, + on: { + init: function init() { + var swiper = this; + swiper.scrollbar.init(); + swiper.scrollbar.updateSize(); + swiper.scrollbar.setTranslate(); + }, + update: function update() { + var swiper = this; + swiper.scrollbar.updateSize(); + }, + resize: function resize() { + var swiper = this; + swiper.scrollbar.updateSize(); + }, + observerUpdate: function observerUpdate() { + var swiper = this; + swiper.scrollbar.updateSize(); + }, + setTranslate: function setTranslate() { + var swiper = this; + swiper.scrollbar.setTranslate(); + }, + setTransition: function setTransition(duration) { + var swiper = this; + swiper.scrollbar.setTransition(duration); + }, + destroy: function destroy() { + var swiper = this; + swiper.scrollbar.destroy(); + }, + }, + }; + + var Parallax = { + setTransform: function setTransform(el, progress) { + var swiper = this; + var rtl = swiper.rtl; + + var $el = $(el); + var rtlFactor = rtl ? -1 : 1; + + var p = $el.attr('data-swiper-parallax') || '0'; + var x = $el.attr('data-swiper-parallax-x'); + var y = $el.attr('data-swiper-parallax-y'); + var scale = $el.attr('data-swiper-parallax-scale'); + var opacity = $el.attr('data-swiper-parallax-opacity'); + + if (x || y) { + x = x || '0'; + y = y || '0'; + } else if (swiper.isHorizontal()) { + x = p; + y = '0'; + } else { + y = p; + x = '0'; + } + + if ((x).indexOf('%') >= 0) { + x = (parseInt(x, 10) * progress * rtlFactor) + "%"; + } else { + x = (x * progress * rtlFactor) + "px"; + } + if ((y).indexOf('%') >= 0) { + y = (parseInt(y, 10) * progress) + "%"; + } else { + y = (y * progress) + "px"; + } + + if (typeof opacity !== 'undefined' && opacity !== null) { + var currentOpacity = opacity - ((opacity - 1) * (1 - Math.abs(progress))); + $el[0].style.opacity = currentOpacity; + } + if (typeof scale === 'undefined' || scale === null) { + $el.transform(("translate3d(" + x + ", " + y + ", 0px)")); + } else { + var currentScale = scale - ((scale - 1) * (1 - Math.abs(progress))); + $el.transform(("translate3d(" + x + ", " + y + ", 0px) scale(" + currentScale + ")")); + } + }, + setTranslate: function setTranslate() { + var swiper = this; + var $el = swiper.$el; + var slides = swiper.slides; + var progress = swiper.progress; + var snapGrid = swiper.snapGrid; + $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each(function (index, el) { + swiper.parallax.setTransform(el, progress); + }); + slides.each(function (slideIndex, slideEl) { + var slideProgress = slideEl.progress; + if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') { + slideProgress += Math.ceil(slideIndex / 2) - (progress * (snapGrid.length - 1)); + } + slideProgress = Math.min(Math.max(slideProgress, -1), 1); + $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each(function (index, el) { + swiper.parallax.setTransform(el, slideProgress); + }); + }); + }, + setTransition: function setTransition(duration) { + if ( duration === void 0 ) duration = this.params.speed; + + var swiper = this; + var $el = swiper.$el; + $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]') + .each(function (index, parallaxEl) { + var $parallaxEl = $(parallaxEl); + var parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration; + if (duration === 0) { parallaxDuration = 0; } + $parallaxEl.transition(parallaxDuration); + }); + }, + }; + + var Parallax$1 = { + name: 'parallax', + params: { + parallax: { + enabled: false, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + parallax: { + setTransform: Parallax.setTransform.bind(swiper), + setTranslate: Parallax.setTranslate.bind(swiper), + setTransition: Parallax.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + if (!swiper.params.parallax.enabled) { return; } + swiper.params.watchSlidesProgress = true; + swiper.originalParams.watchSlidesProgress = true; + }, + init: function init() { + var swiper = this; + if (!swiper.params.parallax.enabled) { return; } + swiper.parallax.setTranslate(); + }, + setTranslate: function setTranslate() { + var swiper = this; + if (!swiper.params.parallax.enabled) { return; } + swiper.parallax.setTranslate(); + }, + setTransition: function setTransition(duration) { + var swiper = this; + if (!swiper.params.parallax.enabled) { return; } + swiper.parallax.setTransition(duration); + }, + }, + }; + + var Zoom = { + // Calc Scale From Multi-touches + getDistanceBetweenTouches: function getDistanceBetweenTouches(e) { + if (e.targetTouches.length < 2) { return 1; } + var x1 = e.targetTouches[0].pageX; + var y1 = e.targetTouches[0].pageY; + var x2 = e.targetTouches[1].pageX; + var y2 = e.targetTouches[1].pageY; + var distance = Math.sqrt((Math.pow( (x2 - x1), 2 )) + (Math.pow( (y2 - y1), 2 ))); + return distance; + }, + // Events + onGestureStart: function onGestureStart(e) { + var swiper = this; + var params = swiper.params.zoom; + var zoom = swiper.zoom; + var gesture = zoom.gesture; + zoom.fakeGestureTouched = false; + zoom.fakeGestureMoved = false; + if (!Support.gestures) { + if (e.type !== 'touchstart' || (e.type === 'touchstart' && e.targetTouches.length < 2)) { + return; + } + zoom.fakeGestureTouched = true; + gesture.scaleStart = Zoom.getDistanceBetweenTouches(e); + } + if (!gesture.$slideEl || !gesture.$slideEl.length) { + gesture.$slideEl = $(e.target).closest('.swiper-slide'); + if (gesture.$slideEl.length === 0) { gesture.$slideEl = swiper.slides.eq(swiper.activeIndex); } + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(("." + (params.containerClass))); + gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + if (gesture.$imageWrapEl.length === 0) { + gesture.$imageEl = undefined; + return; + } + } + gesture.$imageEl.transition(0); + swiper.zoom.isScaling = true; + }, + onGestureChange: function onGestureChange(e) { + var swiper = this; + var params = swiper.params.zoom; + var zoom = swiper.zoom; + var gesture = zoom.gesture; + if (!Support.gestures) { + if (e.type !== 'touchmove' || (e.type === 'touchmove' && e.targetTouches.length < 2)) { + return; + } + zoom.fakeGestureMoved = true; + gesture.scaleMove = Zoom.getDistanceBetweenTouches(e); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; } + if (Support.gestures) { + zoom.scale = e.scale * zoom.currentScale; + } else { + zoom.scale = (gesture.scaleMove / gesture.scaleStart) * zoom.currentScale; + } + if (zoom.scale > gesture.maxRatio) { + zoom.scale = (gesture.maxRatio - 1) + (Math.pow( ((zoom.scale - gesture.maxRatio) + 1), 0.5 )); + } + if (zoom.scale < params.minRatio) { + zoom.scale = (params.minRatio + 1) - (Math.pow( ((params.minRatio - zoom.scale) + 1), 0.5 )); + } + gesture.$imageEl.transform(("translate3d(0,0,0) scale(" + (zoom.scale) + ")")); + }, + onGestureEnd: function onGestureEnd(e) { + var swiper = this; + var params = swiper.params.zoom; + var zoom = swiper.zoom; + var gesture = zoom.gesture; + if (!Support.gestures) { + if (!zoom.fakeGestureTouched || !zoom.fakeGestureMoved) { + return; + } + if (e.type !== 'touchend' || (e.type === 'touchend' && e.changedTouches.length < 2 && !Device.android)) { + return; + } + zoom.fakeGestureTouched = false; + zoom.fakeGestureMoved = false; + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; } + zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio); + gesture.$imageEl.transition(swiper.params.speed).transform(("translate3d(0,0,0) scale(" + (zoom.scale) + ")")); + zoom.currentScale = zoom.scale; + zoom.isScaling = false; + if (zoom.scale === 1) { gesture.$slideEl = undefined; } + }, + onTouchStart: function onTouchStart(e) { + var swiper = this; + var zoom = swiper.zoom; + var gesture = zoom.gesture; + var image = zoom.image; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; } + if (image.isTouched) { return; } + if (Device.android) { e.preventDefault(); } + image.isTouched = true; + image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX; + image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY; + }, + onTouchMove: function onTouchMove(e) { + var swiper = this; + var zoom = swiper.zoom; + var gesture = zoom.gesture; + var image = zoom.image; + var velocity = zoom.velocity; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; } + swiper.allowClick = false; + if (!image.isTouched || !gesture.$slideEl) { return; } + + if (!image.isMoved) { + image.width = gesture.$imageEl[0].offsetWidth; + image.height = gesture.$imageEl[0].offsetHeight; + image.startX = Utils.getTranslate(gesture.$imageWrapEl[0], 'x') || 0; + image.startY = Utils.getTranslate(gesture.$imageWrapEl[0], 'y') || 0; + gesture.slideWidth = gesture.$slideEl[0].offsetWidth; + gesture.slideHeight = gesture.$slideEl[0].offsetHeight; + gesture.$imageWrapEl.transition(0); + if (swiper.rtl) { + image.startX = -image.startX; + image.startY = -image.startY; + } + } + // Define if we need image drag + var scaledWidth = image.width * zoom.scale; + var scaledHeight = image.height * zoom.scale; + + if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) { return; } + + image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0); + image.maxX = -image.minX; + image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0); + image.maxY = -image.minY; + + image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX; + image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY; + + if (!image.isMoved && !zoom.isScaling) { + if ( + swiper.isHorizontal() + && ( + (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x) + || (Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x) + ) + ) { + image.isTouched = false; + return; + } if ( + !swiper.isHorizontal() + && ( + (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y) + || (Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y) + ) + ) { + image.isTouched = false; + return; + } + } + e.preventDefault(); + e.stopPropagation(); + + image.isMoved = true; + image.currentX = (image.touchesCurrent.x - image.touchesStart.x) + image.startX; + image.currentY = (image.touchesCurrent.y - image.touchesStart.y) + image.startY; + + if (image.currentX < image.minX) { + image.currentX = (image.minX + 1) - (Math.pow( ((image.minX - image.currentX) + 1), 0.8 )); + } + if (image.currentX > image.maxX) { + image.currentX = (image.maxX - 1) + (Math.pow( ((image.currentX - image.maxX) + 1), 0.8 )); + } + + if (image.currentY < image.minY) { + image.currentY = (image.minY + 1) - (Math.pow( ((image.minY - image.currentY) + 1), 0.8 )); + } + if (image.currentY > image.maxY) { + image.currentY = (image.maxY - 1) + (Math.pow( ((image.currentY - image.maxY) + 1), 0.8 )); + } + + // Velocity + if (!velocity.prevPositionX) { velocity.prevPositionX = image.touchesCurrent.x; } + if (!velocity.prevPositionY) { velocity.prevPositionY = image.touchesCurrent.y; } + if (!velocity.prevTime) { velocity.prevTime = Date.now(); } + velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2; + velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2; + if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) { velocity.x = 0; } + if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) { velocity.y = 0; } + velocity.prevPositionX = image.touchesCurrent.x; + velocity.prevPositionY = image.touchesCurrent.y; + velocity.prevTime = Date.now(); + + gesture.$imageWrapEl.transform(("translate3d(" + (image.currentX) + "px, " + (image.currentY) + "px,0)")); + }, + onTouchEnd: function onTouchEnd() { + var swiper = this; + var zoom = swiper.zoom; + var gesture = zoom.gesture; + var image = zoom.image; + var velocity = zoom.velocity; + if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; } + if (!image.isTouched || !image.isMoved) { + image.isTouched = false; + image.isMoved = false; + return; + } + image.isTouched = false; + image.isMoved = false; + var momentumDurationX = 300; + var momentumDurationY = 300; + var momentumDistanceX = velocity.x * momentumDurationX; + var newPositionX = image.currentX + momentumDistanceX; + var momentumDistanceY = velocity.y * momentumDurationY; + var newPositionY = image.currentY + momentumDistanceY; + + // Fix duration + if (velocity.x !== 0) { momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x); } + if (velocity.y !== 0) { momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y); } + var momentumDuration = Math.max(momentumDurationX, momentumDurationY); + + image.currentX = newPositionX; + image.currentY = newPositionY; + + // Define if we need image drag + var scaledWidth = image.width * zoom.scale; + var scaledHeight = image.height * zoom.scale; + image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0); + image.maxX = -image.minX; + image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0); + image.maxY = -image.minY; + image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX); + image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY); + + gesture.$imageWrapEl.transition(momentumDuration).transform(("translate3d(" + (image.currentX) + "px, " + (image.currentY) + "px,0)")); + }, + onTransitionEnd: function onTransitionEnd() { + var swiper = this; + var zoom = swiper.zoom; + var gesture = zoom.gesture; + if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) { + gesture.$imageEl.transform('translate3d(0,0,0) scale(1)'); + gesture.$imageWrapEl.transform('translate3d(0,0,0)'); + + zoom.scale = 1; + zoom.currentScale = 1; + + gesture.$slideEl = undefined; + gesture.$imageEl = undefined; + gesture.$imageWrapEl = undefined; + } + }, + // Toggle Zoom + toggle: function toggle(e) { + var swiper = this; + var zoom = swiper.zoom; + + if (zoom.scale && zoom.scale !== 1) { + // Zoom Out + zoom.out(); + } else { + // Zoom In + zoom.in(e); + } + }, + in: function in$1(e) { + var swiper = this; + + var zoom = swiper.zoom; + var params = swiper.params.zoom; + var gesture = zoom.gesture; + var image = zoom.image; + + if (!gesture.$slideEl) { + gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(("." + (params.containerClass))); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; } + + gesture.$slideEl.addClass(("" + (params.zoomedSlideClass))); + + var touchX; + var touchY; + var offsetX; + var offsetY; + var diffX; + var diffY; + var translateX; + var translateY; + var imageWidth; + var imageHeight; + var scaledWidth; + var scaledHeight; + var translateMinX; + var translateMinY; + var translateMaxX; + var translateMaxY; + var slideWidth; + var slideHeight; + + if (typeof image.touchesStart.x === 'undefined' && e) { + touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX; + touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY; + } else { + touchX = image.touchesStart.x; + touchY = image.touchesStart.y; + } + + zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + zoom.currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio; + if (e) { + slideWidth = gesture.$slideEl[0].offsetWidth; + slideHeight = gesture.$slideEl[0].offsetHeight; + offsetX = gesture.$slideEl.offset().left; + offsetY = gesture.$slideEl.offset().top; + diffX = (offsetX + (slideWidth / 2)) - touchX; + diffY = (offsetY + (slideHeight / 2)) - touchY; + + imageWidth = gesture.$imageEl[0].offsetWidth; + imageHeight = gesture.$imageEl[0].offsetHeight; + scaledWidth = imageWidth * zoom.scale; + scaledHeight = imageHeight * zoom.scale; + + translateMinX = Math.min(((slideWidth / 2) - (scaledWidth / 2)), 0); + translateMinY = Math.min(((slideHeight / 2) - (scaledHeight / 2)), 0); + translateMaxX = -translateMinX; + translateMaxY = -translateMinY; + + translateX = diffX * zoom.scale; + translateY = diffY * zoom.scale; + + if (translateX < translateMinX) { + translateX = translateMinX; + } + if (translateX > translateMaxX) { + translateX = translateMaxX; + } + + if (translateY < translateMinY) { + translateY = translateMinY; + } + if (translateY > translateMaxY) { + translateY = translateMaxY; + } + } else { + translateX = 0; + translateY = 0; + } + gesture.$imageWrapEl.transition(300).transform(("translate3d(" + translateX + "px, " + translateY + "px,0)")); + gesture.$imageEl.transition(300).transform(("translate3d(0,0,0) scale(" + (zoom.scale) + ")")); + }, + out: function out() { + var swiper = this; + + var zoom = swiper.zoom; + var params = swiper.params.zoom; + var gesture = zoom.gesture; + + if (!gesture.$slideEl) { + gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex); + gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas'); + gesture.$imageWrapEl = gesture.$imageEl.parent(("." + (params.containerClass))); + } + if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; } + + zoom.scale = 1; + zoom.currentScale = 1; + gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)'); + gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)'); + gesture.$slideEl.removeClass(("" + (params.zoomedSlideClass))); + gesture.$slideEl = undefined; + }, + // Attach/Detach Events + enable: function enable() { + var swiper = this; + var zoom = swiper.zoom; + if (zoom.enabled) { return; } + zoom.enabled = true; + + var passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false; + + // Scale image + if (Support.gestures) { + swiper.$wrapperEl.on('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.on('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.on('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener); + } else if (swiper.touchEvents.start === 'touchstart') { + swiper.$wrapperEl.on(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.on(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.on(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener); + } + + // Move image + swiper.$wrapperEl.on(swiper.touchEvents.move, ("." + (swiper.params.zoom.containerClass)), zoom.onTouchMove); + }, + disable: function disable() { + var swiper = this; + var zoom = swiper.zoom; + if (!zoom.enabled) { return; } + + swiper.zoom.enabled = false; + + var passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false; + + // Scale image + if (Support.gestures) { + swiper.$wrapperEl.off('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.off('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.off('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener); + } else if (swiper.touchEvents.start === 'touchstart') { + swiper.$wrapperEl.off(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener); + swiper.$wrapperEl.off(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener); + swiper.$wrapperEl.off(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener); + } + + // Move image + swiper.$wrapperEl.off(swiper.touchEvents.move, ("." + (swiper.params.zoom.containerClass)), zoom.onTouchMove); + }, + }; + + var Zoom$1 = { + name: 'zoom', + params: { + zoom: { + enabled: false, + maxRatio: 3, + minRatio: 1, + toggle: true, + containerClass: 'swiper-zoom-container', + zoomedSlideClass: 'swiper-slide-zoomed', + }, + }, + create: function create() { + var swiper = this; + var zoom = { + enabled: false, + scale: 1, + currentScale: 1, + isScaling: false, + gesture: { + $slideEl: undefined, + slideWidth: undefined, + slideHeight: undefined, + $imageEl: undefined, + $imageWrapEl: undefined, + maxRatio: 3, + }, + image: { + isTouched: undefined, + isMoved: undefined, + currentX: undefined, + currentY: undefined, + minX: undefined, + minY: undefined, + maxX: undefined, + maxY: undefined, + width: undefined, + height: undefined, + startX: undefined, + startY: undefined, + touchesStart: {}, + touchesCurrent: {}, + }, + velocity: { + x: undefined, + y: undefined, + prevPositionX: undefined, + prevPositionY: undefined, + prevTime: undefined, + }, + }; + + ('onGestureStart onGestureChange onGestureEnd onTouchStart onTouchMove onTouchEnd onTransitionEnd toggle enable disable in out').split(' ').forEach(function (methodName) { + zoom[methodName] = Zoom[methodName].bind(swiper); + }); + Utils.extend(swiper, { + zoom: zoom, + }); + + var scale = 1; + Object.defineProperty(swiper.zoom, 'scale', { + get: function get() { + return scale; + }, + set: function set(value) { + if (scale !== value) { + var imageEl = swiper.zoom.gesture.$imageEl ? swiper.zoom.gesture.$imageEl[0] : undefined; + var slideEl = swiper.zoom.gesture.$slideEl ? swiper.zoom.gesture.$slideEl[0] : undefined; + swiper.emit('zoomChange', value, imageEl, slideEl); + } + scale = value; + }, + }); + }, + on: { + init: function init() { + var swiper = this; + if (swiper.params.zoom.enabled) { + swiper.zoom.enable(); + } + }, + destroy: function destroy() { + var swiper = this; + swiper.zoom.disable(); + }, + touchStart: function touchStart(e) { + var swiper = this; + if (!swiper.zoom.enabled) { return; } + swiper.zoom.onTouchStart(e); + }, + touchEnd: function touchEnd(e) { + var swiper = this; + if (!swiper.zoom.enabled) { return; } + swiper.zoom.onTouchEnd(e); + }, + doubleTap: function doubleTap(e) { + var swiper = this; + if (swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) { + swiper.zoom.toggle(e); + } + }, + transitionEnd: function transitionEnd() { + var swiper = this; + if (swiper.zoom.enabled && swiper.params.zoom.enabled) { + swiper.zoom.onTransitionEnd(); + } + }, + }, + }; + + var Lazy = { + loadInSlide: function loadInSlide(index, loadInDuplicate) { + if ( loadInDuplicate === void 0 ) loadInDuplicate = true; + + var swiper = this; + var params = swiper.params.lazy; + if (typeof index === 'undefined') { return; } + if (swiper.slides.length === 0) { return; } + var isVirtual = swiper.virtual && swiper.params.virtual.enabled; + + var $slideEl = isVirtual + ? swiper.$wrapperEl.children(("." + (swiper.params.slideClass) + "[data-swiper-slide-index=\"" + index + "\"]")) + : swiper.slides.eq(index); + + var $images = $slideEl.find(("." + (params.elementClass) + ":not(." + (params.loadedClass) + "):not(." + (params.loadingClass) + ")")); + if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) { + $images = $images.add($slideEl[0]); + } + if ($images.length === 0) { return; } + + $images.each(function (imageIndex, imageEl) { + var $imageEl = $(imageEl); + $imageEl.addClass(params.loadingClass); + + var background = $imageEl.attr('data-background'); + var src = $imageEl.attr('data-src'); + var srcset = $imageEl.attr('data-srcset'); + var sizes = $imageEl.attr('data-sizes'); + + swiper.loadImage($imageEl[0], (src || background), srcset, sizes, false, function () { + if (typeof swiper === 'undefined' || swiper === null || !swiper || (swiper && !swiper.params) || swiper.destroyed) { return; } + if (background) { + $imageEl.css('background-image', ("url(\"" + background + "\")")); + $imageEl.removeAttr('data-background'); + } else { + if (srcset) { + $imageEl.attr('srcset', srcset); + $imageEl.removeAttr('data-srcset'); + } + if (sizes) { + $imageEl.attr('sizes', sizes); + $imageEl.removeAttr('data-sizes'); + } + if (src) { + $imageEl.attr('src', src); + $imageEl.removeAttr('data-src'); + } + } + + $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass); + $slideEl.find(("." + (params.preloaderClass))).remove(); + if (swiper.params.loop && loadInDuplicate) { + var slideOriginalIndex = $slideEl.attr('data-swiper-slide-index'); + if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) { + var originalSlide = swiper.$wrapperEl.children(("[data-swiper-slide-index=\"" + slideOriginalIndex + "\"]:not(." + (swiper.params.slideDuplicateClass) + ")")); + swiper.lazy.loadInSlide(originalSlide.index(), false); + } else { + var duplicatedSlide = swiper.$wrapperEl.children(("." + (swiper.params.slideDuplicateClass) + "[data-swiper-slide-index=\"" + slideOriginalIndex + "\"]")); + swiper.lazy.loadInSlide(duplicatedSlide.index(), false); + } + } + swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]); + }); + + swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]); + }); + }, + load: function load() { + var swiper = this; + var $wrapperEl = swiper.$wrapperEl; + var swiperParams = swiper.params; + var slides = swiper.slides; + var activeIndex = swiper.activeIndex; + var isVirtual = swiper.virtual && swiperParams.virtual.enabled; + var params = swiperParams.lazy; + + var slidesPerView = swiperParams.slidesPerView; + if (slidesPerView === 'auto') { + slidesPerView = 0; + } + + function slideExist(index) { + if (isVirtual) { + if ($wrapperEl.children(("." + (swiperParams.slideClass) + "[data-swiper-slide-index=\"" + index + "\"]")).length) { + return true; + } + } else if (slides[index]) { return true; } + return false; + } + function slideIndex(slideEl) { + if (isVirtual) { + return $(slideEl).attr('data-swiper-slide-index'); + } + return $(slideEl).index(); + } + + if (!swiper.lazy.initialImageLoaded) { swiper.lazy.initialImageLoaded = true; } + if (swiper.params.watchSlidesVisibility) { + $wrapperEl.children(("." + (swiperParams.slideVisibleClass))).each(function (elIndex, slideEl) { + var index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index(); + swiper.lazy.loadInSlide(index); + }); + } else if (slidesPerView > 1) { + for (var i = activeIndex; i < activeIndex + slidesPerView; i += 1) { + if (slideExist(i)) { swiper.lazy.loadInSlide(i); } + } + } else { + swiper.lazy.loadInSlide(activeIndex); + } + if (params.loadPrevNext) { + if (slidesPerView > 1 || (params.loadPrevNextAmount && params.loadPrevNextAmount > 1)) { + var amount = params.loadPrevNextAmount; + var spv = slidesPerView; + var maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length); + var minIndex = Math.max(activeIndex - Math.max(spv, amount), 0); + // Next Slides + for (var i$1 = activeIndex + slidesPerView; i$1 < maxIndex; i$1 += 1) { + if (slideExist(i$1)) { swiper.lazy.loadInSlide(i$1); } + } + // Prev Slides + for (var i$2 = minIndex; i$2 < activeIndex; i$2 += 1) { + if (slideExist(i$2)) { swiper.lazy.loadInSlide(i$2); } + } + } else { + var nextSlide = $wrapperEl.children(("." + (swiperParams.slideNextClass))); + if (nextSlide.length > 0) { swiper.lazy.loadInSlide(slideIndex(nextSlide)); } + + var prevSlide = $wrapperEl.children(("." + (swiperParams.slidePrevClass))); + if (prevSlide.length > 0) { swiper.lazy.loadInSlide(slideIndex(prevSlide)); } + } + } + }, + }; + + var Lazy$1 = { + name: 'lazy', + params: { + lazy: { + enabled: false, + loadPrevNext: false, + loadPrevNextAmount: 1, + loadOnTransitionStart: false, + + elementClass: 'swiper-lazy', + loadingClass: 'swiper-lazy-loading', + loadedClass: 'swiper-lazy-loaded', + preloaderClass: 'swiper-lazy-preloader', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + lazy: { + initialImageLoaded: false, + load: Lazy.load.bind(swiper), + loadInSlide: Lazy.loadInSlide.bind(swiper), + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + if (swiper.params.lazy.enabled && swiper.params.preloadImages) { + swiper.params.preloadImages = false; + } + }, + init: function init() { + var swiper = this; + if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) { + swiper.lazy.load(); + } + }, + scroll: function scroll() { + var swiper = this; + if (swiper.params.freeMode && !swiper.params.freeModeSticky) { + swiper.lazy.load(); + } + }, + resize: function resize() { + var swiper = this; + if (swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + }, + scrollbarDragMove: function scrollbarDragMove() { + var swiper = this; + if (swiper.params.lazy.enabled) { + swiper.lazy.load(); + } + }, + transitionStart: function transitionStart() { + var swiper = this; + if (swiper.params.lazy.enabled) { + if (swiper.params.lazy.loadOnTransitionStart || (!swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded)) { + swiper.lazy.load(); + } + } + }, + transitionEnd: function transitionEnd() { + var swiper = this; + if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) { + swiper.lazy.load(); + } + }, + }, + }; + + /* eslint no-bitwise: ["error", { "allow": [">>"] }] */ + + var Controller = { + LinearSpline: function LinearSpline(x, y) { + var binarySearch = (function search() { + var maxIndex; + var minIndex; + var guess; + return function (array, val) { + minIndex = -1; + maxIndex = array.length; + while (maxIndex - minIndex > 1) { + guess = maxIndex + minIndex >> 1; + if (array[guess] <= val) { + minIndex = guess; + } else { + maxIndex = guess; + } + } + return maxIndex; + }; + }()); + this.x = x; + this.y = y; + this.lastIndex = x.length - 1; + // Given an x value (x2), return the expected y2 value: + // (x1,y1) is the known point before given value, + // (x3,y3) is the known point after given value. + var i1; + var i3; + + this.interpolate = function interpolate(x2) { + if (!x2) { return 0; } + + // Get the indexes of x1 and x3 (the array indexes before and after given x2): + i3 = binarySearch(this.x, x2); + i1 = i3 - 1; + + // We have our indexes i1 & i3, so we can calculate already: + // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1 + return (((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1])) + this.y[i1]; + }; + return this; + }, + // xxx: for now i will just save one spline function to to + getInterpolateFunction: function getInterpolateFunction(c) { + var swiper = this; + if (!swiper.controller.spline) { + swiper.controller.spline = swiper.params.loop + ? new Controller.LinearSpline(swiper.slidesGrid, c.slidesGrid) + : new Controller.LinearSpline(swiper.snapGrid, c.snapGrid); + } + }, + setTranslate: function setTranslate(setTranslate$1, byController) { + var swiper = this; + var controlled = swiper.controller.control; + var multiplier; + var controlledTranslate; + function setControlledTranslate(c) { + // this will create an Interpolate function based on the snapGrids + // x is the Grid of the scrolled scroller and y will be the controlled scroller + // it makes sense to create this only once and recall it for the interpolation + // the function does a lot of value caching for performance + var translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate; + if (swiper.params.controller.by === 'slide') { + swiper.controller.getInterpolateFunction(c); + // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid + // but it did not work out + controlledTranslate = -swiper.controller.spline.interpolate(-translate); + } + + if (!controlledTranslate || swiper.params.controller.by === 'container') { + multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate()); + controlledTranslate = ((translate - swiper.minTranslate()) * multiplier) + c.minTranslate(); + } + + if (swiper.params.controller.inverse) { + controlledTranslate = c.maxTranslate() - controlledTranslate; + } + c.updateProgress(controlledTranslate); + c.setTranslate(controlledTranslate, swiper); + c.updateActiveIndex(); + c.updateSlidesClasses(); + } + if (Array.isArray(controlled)) { + for (var i = 0; i < controlled.length; i += 1) { + if (controlled[i] !== byController && controlled[i] instanceof Swiper) { + setControlledTranslate(controlled[i]); + } + } + } else if (controlled instanceof Swiper && byController !== controlled) { + setControlledTranslate(controlled); + } + }, + setTransition: function setTransition(duration, byController) { + var swiper = this; + var controlled = swiper.controller.control; + var i; + function setControlledTransition(c) { + c.setTransition(duration, swiper); + if (duration !== 0) { + c.transitionStart(); + if (c.params.autoHeight) { + Utils.nextTick(function () { + c.updateAutoHeight(); + }); + } + c.$wrapperEl.transitionEnd(function () { + if (!controlled) { return; } + if (c.params.loop && swiper.params.controller.by === 'slide') { + c.loopFix(); + } + c.transitionEnd(); + }); + } + } + if (Array.isArray(controlled)) { + for (i = 0; i < controlled.length; i += 1) { + if (controlled[i] !== byController && controlled[i] instanceof Swiper) { + setControlledTransition(controlled[i]); + } + } + } else if (controlled instanceof Swiper && byController !== controlled) { + setControlledTransition(controlled); + } + }, + }; + var Controller$1 = { + name: 'controller', + params: { + controller: { + control: undefined, + inverse: false, + by: 'slide', // or 'container' + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + controller: { + control: swiper.params.controller.control, + getInterpolateFunction: Controller.getInterpolateFunction.bind(swiper), + setTranslate: Controller.setTranslate.bind(swiper), + setTransition: Controller.setTransition.bind(swiper), + }, + }); + }, + on: { + update: function update() { + var swiper = this; + if (!swiper.controller.control) { return; } + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + resize: function resize() { + var swiper = this; + if (!swiper.controller.control) { return; } + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + observerUpdate: function observerUpdate() { + var swiper = this; + if (!swiper.controller.control) { return; } + if (swiper.controller.spline) { + swiper.controller.spline = undefined; + delete swiper.controller.spline; + } + }, + setTranslate: function setTranslate(translate, byController) { + var swiper = this; + if (!swiper.controller.control) { return; } + swiper.controller.setTranslate(translate, byController); + }, + setTransition: function setTransition(duration, byController) { + var swiper = this; + if (!swiper.controller.control) { return; } + swiper.controller.setTransition(duration, byController); + }, + }, + }; + + var a11y = { + makeElFocusable: function makeElFocusable($el) { + $el.attr('tabIndex', '0'); + return $el; + }, + addElRole: function addElRole($el, role) { + $el.attr('role', role); + return $el; + }, + addElLabel: function addElLabel($el, label) { + $el.attr('aria-label', label); + return $el; + }, + disableEl: function disableEl($el) { + $el.attr('aria-disabled', true); + return $el; + }, + enableEl: function enableEl($el) { + $el.attr('aria-disabled', false); + return $el; + }, + onEnterKey: function onEnterKey(e) { + var swiper = this; + var params = swiper.params.a11y; + if (e.keyCode !== 13) { return; } + var $targetEl = $(e.target); + if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) { + if (!(swiper.isEnd && !swiper.params.loop)) { + swiper.slideNext(); + } + if (swiper.isEnd) { + swiper.a11y.notify(params.lastSlideMessage); + } else { + swiper.a11y.notify(params.nextSlideMessage); + } + } + if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) { + if (!(swiper.isBeginning && !swiper.params.loop)) { + swiper.slidePrev(); + } + if (swiper.isBeginning) { + swiper.a11y.notify(params.firstSlideMessage); + } else { + swiper.a11y.notify(params.prevSlideMessage); + } + } + if (swiper.pagination && $targetEl.is(("." + (swiper.params.pagination.bulletClass)))) { + $targetEl[0].click(); + } + }, + notify: function notify(message) { + var swiper = this; + var notification = swiper.a11y.liveRegion; + if (notification.length === 0) { return; } + notification.html(''); + notification.html(message); + }, + updateNavigation: function updateNavigation() { + var swiper = this; + + if (swiper.params.loop) { return; } + var ref = swiper.navigation; + var $nextEl = ref.$nextEl; + var $prevEl = ref.$prevEl; + + if ($prevEl && $prevEl.length > 0) { + if (swiper.isBeginning) { + swiper.a11y.disableEl($prevEl); + } else { + swiper.a11y.enableEl($prevEl); + } + } + if ($nextEl && $nextEl.length > 0) { + if (swiper.isEnd) { + swiper.a11y.disableEl($nextEl); + } else { + swiper.a11y.enableEl($nextEl); + } + } + }, + updatePagination: function updatePagination() { + var swiper = this; + var params = swiper.params.a11y; + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.bullets.each(function (bulletIndex, bulletEl) { + var $bulletEl = $(bulletEl); + swiper.a11y.makeElFocusable($bulletEl); + swiper.a11y.addElRole($bulletEl, 'button'); + swiper.a11y.addElLabel($bulletEl, params.paginationBulletMessage.replace(/{{index}}/, $bulletEl.index() + 1)); + }); + } + }, + init: function init() { + var swiper = this; + + swiper.$el.append(swiper.a11y.liveRegion); + + // Navigation + var params = swiper.params.a11y; + var $nextEl; + var $prevEl; + if (swiper.navigation && swiper.navigation.$nextEl) { + $nextEl = swiper.navigation.$nextEl; + } + if (swiper.navigation && swiper.navigation.$prevEl) { + $prevEl = swiper.navigation.$prevEl; + } + if ($nextEl) { + swiper.a11y.makeElFocusable($nextEl); + swiper.a11y.addElRole($nextEl, 'button'); + swiper.a11y.addElLabel($nextEl, params.nextSlideMessage); + $nextEl.on('keydown', swiper.a11y.onEnterKey); + } + if ($prevEl) { + swiper.a11y.makeElFocusable($prevEl); + swiper.a11y.addElRole($prevEl, 'button'); + swiper.a11y.addElLabel($prevEl, params.prevSlideMessage); + $prevEl.on('keydown', swiper.a11y.onEnterKey); + } + + // Pagination + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.$el.on('keydown', ("." + (swiper.params.pagination.bulletClass)), swiper.a11y.onEnterKey); + } + }, + destroy: function destroy() { + var swiper = this; + if (swiper.a11y.liveRegion && swiper.a11y.liveRegion.length > 0) { swiper.a11y.liveRegion.remove(); } + + var $nextEl; + var $prevEl; + if (swiper.navigation && swiper.navigation.$nextEl) { + $nextEl = swiper.navigation.$nextEl; + } + if (swiper.navigation && swiper.navigation.$prevEl) { + $prevEl = swiper.navigation.$prevEl; + } + if ($nextEl) { + $nextEl.off('keydown', swiper.a11y.onEnterKey); + } + if ($prevEl) { + $prevEl.off('keydown', swiper.a11y.onEnterKey); + } + + // Pagination + if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) { + swiper.pagination.$el.off('keydown', ("." + (swiper.params.pagination.bulletClass)), swiper.a11y.onEnterKey); + } + }, + }; + var A11y = { + name: 'a11y', + params: { + a11y: { + enabled: true, + notificationClass: 'swiper-notification', + prevSlideMessage: 'Previous slide', + nextSlideMessage: 'Next slide', + firstSlideMessage: 'This is the first slide', + lastSlideMessage: 'This is the last slide', + paginationBulletMessage: 'Go to slide {{index}}', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + a11y: { + liveRegion: $(("")), + }, + }); + Object.keys(a11y).forEach(function (methodName) { + swiper.a11y[methodName] = a11y[methodName].bind(swiper); + }); + }, + on: { + init: function init() { + var swiper = this; + if (!swiper.params.a11y.enabled) { return; } + swiper.a11y.init(); + swiper.a11y.updateNavigation(); + }, + toEdge: function toEdge() { + var swiper = this; + if (!swiper.params.a11y.enabled) { return; } + swiper.a11y.updateNavigation(); + }, + fromEdge: function fromEdge() { + var swiper = this; + if (!swiper.params.a11y.enabled) { return; } + swiper.a11y.updateNavigation(); + }, + paginationUpdate: function paginationUpdate() { + var swiper = this; + if (!swiper.params.a11y.enabled) { return; } + swiper.a11y.updatePagination(); + }, + destroy: function destroy() { + var swiper = this; + if (!swiper.params.a11y.enabled) { return; } + swiper.a11y.destroy(); + }, + }, + }; + + var History = { + init: function init() { + var swiper = this; + if (!swiper.params.history) { return; } + if (!win.history || !win.history.pushState) { + swiper.params.history.enabled = false; + swiper.params.hashNavigation.enabled = true; + return; + } + var history = swiper.history; + history.initialized = true; + history.paths = History.getPathValues(); + if (!history.paths.key && !history.paths.value) { return; } + history.scrollToSlide(0, history.paths.value, swiper.params.runCallbacksOnInit); + if (!swiper.params.history.replaceState) { + win.addEventListener('popstate', swiper.history.setHistoryPopState); + } + }, + destroy: function destroy() { + var swiper = this; + if (!swiper.params.history.replaceState) { + win.removeEventListener('popstate', swiper.history.setHistoryPopState); + } + }, + setHistoryPopState: function setHistoryPopState() { + var swiper = this; + swiper.history.paths = History.getPathValues(); + swiper.history.scrollToSlide(swiper.params.speed, swiper.history.paths.value, false); + }, + getPathValues: function getPathValues() { + var pathArray = win.location.pathname.slice(1).split('/').filter(function (part) { return part !== ''; }); + var total = pathArray.length; + var key = pathArray[total - 2]; + var value = pathArray[total - 1]; + return { key: key, value: value }; + }, + setHistory: function setHistory(key, index) { + var swiper = this; + if (!swiper.history.initialized || !swiper.params.history.enabled) { return; } + var slide = swiper.slides.eq(index); + var value = History.slugify(slide.attr('data-history')); + if (!win.location.pathname.includes(key)) { + value = key + "/" + value; + } + var currentState = win.history.state; + if (currentState && currentState.value === value) { + return; + } + if (swiper.params.history.replaceState) { + win.history.replaceState({ value: value }, null, value); + } else { + win.history.pushState({ value: value }, null, value); + } + }, + slugify: function slugify(text) { + return text.toString() + .replace(/\s+/g, '-') + .replace(/[^\w-]+/g, '') + .replace(/--+/g, '-') + .replace(/^-+/, '') + .replace(/-+$/, ''); + }, + scrollToSlide: function scrollToSlide(speed, value, runCallbacks) { + var swiper = this; + if (value) { + for (var i = 0, length = swiper.slides.length; i < length; i += 1) { + var slide = swiper.slides.eq(i); + var slideHistory = History.slugify(slide.attr('data-history')); + if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) { + var index = slide.index(); + swiper.slideTo(index, speed, runCallbacks); + } + } + } else { + swiper.slideTo(0, speed, runCallbacks); + } + }, + }; + + var History$1 = { + name: 'history', + params: { + history: { + enabled: false, + replaceState: false, + key: 'slides', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + history: { + init: History.init.bind(swiper), + setHistory: History.setHistory.bind(swiper), + setHistoryPopState: History.setHistoryPopState.bind(swiper), + scrollToSlide: History.scrollToSlide.bind(swiper), + destroy: History.destroy.bind(swiper), + }, + }); + }, + on: { + init: function init() { + var swiper = this; + if (swiper.params.history.enabled) { + swiper.history.init(); + } + }, + destroy: function destroy() { + var swiper = this; + if (swiper.params.history.enabled) { + swiper.history.destroy(); + } + }, + transitionEnd: function transitionEnd() { + var swiper = this; + if (swiper.history.initialized) { + swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex); + } + }, + }, + }; + + var HashNavigation = { + onHashCange: function onHashCange() { + var swiper = this; + var newHash = doc.location.hash.replace('#', ''); + var activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash'); + if (newHash !== activeSlideHash) { + var newIndex = swiper.$wrapperEl.children(("." + (swiper.params.slideClass) + "[data-hash=\"" + newHash + "\"]")).index(); + if (typeof newIndex === 'undefined') { return; } + swiper.slideTo(newIndex); + } + }, + setHash: function setHash() { + var swiper = this; + if (!swiper.hashNavigation.initialized || !swiper.params.hashNavigation.enabled) { return; } + if (swiper.params.hashNavigation.replaceState && win.history && win.history.replaceState) { + win.history.replaceState(null, null, (("#" + (swiper.slides.eq(swiper.activeIndex).attr('data-hash'))) || '')); + } else { + var slide = swiper.slides.eq(swiper.activeIndex); + var hash = slide.attr('data-hash') || slide.attr('data-history'); + doc.location.hash = hash || ''; + } + }, + init: function init() { + var swiper = this; + if (!swiper.params.hashNavigation.enabled || (swiper.params.history && swiper.params.history.enabled)) { return; } + swiper.hashNavigation.initialized = true; + var hash = doc.location.hash.replace('#', ''); + if (hash) { + var speed = 0; + for (var i = 0, length = swiper.slides.length; i < length; i += 1) { + var slide = swiper.slides.eq(i); + var slideHash = slide.attr('data-hash') || slide.attr('data-history'); + if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) { + var index = slide.index(); + swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true); + } + } + } + if (swiper.params.hashNavigation.watchState) { + $(win).on('hashchange', swiper.hashNavigation.onHashCange); + } + }, + destroy: function destroy() { + var swiper = this; + if (swiper.params.hashNavigation.watchState) { + $(win).off('hashchange', swiper.hashNavigation.onHashCange); + } + }, + }; + var HashNavigation$1 = { + name: 'hash-navigation', + params: { + hashNavigation: { + enabled: false, + replaceState: false, + watchState: false, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + hashNavigation: { + initialized: false, + init: HashNavigation.init.bind(swiper), + destroy: HashNavigation.destroy.bind(swiper), + setHash: HashNavigation.setHash.bind(swiper), + onHashCange: HashNavigation.onHashCange.bind(swiper), + }, + }); + }, + on: { + init: function init() { + var swiper = this; + if (swiper.params.hashNavigation.enabled) { + swiper.hashNavigation.init(); + } + }, + destroy: function destroy() { + var swiper = this; + if (swiper.params.hashNavigation.enabled) { + swiper.hashNavigation.destroy(); + } + }, + transitionEnd: function transitionEnd() { + var swiper = this; + if (swiper.hashNavigation.initialized) { + swiper.hashNavigation.setHash(); + } + }, + }, + }; + + /* eslint no-underscore-dangle: "off" */ + + var Autoplay = { + run: function run() { + var swiper = this; + var $activeSlideEl = swiper.slides.eq(swiper.activeIndex); + var delay = swiper.params.autoplay.delay; + if ($activeSlideEl.attr('data-swiper-autoplay')) { + delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay; + } + swiper.autoplay.timeout = Utils.nextTick(function () { + if (swiper.params.autoplay.reverseDirection) { + if (swiper.params.loop) { + swiper.loopFix(); + swiper.slidePrev(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.isBeginning) { + swiper.slidePrev(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.params.autoplay.stopOnLastSlide) { + swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else { + swiper.autoplay.stop(); + } + } else if (swiper.params.loop) { + swiper.loopFix(); + swiper.slideNext(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.isEnd) { + swiper.slideNext(swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else if (!swiper.params.autoplay.stopOnLastSlide) { + swiper.slideTo(0, swiper.params.speed, true, true); + swiper.emit('autoplay'); + } else { + swiper.autoplay.stop(); + } + }, delay); + }, + start: function start() { + var swiper = this; + if (typeof swiper.autoplay.timeout !== 'undefined') { return false; } + if (swiper.autoplay.running) { return false; } + swiper.autoplay.running = true; + swiper.emit('autoplayStart'); + swiper.autoplay.run(); + return true; + }, + stop: function stop() { + var swiper = this; + if (!swiper.autoplay.running) { return false; } + if (typeof swiper.autoplay.timeout === 'undefined') { return false; } + + if (swiper.autoplay.timeout) { + clearTimeout(swiper.autoplay.timeout); + swiper.autoplay.timeout = undefined; + } + swiper.autoplay.running = false; + swiper.emit('autoplayStop'); + return true; + }, + pause: function pause(speed) { + var swiper = this; + if (!swiper.autoplay.running) { return; } + if (swiper.autoplay.paused) { return; } + if (swiper.autoplay.timeout) { clearTimeout(swiper.autoplay.timeout); } + swiper.autoplay.paused = true; + if (speed === 0 || !swiper.params.autoplay.waitForTransition) { + swiper.autoplay.paused = false; + swiper.autoplay.run(); + } else { + swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd); + swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd); + } + }, + }; + + var Autoplay$1 = { + name: 'autoplay', + params: { + autoplay: { + enabled: false, + delay: 3000, + waitForTransition: true, + disableOnInteraction: true, + stopOnLastSlide: false, + reverseDirection: false, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + autoplay: { + running: false, + paused: false, + run: Autoplay.run.bind(swiper), + start: Autoplay.start.bind(swiper), + stop: Autoplay.stop.bind(swiper), + pause: Autoplay.pause.bind(swiper), + onTransitionEnd: function onTransitionEnd(e) { + if (!swiper || swiper.destroyed || !swiper.$wrapperEl) { return; } + if (e.target !== this) { return; } + swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd); + swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd); + swiper.autoplay.paused = false; + if (!swiper.autoplay.running) { + swiper.autoplay.stop(); + } else { + swiper.autoplay.run(); + } + }, + }, + }); + }, + on: { + init: function init() { + var swiper = this; + if (swiper.params.autoplay.enabled) { + swiper.autoplay.start(); + } + }, + beforeTransitionStart: function beforeTransitionStart(speed, internal) { + var swiper = this; + if (swiper.autoplay.running) { + if (internal || !swiper.params.autoplay.disableOnInteraction) { + swiper.autoplay.pause(speed); + } else { + swiper.autoplay.stop(); + } + } + }, + sliderFirstMove: function sliderFirstMove() { + var swiper = this; + if (swiper.autoplay.running) { + if (swiper.params.autoplay.disableOnInteraction) { + swiper.autoplay.stop(); + } else { + swiper.autoplay.pause(); + } + } + }, + destroy: function destroy() { + var swiper = this; + if (swiper.autoplay.running) { + swiper.autoplay.stop(); + } + }, + }, + }; + + var Fade = { + setTranslate: function setTranslate() { + var swiper = this; + var slides = swiper.slides; + for (var i = 0; i < slides.length; i += 1) { + var $slideEl = swiper.slides.eq(i); + var offset = $slideEl[0].swiperSlideOffset; + var tx = -offset; + if (!swiper.params.virtualTranslate) { tx -= swiper.translate; } + var ty = 0; + if (!swiper.isHorizontal()) { + ty = tx; + tx = 0; + } + var slideOpacity = swiper.params.fadeEffect.crossFade + ? Math.max(1 - Math.abs($slideEl[0].progress), 0) + : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0); + $slideEl + .css({ + opacity: slideOpacity, + }) + .transform(("translate3d(" + tx + "px, " + ty + "px, 0px)")); + } + }, + setTransition: function setTransition(duration) { + var swiper = this; + var slides = swiper.slides; + var $wrapperEl = swiper.$wrapperEl; + slides.transition(duration); + if (swiper.params.virtualTranslate && duration !== 0) { + var eventTriggered = false; + slides.transitionEnd(function () { + if (eventTriggered) { return; } + if (!swiper || swiper.destroyed) { return; } + eventTriggered = true; + swiper.animating = false; + var triggerEvents = ['webkitTransitionEnd', 'transitionend']; + for (var i = 0; i < triggerEvents.length; i += 1) { + $wrapperEl.trigger(triggerEvents[i]); + } + }); + } + }, + }; + + var EffectFade = { + name: 'effect-fade', + params: { + fadeEffect: { + crossFade: false, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + fadeEffect: { + setTranslate: Fade.setTranslate.bind(swiper), + setTransition: Fade.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + if (swiper.params.effect !== 'fade') { return; } + swiper.classNames.push(((swiper.params.containerModifierClass) + "fade")); + var overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + spaceBetween: 0, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate: function setTranslate() { + var swiper = this; + if (swiper.params.effect !== 'fade') { return; } + swiper.fadeEffect.setTranslate(); + }, + setTransition: function setTransition(duration) { + var swiper = this; + if (swiper.params.effect !== 'fade') { return; } + swiper.fadeEffect.setTransition(duration); + }, + }, + }; + + var Cube = { + setTranslate: function setTranslate() { + var swiper = this; + var $el = swiper.$el; + var $wrapperEl = swiper.$wrapperEl; + var slides = swiper.slides; + var swiperWidth = swiper.width; + var swiperHeight = swiper.height; + var rtl = swiper.rtlTranslate; + var swiperSize = swiper.size; + var params = swiper.params.cubeEffect; + var isHorizontal = swiper.isHorizontal(); + var isVirtual = swiper.virtual && swiper.params.virtual.enabled; + var wrapperRotate = 0; + var $cubeShadowEl; + if (params.shadow) { + if (isHorizontal) { + $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow'); + if ($cubeShadowEl.length === 0) { + $cubeShadowEl = $('
            '); + $wrapperEl.append($cubeShadowEl); + } + $cubeShadowEl.css({ height: (swiperWidth + "px") }); + } else { + $cubeShadowEl = $el.find('.swiper-cube-shadow'); + if ($cubeShadowEl.length === 0) { + $cubeShadowEl = $('
            '); + $el.append($cubeShadowEl); + } + } + } + for (var i = 0; i < slides.length; i += 1) { + var $slideEl = slides.eq(i); + var slideIndex = i; + if (isVirtual) { + slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10); + } + var slideAngle = slideIndex * 90; + var round = Math.floor(slideAngle / 360); + if (rtl) { + slideAngle = -slideAngle; + round = Math.floor(-slideAngle / 360); + } + var progress = Math.max(Math.min($slideEl[0].progress, 1), -1); + var tx = 0; + var ty = 0; + var tz = 0; + if (slideIndex % 4 === 0) { + tx = -round * 4 * swiperSize; + tz = 0; + } else if ((slideIndex - 1) % 4 === 0) { + tx = 0; + tz = -round * 4 * swiperSize; + } else if ((slideIndex - 2) % 4 === 0) { + tx = swiperSize + (round * 4 * swiperSize); + tz = swiperSize; + } else if ((slideIndex - 3) % 4 === 0) { + tx = -swiperSize; + tz = (3 * swiperSize) + (swiperSize * 4 * round); + } + if (rtl) { + tx = -tx; + } + + if (!isHorizontal) { + ty = tx; + tx = 0; + } + + var transform = "rotateX(" + (isHorizontal ? 0 : -slideAngle) + "deg) rotateY(" + (isHorizontal ? slideAngle : 0) + "deg) translate3d(" + tx + "px, " + ty + "px, " + tz + "px)"; + if (progress <= 1 && progress > -1) { + wrapperRotate = (slideIndex * 90) + (progress * 90); + if (rtl) { wrapperRotate = (-slideIndex * 90) - (progress * 90); } + } + $slideEl.transform(transform); + if (params.slideShadows) { + // Set shadows + var shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + var shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if (shadowBefore.length === 0) { + shadowBefore = $(("
            ")); + $slideEl.append(shadowBefore); + } + if (shadowAfter.length === 0) { + shadowAfter = $(("
            ")); + $slideEl.append(shadowAfter); + } + if (shadowBefore.length) { shadowBefore[0].style.opacity = Math.max(-progress, 0); } + if (shadowAfter.length) { shadowAfter[0].style.opacity = Math.max(progress, 0); } + } + } + $wrapperEl.css({ + '-webkit-transform-origin': ("50% 50% -" + (swiperSize / 2) + "px"), + '-moz-transform-origin': ("50% 50% -" + (swiperSize / 2) + "px"), + '-ms-transform-origin': ("50% 50% -" + (swiperSize / 2) + "px"), + 'transform-origin': ("50% 50% -" + (swiperSize / 2) + "px"), + }); + + if (params.shadow) { + if (isHorizontal) { + $cubeShadowEl.transform(("translate3d(0px, " + ((swiperWidth / 2) + params.shadowOffset) + "px, " + (-swiperWidth / 2) + "px) rotateX(90deg) rotateZ(0deg) scale(" + (params.shadowScale) + ")")); + } else { + var shadowAngle = Math.abs(wrapperRotate) - (Math.floor(Math.abs(wrapperRotate) / 90) * 90); + var multiplier = 1.5 - ( + (Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2) + + (Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2) + ); + var scale1 = params.shadowScale; + var scale2 = params.shadowScale / multiplier; + var offset = params.shadowOffset; + $cubeShadowEl.transform(("scale3d(" + scale1 + ", 1, " + scale2 + ") translate3d(0px, " + ((swiperHeight / 2) + offset) + "px, " + (-swiperHeight / 2 / scale2) + "px) rotateX(-90deg)")); + } + } + var zFactor = (Browser.isSafari || Browser.isUiWebView) ? (-swiperSize / 2) : 0; + $wrapperEl + .transform(("translate3d(0px,0," + zFactor + "px) rotateX(" + (swiper.isHorizontal() ? 0 : wrapperRotate) + "deg) rotateY(" + (swiper.isHorizontal() ? -wrapperRotate : 0) + "deg)")); + }, + setTransition: function setTransition(duration) { + var swiper = this; + var $el = swiper.$el; + var slides = swiper.slides; + slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) { + $el.find('.swiper-cube-shadow').transition(duration); + } + }, + }; + + var EffectCube = { + name: 'effect-cube', + params: { + cubeEffect: { + slideShadows: true, + shadow: true, + shadowOffset: 20, + shadowScale: 0.94, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + cubeEffect: { + setTranslate: Cube.setTranslate.bind(swiper), + setTransition: Cube.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + if (swiper.params.effect !== 'cube') { return; } + swiper.classNames.push(((swiper.params.containerModifierClass) + "cube")); + swiper.classNames.push(((swiper.params.containerModifierClass) + "3d")); + var overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + resistanceRatio: 0, + spaceBetween: 0, + centeredSlides: false, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate: function setTranslate() { + var swiper = this; + if (swiper.params.effect !== 'cube') { return; } + swiper.cubeEffect.setTranslate(); + }, + setTransition: function setTransition(duration) { + var swiper = this; + if (swiper.params.effect !== 'cube') { return; } + swiper.cubeEffect.setTransition(duration); + }, + }, + }; + + var Flip = { + setTranslate: function setTranslate() { + var swiper = this; + var slides = swiper.slides; + var rtl = swiper.rtlTranslate; + for (var i = 0; i < slides.length; i += 1) { + var $slideEl = slides.eq(i); + var progress = $slideEl[0].progress; + if (swiper.params.flipEffect.limitRotation) { + progress = Math.max(Math.min($slideEl[0].progress, 1), -1); + } + var offset = $slideEl[0].swiperSlideOffset; + var rotate = -180 * progress; + var rotateY = rotate; + var rotateX = 0; + var tx = -offset; + var ty = 0; + if (!swiper.isHorizontal()) { + ty = tx; + tx = 0; + rotateX = -rotateY; + rotateY = 0; + } else if (rtl) { + rotateY = -rotateY; + } + + $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length; + + if (swiper.params.flipEffect.slideShadows) { + // Set shadows + var shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + var shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if (shadowBefore.length === 0) { + shadowBefore = $(("
            ")); + $slideEl.append(shadowBefore); + } + if (shadowAfter.length === 0) { + shadowAfter = $(("
            ")); + $slideEl.append(shadowAfter); + } + if (shadowBefore.length) { shadowBefore[0].style.opacity = Math.max(-progress, 0); } + if (shadowAfter.length) { shadowAfter[0].style.opacity = Math.max(progress, 0); } + } + $slideEl + .transform(("translate3d(" + tx + "px, " + ty + "px, 0px) rotateX(" + rotateX + "deg) rotateY(" + rotateY + "deg)")); + } + }, + setTransition: function setTransition(duration) { + var swiper = this; + var slides = swiper.slides; + var activeIndex = swiper.activeIndex; + var $wrapperEl = swiper.$wrapperEl; + slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + if (swiper.params.virtualTranslate && duration !== 0) { + var eventTriggered = false; + // eslint-disable-next-line + slides.eq(activeIndex).transitionEnd(function onTransitionEnd() { + if (eventTriggered) { return; } + if (!swiper || swiper.destroyed) { return; } + // if (!$(this).hasClass(swiper.params.slideActiveClass)) return; + eventTriggered = true; + swiper.animating = false; + var triggerEvents = ['webkitTransitionEnd', 'transitionend']; + for (var i = 0; i < triggerEvents.length; i += 1) { + $wrapperEl.trigger(triggerEvents[i]); + } + }); + } + }, + }; + + var EffectFlip = { + name: 'effect-flip', + params: { + flipEffect: { + slideShadows: true, + limitRotation: true, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + flipEffect: { + setTranslate: Flip.setTranslate.bind(swiper), + setTransition: Flip.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + if (swiper.params.effect !== 'flip') { return; } + swiper.classNames.push(((swiper.params.containerModifierClass) + "flip")); + swiper.classNames.push(((swiper.params.containerModifierClass) + "3d")); + var overwriteParams = { + slidesPerView: 1, + slidesPerColumn: 1, + slidesPerGroup: 1, + watchSlidesProgress: true, + spaceBetween: 0, + virtualTranslate: true, + }; + Utils.extend(swiper.params, overwriteParams); + Utils.extend(swiper.originalParams, overwriteParams); + }, + setTranslate: function setTranslate() { + var swiper = this; + if (swiper.params.effect !== 'flip') { return; } + swiper.flipEffect.setTranslate(); + }, + setTransition: function setTransition(duration) { + var swiper = this; + if (swiper.params.effect !== 'flip') { return; } + swiper.flipEffect.setTransition(duration); + }, + }, + }; + + var Coverflow = { + setTranslate: function setTranslate() { + var swiper = this; + var swiperWidth = swiper.width; + var swiperHeight = swiper.height; + var slides = swiper.slides; + var $wrapperEl = swiper.$wrapperEl; + var slidesSizesGrid = swiper.slidesSizesGrid; + var params = swiper.params.coverflowEffect; + var isHorizontal = swiper.isHorizontal(); + var transform = swiper.translate; + var center = isHorizontal ? -transform + (swiperWidth / 2) : -transform + (swiperHeight / 2); + var rotate = isHorizontal ? params.rotate : -params.rotate; + var translate = params.depth; + // Each slide offset from center + for (var i = 0, length = slides.length; i < length; i += 1) { + var $slideEl = slides.eq(i); + var slideSize = slidesSizesGrid[i]; + var slideOffset = $slideEl[0].swiperSlideOffset; + var offsetMultiplier = ((center - slideOffset - (slideSize / 2)) / slideSize) * params.modifier; + + var rotateY = isHorizontal ? rotate * offsetMultiplier : 0; + var rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; + // var rotateZ = 0 + var translateZ = -translate * Math.abs(offsetMultiplier); + + var translateY = isHorizontal ? 0 : params.stretch * (offsetMultiplier); + var translateX = isHorizontal ? params.stretch * (offsetMultiplier) : 0; + + // Fix for ultra small values + if (Math.abs(translateX) < 0.001) { translateX = 0; } + if (Math.abs(translateY) < 0.001) { translateY = 0; } + if (Math.abs(translateZ) < 0.001) { translateZ = 0; } + if (Math.abs(rotateY) < 0.001) { rotateY = 0; } + if (Math.abs(rotateX) < 0.001) { rotateX = 0; } + + var slideTransform = "translate3d(" + translateX + "px," + translateY + "px," + translateZ + "px) rotateX(" + rotateX + "deg) rotateY(" + rotateY + "deg)"; + + $slideEl.transform(slideTransform); + $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1; + if (params.slideShadows) { + // Set shadows + var $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top'); + var $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom'); + if ($shadowBeforeEl.length === 0) { + $shadowBeforeEl = $(("
            ")); + $slideEl.append($shadowBeforeEl); + } + if ($shadowAfterEl.length === 0) { + $shadowAfterEl = $(("
            ")); + $slideEl.append($shadowAfterEl); + } + if ($shadowBeforeEl.length) { $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0; } + if ($shadowAfterEl.length) { $shadowAfterEl[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0; } + } + } + + // Set correct perspective for IE10 + if (Support.pointerEvents || Support.prefixedPointerEvents) { + var ws = $wrapperEl[0].style; + ws.perspectiveOrigin = center + "px 50%"; + } + }, + setTransition: function setTransition(duration) { + var swiper = this; + swiper.slides + .transition(duration) + .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left') + .transition(duration); + }, + }; + + var EffectCoverflow = { + name: 'effect-coverflow', + params: { + coverflowEffect: { + rotate: 50, + stretch: 0, + depth: 100, + modifier: 1, + slideShadows: true, + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + coverflowEffect: { + setTranslate: Coverflow.setTranslate.bind(swiper), + setTransition: Coverflow.setTransition.bind(swiper), + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + if (swiper.params.effect !== 'coverflow') { return; } + + swiper.classNames.push(((swiper.params.containerModifierClass) + "coverflow")); + swiper.classNames.push(((swiper.params.containerModifierClass) + "3d")); + + swiper.params.watchSlidesProgress = true; + swiper.originalParams.watchSlidesProgress = true; + }, + setTranslate: function setTranslate() { + var swiper = this; + if (swiper.params.effect !== 'coverflow') { return; } + swiper.coverflowEffect.setTranslate(); + }, + setTransition: function setTransition(duration) { + var swiper = this; + if (swiper.params.effect !== 'coverflow') { return; } + swiper.coverflowEffect.setTransition(duration); + }, + }, + }; + + var Thumbs = { + init: function init() { + var swiper = this; + var ref = swiper.params; + var thumbsParams = ref.thumbs; + var SwiperClass = swiper.constructor; + if (thumbsParams.swiper instanceof SwiperClass) { + swiper.thumbs.swiper = thumbsParams.swiper; + Utils.extend(swiper.thumbs.swiper.originalParams, { + watchSlidesProgress: true, + slideToClickedSlide: false, + }); + Utils.extend(swiper.thumbs.swiper.params, { + watchSlidesProgress: true, + slideToClickedSlide: false, + }); + } else if (Utils.isObject(thumbsParams.swiper)) { + swiper.thumbs.swiper = new SwiperClass(Utils.extend({}, thumbsParams.swiper, { + watchSlidesVisibility: true, + watchSlidesProgress: true, + slideToClickedSlide: false, + })); + swiper.thumbs.swiperCreated = true; + } + swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass); + swiper.thumbs.swiper.on('tap', swiper.thumbs.onThumbClick); + }, + onThumbClick: function onThumbClick() { + var swiper = this; + var thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) { return; } + var clickedIndex = thumbsSwiper.clickedIndex; + var clickedSlide = thumbsSwiper.clickedSlide; + if (clickedSlide && $(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) { return; } + if (typeof clickedIndex === 'undefined' || clickedIndex === null) { return; } + var slideToIndex; + if (thumbsSwiper.params.loop) { + slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10); + } else { + slideToIndex = clickedIndex; + } + if (swiper.params.loop) { + var currentIndex = swiper.activeIndex; + if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) { + swiper.loopFix(); + // eslint-disable-next-line + swiper._clientLeft = swiper.$wrapperEl[0].clientLeft; + currentIndex = swiper.activeIndex; + } + var prevIndex = swiper.slides.eq(currentIndex).prevAll(("[data-swiper-slide-index=\"" + slideToIndex + "\"]")).eq(0).index(); + var nextIndex = swiper.slides.eq(currentIndex).nextAll(("[data-swiper-slide-index=\"" + slideToIndex + "\"]")).eq(0).index(); + if (typeof prevIndex === 'undefined') { slideToIndex = nextIndex; } + else if (typeof nextIndex === 'undefined') { slideToIndex = prevIndex; } + else if (nextIndex - currentIndex < currentIndex - prevIndex) { slideToIndex = nextIndex; } + else { slideToIndex = prevIndex; } + } + swiper.slideTo(slideToIndex); + }, + update: function update(initial) { + var swiper = this; + var thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) { return; } + + var slidesPerView = thumbsSwiper.params.slidesPerView === 'auto' + ? thumbsSwiper.slidesPerViewDynamic() + : thumbsSwiper.params.slidesPerView; + + if (swiper.realIndex !== thumbsSwiper.realIndex) { + var currentThumbsIndex = thumbsSwiper.activeIndex; + var newThumbsIndex; + if (thumbsSwiper.params.loop) { + if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) { + thumbsSwiper.loopFix(); + // eslint-disable-next-line + thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft; + currentThumbsIndex = thumbsSwiper.activeIndex; + } + // Find actual thumbs index to slide to + var prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll(("[data-swiper-slide-index=\"" + (swiper.realIndex) + "\"]")).eq(0).index(); + var nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll(("[data-swiper-slide-index=\"" + (swiper.realIndex) + "\"]")).eq(0).index(); + if (typeof prevThumbsIndex === 'undefined') { newThumbsIndex = nextThumbsIndex; } + else if (typeof nextThumbsIndex === 'undefined') { newThumbsIndex = prevThumbsIndex; } + else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) { newThumbsIndex = currentThumbsIndex; } + else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) { newThumbsIndex = nextThumbsIndex; } + else { newThumbsIndex = prevThumbsIndex; } + } else { + newThumbsIndex = swiper.realIndex; + } + if (thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) { + if (thumbsSwiper.params.centeredSlides) { + if (newThumbsIndex > currentThumbsIndex) { + newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1; + } else { + newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1; + } + } else if (newThumbsIndex > currentThumbsIndex) { + newThumbsIndex = newThumbsIndex - slidesPerView + 1; + } + thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined); + } + } + + // Activate thumbs + var thumbsToActivate = 1; + var thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass; + + if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) { + thumbsToActivate = swiper.params.slidesPerView; + } + + thumbsSwiper.slides.removeClass(thumbActiveClass); + if (thumbsSwiper.params.loop) { + for (var i = 0; i < thumbsToActivate; i += 1) { + thumbsSwiper.$wrapperEl.children(("[data-swiper-slide-index=\"" + (swiper.realIndex + i) + "\"]")).addClass(thumbActiveClass); + } + } else { + for (var i$1 = 0; i$1 < thumbsToActivate; i$1 += 1) { + thumbsSwiper.slides.eq(swiper.realIndex + i$1).addClass(thumbActiveClass); + } + } + }, + }; + var Thumbs$1 = { + name: 'thumbs', + params: { + thumbs: { + swiper: null, + slideThumbActiveClass: 'swiper-slide-thumb-active', + thumbsContainerClass: 'swiper-container-thumbs', + }, + }, + create: function create() { + var swiper = this; + Utils.extend(swiper, { + thumbs: { + swiper: null, + init: Thumbs.init.bind(swiper), + update: Thumbs.update.bind(swiper), + onThumbClick: Thumbs.onThumbClick.bind(swiper), + }, + }); + }, + on: { + beforeInit: function beforeInit() { + var swiper = this; + var ref = swiper.params; + var thumbs = ref.thumbs; + if (!thumbs || !thumbs.swiper) { return; } + swiper.thumbs.init(); + swiper.thumbs.update(true); + }, + slideChange: function slideChange() { + var swiper = this; + if (!swiper.thumbs.swiper) { return; } + swiper.thumbs.update(); + }, + update: function update() { + var swiper = this; + if (!swiper.thumbs.swiper) { return; } + swiper.thumbs.update(); + }, + resize: function resize() { + var swiper = this; + if (!swiper.thumbs.swiper) { return; } + swiper.thumbs.update(); + }, + observerUpdate: function observerUpdate() { + var swiper = this; + if (!swiper.thumbs.swiper) { return; } + swiper.thumbs.update(); + }, + setTransition: function setTransition(duration) { + var swiper = this; + var thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) { return; } + thumbsSwiper.setTransition(duration); + }, + beforeDestroy: function beforeDestroy() { + var swiper = this; + var thumbsSwiper = swiper.thumbs.swiper; + if (!thumbsSwiper) { return; } + if (swiper.thumbs.swiperCreated && thumbsSwiper) { + thumbsSwiper.destroy(); + } + }, + }, + }; + + // Swiper Class + + var components = [ + Device$1, + Support$1, + Browser$1, + Resize, + Observer$1, + Virtual$1, + Keyboard$1, + Mousewheel$1, + Navigation$1, + Pagination$1, + Scrollbar$1, + Parallax$1, + Zoom$1, + Lazy$1, + Controller$1, + A11y, + History$1, + HashNavigation$1, + Autoplay$1, + EffectFade, + EffectCube, + EffectFlip, + EffectCoverflow, + Thumbs$1 + ]; + + if (typeof Swiper.use === 'undefined') { + Swiper.use = Swiper.Class.use; + Swiper.installModule = Swiper.Class.installModule; + } + + Swiper.use(components); + + return Swiper; + +})); diff --git a/assets/3rd/swiper/js/swiper.min.js b/assets/3rd/swiper/js/swiper.min.js new file mode 100755 index 00000000..e2b7d5e1 --- /dev/null +++ b/assets/3rd/swiper/js/swiper.min.js @@ -0,0 +1,13 @@ +/** + * Swiper 4.5.0 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * http://www.idangero.us/swiper/ + * + * Copyright 2014-2019 Vladimir Kharlampidi + * + * Released under the MIT License + * + * Released on: February 22, 2019 + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Swiper=t()}(this,function(){"use strict";var f="undefined"==typeof document?{body:{},addEventListener:function(){},removeEventListener:function(){},activeElement:{blur:function(){},nodeName:""},querySelector:function(){return null},querySelectorAll:function(){return[]},getElementById:function(){return null},createEvent:function(){return{initEvent:function(){}}},createElement:function(){return{children:[],childNodes:[],style:{},setAttribute:function(){},getElementsByTagName:function(){return[]}}},location:{hash:""}}:document,J="undefined"==typeof window?{document:f,navigator:{userAgent:""},location:{},history:{},CustomEvent:function(){return this},addEventListener:function(){},removeEventListener:function(){},getComputedStyle:function(){return{getPropertyValue:function(){return""}}},Image:function(){},Date:function(){},screen:{},setTimeout:function(){},clearTimeout:function(){}}:window,l=function(e){for(var t=0;t")){var o="div";for(0===n.indexOf(":~]/)?(t||f).querySelectorAll(e.trim()):[f.getElementById(e.trim().split("#")[1])],i=0;ia.slides.length)break;i.push(a.slides.eq(r)[0])}else i.push(a.slides.eq(a.activeIndex)[0]);for(t=0;t=t.size)&&(t.visibleSlides.push(o),t.visibleSlidesIndexes.push(n),i.eq(n).addClass(a.slideVisibleClass))}o.progress=s?-l:l}t.visibleSlides=L(t.visibleSlides)}},updateProgress:function(e){void 0===e&&(e=this&&this.translate||0);var t=this,a=t.params,i=t.maxTranslate()-t.minTranslate(),s=t.progress,r=t.isBeginning,n=t.isEnd,o=r,l=n;0===i?n=r=!(s=0):(r=(s=(e-t.minTranslate())/i)<=0,n=1<=s),ee.extend(t,{progress:s,isBeginning:r,isEnd:n}),(a.watchSlidesProgress||a.watchSlidesVisibility)&&t.updateSlidesProgress(e),r&&!o&&t.emit("reachBeginning toEdge"),n&&!l&&t.emit("reachEnd toEdge"),(o&&!r||l&&!n)&&t.emit("fromEdge"),t.emit("progress",s)},updateSlidesClasses:function(){var e,t=this,a=t.slides,i=t.params,s=t.$wrapperEl,r=t.activeIndex,n=t.realIndex,o=t.virtual&&i.virtual.enabled;a.removeClass(i.slideActiveClass+" "+i.slideNextClass+" "+i.slidePrevClass+" "+i.slideDuplicateActiveClass+" "+i.slideDuplicateNextClass+" "+i.slideDuplicatePrevClass),(e=o?t.$wrapperEl.find("."+i.slideClass+'[data-swiper-slide-index="'+r+'"]'):a.eq(r)).addClass(i.slideActiveClass),i.loop&&(e.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+n+'"]').addClass(i.slideDuplicateActiveClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+n+'"]').addClass(i.slideDuplicateActiveClass));var l=e.nextAll("."+i.slideClass).eq(0).addClass(i.slideNextClass);i.loop&&0===l.length&&(l=a.eq(0)).addClass(i.slideNextClass);var d=e.prevAll("."+i.slideClass).eq(0).addClass(i.slidePrevClass);i.loop&&0===d.length&&(d=a.eq(-1)).addClass(i.slidePrevClass),i.loop&&(l.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+l.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicateNextClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+l.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicateNextClass),d.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+d.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicatePrevClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+d.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicatePrevClass))},updateActiveIndex:function(e){var t,a=this,i=a.rtlTranslate?a.translate:-a.translate,s=a.slidesGrid,r=a.snapGrid,n=a.params,o=a.activeIndex,l=a.realIndex,d=a.snapIndex,p=e;if(void 0===p){for(var c=0;c=s[c]&&i=s[c]&&i=s[c]&&(p=c);n.normalizeSlideIndex&&(p<0||void 0===p)&&(p=0)}if((t=0<=r.indexOf(i)?r.indexOf(i):Math.floor(p/n.slidesPerGroup))>=r.length&&(t=r.length-1),p!==o){var u=parseInt(a.slides.eq(p).attr("data-swiper-slide-index")||p,10);ee.extend(a,{snapIndex:t,realIndex:u,previousIndex:o,activeIndex:p}),a.emit("activeIndexChange"),a.emit("snapIndexChange"),l!==u&&a.emit("realIndexChange"),a.emit("slideChange")}else t!==d&&(a.snapIndex=t,a.emit("snapIndexChange"))},updateClickedSlide:function(e){var t=this,a=t.params,i=L(e.target).closest("."+a.slideClass)[0],s=!1;if(i)for(var r=0;r=o.length&&(u=o.length-1),(p||n.initialSlide||0)===(d||0)&&a&&s.emit("beforeSlideChangeStart");var h,v=-o[u];if(s.updateProgress(v),n.normalizeSlideIndex)for(var f=0;f=Math.floor(100*l[f])&&(r=f);if(s.initialized&&r!==p){if(!s.allowSlideNext&&vs.translate&&v>s.maxTranslate()&&(p||0)!==r)return!1}return h=pt.slides.length-t.loopedSlides+s/2?(t.loopFix(),r=i.children("."+a.slideClass+'[data-swiper-slide-index="'+e+'"]:not(.'+a.slideDuplicateClass+")").eq(0).index(),ee.nextTick(function(){t.slideTo(r)})):t.slideTo(r):r>t.slides.length-s?(t.loopFix(),r=i.children("."+a.slideClass+'[data-swiper-slide-index="'+e+'"]:not(.'+a.slideDuplicateClass+")").eq(0).index(),ee.nextTick(function(){t.slideTo(r)})):t.slideTo(r)}else t.slideTo(r)}};var h={loopCreate:function(){var i=this,e=i.params,t=i.$wrapperEl;t.children("."+e.slideClass+"."+e.slideDuplicateClass).remove();var s=t.children("."+e.slideClass);if(e.loopFillGroupWithBlank){var a=e.slidesPerGroup-s.length%e.slidesPerGroup;if(a!==e.slidesPerGroup){for(var r=0;rs.length&&(i.loopedSlides=s.length);var o=[],l=[];s.each(function(e,t){var a=L(t);e=s.length-i.loopedSlides&&o.push(t),a.attr("data-swiper-slide-index",e)});for(var d=0;d=s.length-r)&&(e=-s.length+i+r,e+=r,t.slideTo(e,0,!1,!0)&&0!==p&&t.setTranslate((d?-t.translate:t.translate)-p));t.allowSlidePrev=n,t.allowSlideNext=o},loopDestroy:function(){var e=this.$wrapperEl,t=this.params,a=this.slides;e.children("."+t.slideClass+"."+t.slideDuplicateClass+",."+t.slideClass+"."+t.slideBlankClass).remove(),a.removeAttr("data-swiper-slide-index")}};var v={setGrabCursor:function(e){if(!(te.touch||!this.params.simulateTouch||this.params.watchOverflow&&this.isLocked)){var t=this.el;t.style.cursor="move",t.style.cursor=e?"-webkit-grabbing":"-webkit-grab",t.style.cursor=e?"-moz-grabbin":"-moz-grab",t.style.cursor=e?"grabbing":"grab"}},unsetGrabCursor:function(){te.touch||this.params.watchOverflow&&this.isLocked||(this.el.style.cursor="")}};var m={appendSlide:function(e){var t=this,a=t.$wrapperEl,i=t.params;if(i.loop&&t.loopDestroy(),"object"==typeof e&&"length"in e)for(var s=0;s=J.screen.width-d)){if(ee.extend(a,{isTouched:!0,isMoved:!1,allowTouchCallbacks:!0,isScrolling:void 0,startMoving:void 0}),s.startX=n,s.startY=o,a.touchStartTime=ee.now(),t.allowClick=!0,t.updateSize(),t.swipeDirection=void 0,0s.startY&&t.translate>=t.minTranslate())return a.isTouched=!1,void(a.isMoved=!1)}else if(os.startX&&t.translate>=t.minTranslate())return;if(a.isTouchEvent&&f.activeElement&&n.target===f.activeElement&&L(n.target).is(a.formElements))return a.isMoved=!0,void(t.allowClick=!1);if(a.allowTouchCallbacks&&t.emit("touchMove",n),!(n.targetTouches&&1i.touchAngle:90-d>i.touchAngle)),a.isScrolling&&t.emit("touchMoveOpposite",n),void 0===a.startMoving&&(s.currentX===s.startX&&s.currentY===s.startY||(a.startMoving=!0)),a.isScrolling)a.isTouched=!1;else if(a.startMoving){t.allowClick=!1,n.preventDefault(),i.touchMoveStopPropagation&&!i.nested&&n.stopPropagation(),a.isMoved||(i.loop&&t.loopFix(),a.startTranslate=t.getTranslate(),t.setTransition(0),t.animating&&t.$wrapperEl.trigger("webkitTransitionEnd transitionend"),a.allowMomentumBounce=!1,!i.grabCursor||!0!==t.allowSlideNext&&!0!==t.allowSlidePrev||t.setGrabCursor(!0),t.emit("sliderFirstMove",n)),t.emit("sliderMove",n),a.isMoved=!0;var u=t.isHorizontal()?p:c;s.diff=u,u*=i.touchRatio,r&&(u=-u),t.swipeDirection=0t.minTranslate()?(h=!1,i.resistance&&(a.currentTranslate=t.minTranslate()-1+Math.pow(-t.minTranslate()+a.startTranslate+u,v))):u<0&&a.currentTranslatea.startTranslate&&(a.currentTranslate=a.startTranslate),0i.threshold||a.allowThresholdMove))return void(a.currentTranslate=a.startTranslate);if(!a.allowThresholdMove)return a.allowThresholdMove=!0,s.startX=s.currentX,s.startY=s.currentY,a.currentTranslate=a.startTranslate,void(s.diff=t.isHorizontal()?s.currentX-s.startX:s.currentY-s.startY)}i.followFinger&&((i.freeMode||i.watchSlidesProgress||i.watchSlidesVisibility)&&(t.updateActiveIndex(),t.updateSlidesClasses()),i.freeMode&&(0===a.velocities.length&&a.velocities.push({position:s[t.isHorizontal()?"startX":"startY"],time:a.touchStartTime}),a.velocities.push({position:s[t.isHorizontal()?"currentX":"currentY"],time:ee.now()})),t.updateProgress(a.currentTranslate),t.setTranslate(a.currentTranslate))}}}}else a.startMoving&&a.isScrolling&&t.emit("touchMoveOpposite",n)}.bind(e),e.onTouchEnd=function(e){var t=this,a=t.touchEventsData,i=t.params,s=t.touches,r=t.rtlTranslate,n=t.$wrapperEl,o=t.slidesGrid,l=t.snapGrid,d=e;if(d.originalEvent&&(d=d.originalEvent),a.allowTouchCallbacks&&t.emit("touchEnd",d),a.allowTouchCallbacks=!1,!a.isTouched)return a.isMoved&&i.grabCursor&&t.setGrabCursor(!1),a.isMoved=!1,void(a.startMoving=!1);i.grabCursor&&a.isMoved&&a.isTouched&&(!0===t.allowSlideNext||!0===t.allowSlidePrev)&&t.setGrabCursor(!1);var p,c=ee.now(),u=c-a.touchStartTime;if(t.allowClick&&(t.updateClickedSlide(d),t.emit("tap",d),u<300&&300-t.maxTranslate())return void(t.slides.lengtht.minTranslate())i.freeModeMomentumBounce?(w-t.minTranslate()>E&&(w=t.minTranslate()+E),y=t.minTranslate(),T=!0,a.allowMomentumBounce=!0):w=t.minTranslate(),i.loop&&i.centeredSlides&&(x=!0);else if(i.freeModeSticky){for(var S,C=0;C-w){S=C;break}w=-(w=Math.abs(l[S]-w)=i.longSwipesMs)&&(t.updateProgress(),t.updateActiveIndex(),t.updateSlidesClasses())}else{for(var M=0,z=t.slidesSizesGrid[0],P=0;P=o[P]&&p=o[P]&&(M=P,z=o[o.length-1]-o[o.length-2]);var k=(p-o[M])/z;if(u>i.longSwipesMs){if(!i.longSwipes)return void t.slideTo(t.activeIndex);"next"===t.swipeDirection&&(k>=i.longSwipesRatio?t.slideTo(M+i.slidesPerGroup):t.slideTo(M)),"prev"===t.swipeDirection&&(k>1-i.longSwipesRatio?t.slideTo(M+i.slidesPerGroup):t.slideTo(M))}else{if(!i.shortSwipes)return void t.slideTo(t.activeIndex);"next"===t.swipeDirection&&t.slideTo(M+i.slidesPerGroup),"prev"===t.swipeDirection&&t.slideTo(M)}}}.bind(e),e.onClick=function(e){this.allowClick||(this.params.preventClicks&&e.preventDefault(),this.params.preventClicksPropagation&&this.animating&&(e.stopPropagation(),e.stopImmediatePropagation()))}.bind(e);var r="container"===t.touchEventsTarget?i:s,n=!!t.nested;if(te.touch||!te.pointerEvents&&!te.prefixedPointerEvents){if(te.touch){var o=!("touchstart"!==a.start||!te.passiveListener||!t.passiveListeners)&&{passive:!0,capture:!1};r.addEventListener(a.start,e.onTouchStart,o),r.addEventListener(a.move,e.onTouchMove,te.passiveListener?{passive:!1,capture:n}:n),r.addEventListener(a.end,e.onTouchEnd,o)}(t.simulateTouch&&!g.ios&&!g.android||t.simulateTouch&&!te.touch&&g.ios)&&(r.addEventListener("mousedown",e.onTouchStart,!1),f.addEventListener("mousemove",e.onTouchMove,n),f.addEventListener("mouseup",e.onTouchEnd,!1))}else r.addEventListener(a.start,e.onTouchStart,!1),f.addEventListener(a.move,e.onTouchMove,n),f.addEventListener(a.end,e.onTouchEnd,!1);(t.preventClicks||t.preventClicksPropagation)&&r.addEventListener("click",e.onClick,!0),e.on(g.ios||g.android?"resize orientationchange observerUpdate":"resize observerUpdate",b,!0)},detachEvents:function(){var e=this,t=e.params,a=e.touchEvents,i=e.el,s=e.wrapperEl,r="container"===t.touchEventsTarget?i:s,n=!!t.nested;if(te.touch||!te.pointerEvents&&!te.prefixedPointerEvents){if(te.touch){var o=!("onTouchStart"!==a.start||!te.passiveListener||!t.passiveListeners)&&{passive:!0,capture:!1};r.removeEventListener(a.start,e.onTouchStart,o),r.removeEventListener(a.move,e.onTouchMove,n),r.removeEventListener(a.end,e.onTouchEnd,o)}(t.simulateTouch&&!g.ios&&!g.android||t.simulateTouch&&!te.touch&&g.ios)&&(r.removeEventListener("mousedown",e.onTouchStart,!1),f.removeEventListener("mousemove",e.onTouchMove,n),f.removeEventListener("mouseup",e.onTouchEnd,!1))}else r.removeEventListener(a.start,e.onTouchStart,!1),f.removeEventListener(a.move,e.onTouchMove,n),f.removeEventListener(a.end,e.onTouchEnd,!1);(t.preventClicks||t.preventClicksPropagation)&&r.removeEventListener("click",e.onClick,!0),e.off(g.ios||g.android?"resize orientationchange observerUpdate":"resize observerUpdate",b)}},breakpoints:{setBreakpoint:function(){var e=this,t=e.activeIndex,a=e.initialized,i=e.loopedSlides;void 0===i&&(i=0);var s=e.params,r=s.breakpoints;if(r&&(!r||0!==Object.keys(r).length)){var n=e.getBreakpoint(r);if(n&&e.currentBreakpoint!==n){var o=n in r?r[n]:void 0;o&&["slidesPerView","spaceBetween","slidesPerGroup"].forEach(function(e){var t=o[e];void 0!==t&&(o[e]="slidesPerView"!==e||"AUTO"!==t&&"auto"!==t?"slidesPerView"===e?parseFloat(t):parseInt(t,10):"auto")});var l=o||e.originalParams,d=l.direction&&l.direction!==s.direction,p=s.loop&&(l.slidesPerView!==s.slidesPerView||d);d&&a&&e.changeDirection(),ee.extend(e.params,l),ee.extend(e,{allowTouchMove:e.params.allowTouchMove,allowSlideNext:e.params.allowSlideNext,allowSlidePrev:e.params.allowSlidePrev}),e.currentBreakpoint=n,p&&a&&(e.loopDestroy(),e.loopCreate(),e.updateSlides(),e.slideTo(t-i+e.loopedSlides,0,!1)),e.emit("breakpoint",l)}}},getBreakpoint:function(e){if(e){var t=!1,a=[];Object.keys(e).forEach(function(e){a.push(e)}),a.sort(function(e,t){return parseInt(e,10)-parseInt(t,10)});for(var i=0;i=J.innerWidth&&!t&&(t=s)}return t||"max"}}},checkOverflow:{checkOverflow:function(){var e=this,t=e.isLocked;e.isLocked=1===e.snapGrid.length,e.allowSlideNext=!e.isLocked,e.allowSlidePrev=!e.isLocked,t!==e.isLocked&&e.emit(e.isLocked?"lock":"unlock"),t&&t!==e.isLocked&&(e.isEnd=!1,e.navigation.update())}},classes:{addClasses:function(){var t=this.classNames,a=this.params,e=this.rtl,i=this.$el,s=[];s.push("initialized"),s.push(a.direction),a.freeMode&&s.push("free-mode"),te.flexbox||s.push("no-flexbox"),a.autoHeight&&s.push("autoheight"),e&&s.push("rtl"),1'+e+"
            ");return s.attr("data-swiper-slide-index")||s.attr("data-swiper-slide-index",t),i.cache&&(a.virtual.cache[t]=s),s},appendSlide:function(e){if("object"==typeof e&&"length"in e)for(var t=0;tMath.abs(n.pixelY)))return!0;s=n.pixelX*r}else{if(!(Math.abs(n.pixelY)>Math.abs(n.pixelX)))return!0;s=n.pixelY}else s=Math.abs(n.pixelX)>Math.abs(n.pixelY)?-n.pixelX*r:-n.pixelY;if(0===s)return!0;if(i.invert&&(s=-s),a.params.freeMode){a.params.loop&&a.loopFix();var o=a.getTranslate()+s*i.sensitivity,l=a.isBeginning,d=a.isEnd;if(o>=a.minTranslate()&&(o=a.minTranslate()),o<=a.maxTranslate()&&(o=a.maxTranslate()),a.setTransition(0),a.setTranslate(o),a.updateProgress(),a.updateActiveIndex(),a.updateSlidesClasses(),(!l&&a.isBeginning||!d&&a.isEnd)&&a.updateSlidesClasses(),a.params.freeModeSticky&&(clearTimeout(a.mousewheel.timeout),a.mousewheel.timeout=ee.nextTick(function(){a.slideToClosest()},300)),a.emit("scroll",t),a.params.autoplay&&a.params.autoplayDisableOnInteraction&&a.autoplay.stop(),o===a.minTranslate()||o===a.maxTranslate())return!0}else{if(60a-1-2*e.loopedSlides&&(r-=a-2*e.loopedSlides),n-1s.dynamicMainBullets-1?e.pagination.dynamicBulletIndex=s.dynamicMainBullets-1:e.pagination.dynamicBulletIndex<0&&(e.pagination.dynamicBulletIndex=0)),o=r-e.pagination.dynamicBulletIndex,d=((l=o+(Math.min(p.length,s.dynamicMainBullets)-1))+o)/2),p.removeClass(s.bulletActiveClass+" "+s.bulletActiveClass+"-next "+s.bulletActiveClass+"-next-next "+s.bulletActiveClass+"-prev "+s.bulletActiveClass+"-prev-prev "+s.bulletActiveClass+"-main"),1";i.html(s),e.pagination.bullets=i.find("."+t.bulletClass)}"fraction"===t.type&&(s=t.renderFraction?t.renderFraction.call(e,t.currentClass,t.totalClass):' / ',i.html(s)),"progressbar"===t.type&&(s=t.renderProgressbar?t.renderProgressbar.call(e,t.progressbarFillClass):'',i.html(s)),"custom"!==t.type&&e.emit("paginationRender",e.pagination.$el[0])}},init:function(){var a=this,e=a.params.pagination;if(e.el){var t=L(e.el);0!==t.length&&(a.params.uniqueNavElements&&"string"==typeof e.el&&1'),s.append(r)),ee.extend(t,{$el:s,el:s[0],$dragEl:r,dragEl:r[0]}),i.draggable&&t.enableDraggable()}},destroy:function(){this.scrollbar.disableDraggable()}},B={setTransform:function(e,t){var a=this.rtl,i=L(e),s=a?-1:1,r=i.attr("data-swiper-parallax")||"0",n=i.attr("data-swiper-parallax-x"),o=i.attr("data-swiper-parallax-y"),l=i.attr("data-swiper-parallax-scale"),d=i.attr("data-swiper-parallax-opacity");if(n||o?(n=n||"0",o=o||"0"):this.isHorizontal()?(n=r,o="0"):(o=r,n="0"),n=0<=n.indexOf("%")?parseInt(n,10)*t*s+"%":n*t*s+"px",o=0<=o.indexOf("%")?parseInt(o,10)*t+"%":o*t+"px",null!=d){var p=d-(d-1)*(1-Math.abs(t));i[0].style.opacity=p}if(null==l)i.transform("translate3d("+n+", "+o+", 0px)");else{var c=l-(l-1)*(1-Math.abs(t));i.transform("translate3d("+n+", "+o+", 0px) scale("+c+")")}},setTranslate:function(){var i=this,e=i.$el,t=i.slides,s=i.progress,r=i.snapGrid;e.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(e,t){i.parallax.setTransform(t,s)}),t.each(function(e,t){var a=t.progress;1i.maxRatio&&(a.scale=i.maxRatio-1+Math.pow(a.scale-i.maxRatio+1,.5)),a.scales.touchesStart.x))return void(s.isTouched=!1);if(!t.isHorizontal()&&(Math.floor(s.minY)===Math.floor(s.startY)&&s.touchesCurrent.ys.touchesStart.y))return void(s.isTouched=!1)}e.preventDefault(),e.stopPropagation(),s.isMoved=!0,s.currentX=s.touchesCurrent.x-s.touchesStart.x+s.startX,s.currentY=s.touchesCurrent.y-s.touchesStart.y+s.startY,s.currentXs.maxX&&(s.currentX=s.maxX-1+Math.pow(s.currentX-s.maxX+1,.8)),s.currentYs.maxY&&(s.currentY=s.maxY-1+Math.pow(s.currentY-s.maxY+1,.8)),r.prevPositionX||(r.prevPositionX=s.touchesCurrent.x),r.prevPositionY||(r.prevPositionY=s.touchesCurrent.y),r.prevTime||(r.prevTime=Date.now()),r.x=(s.touchesCurrent.x-r.prevPositionX)/(Date.now()-r.prevTime)/2,r.y=(s.touchesCurrent.y-r.prevPositionY)/(Date.now()-r.prevTime)/2,Math.abs(s.touchesCurrent.x-r.prevPositionX)<2&&(r.x=0),Math.abs(s.touchesCurrent.y-r.prevPositionY)<2&&(r.y=0),r.prevPositionX=s.touchesCurrent.x,r.prevPositionY=s.touchesCurrent.y,r.prevTime=Date.now(),i.$imageWrapEl.transform("translate3d("+s.currentX+"px, "+s.currentY+"px,0)")}}},onTouchEnd:function(){var e=this.zoom,t=e.gesture,a=e.image,i=e.velocity;if(t.$imageEl&&0!==t.$imageEl.length){if(!a.isTouched||!a.isMoved)return a.isTouched=!1,void(a.isMoved=!1);a.isTouched=!1,a.isMoved=!1;var s=300,r=300,n=i.x*s,o=a.currentX+n,l=i.y*r,d=a.currentY+l;0!==i.x&&(s=Math.abs((o-a.currentX)/i.x)),0!==i.y&&(r=Math.abs((d-a.currentY)/i.y));var p=Math.max(s,r);a.currentX=o,a.currentY=d;var c=a.width*e.scale,u=a.height*e.scale;a.minX=Math.min(t.slideWidth/2-c/2,0),a.maxX=-a.minX,a.minY=Math.min(t.slideHeight/2-u/2,0),a.maxY=-a.minY,a.currentX=Math.max(Math.min(a.currentX,a.maxX),a.minX),a.currentY=Math.max(Math.min(a.currentY,a.maxY),a.minY),t.$imageWrapEl.transition(p).transform("translate3d("+a.currentX+"px, "+a.currentY+"px,0)")}},onTransitionEnd:function(){var e=this.zoom,t=e.gesture;t.$slideEl&&this.previousIndex!==this.activeIndex&&(t.$imageEl.transform("translate3d(0,0,0) scale(1)"),t.$imageWrapEl.transform("translate3d(0,0,0)"),e.scale=1,e.currentScale=1,t.$slideEl=void 0,t.$imageEl=void 0,t.$imageWrapEl=void 0)},toggle:function(e){var t=this.zoom;t.scale&&1!==t.scale?t.out():t.in(e)},in:function(e){var t,a,i,s,r,n,o,l,d,p,c,u,h,v,f,m,g=this,b=g.zoom,w=g.params.zoom,y=b.gesture,x=b.image;(y.$slideEl||(y.$slideEl=g.clickedSlide?L(g.clickedSlide):g.slides.eq(g.activeIndex),y.$imageEl=y.$slideEl.find("img, svg, canvas"),y.$imageWrapEl=y.$imageEl.parent("."+w.containerClass)),y.$imageEl&&0!==y.$imageEl.length)&&(y.$slideEl.addClass(""+w.zoomedSlideClass),void 0===x.touchesStart.x&&e?(t="touchend"===e.type?e.changedTouches[0].pageX:e.pageX,a="touchend"===e.type?e.changedTouches[0].pageY:e.pageY):(t=x.touchesStart.x,a=x.touchesStart.y),b.scale=y.$imageWrapEl.attr("data-swiper-zoom")||w.maxRatio,b.currentScale=y.$imageWrapEl.attr("data-swiper-zoom")||w.maxRatio,e?(f=y.$slideEl[0].offsetWidth,m=y.$slideEl[0].offsetHeight,i=y.$slideEl.offset().left+f/2-t,s=y.$slideEl.offset().top+m/2-a,o=y.$imageEl[0].offsetWidth,l=y.$imageEl[0].offsetHeight,d=o*b.scale,p=l*b.scale,h=-(c=Math.min(f/2-d/2,0)),v=-(u=Math.min(m/2-p/2,0)),(r=i*b.scale)>1]<=t?i=s:a=s;return a};return this.x=e,this.y=t,this.lastIndex=e.length-1,this.interpolate=function(e){return e?(n=o(this.x,e),r=n-1,(e-this.x[r])*(this.y[n]-this.y[r])/(this.x[n]-this.x[r])+this.y[r]):0},this},getInterpolateFunction:function(e){var t=this;t.controller.spline||(t.controller.spline=t.params.loop?new V.LinearSpline(t.slidesGrid,e.slidesGrid):new V.LinearSpline(t.snapGrid,e.snapGrid))},setTranslate:function(e,t){var a,i,s=this,r=s.controller.control;function n(e){var t=s.rtlTranslate?-s.translate:s.translate;"slide"===s.params.controller.by&&(s.controller.getInterpolateFunction(e),i=-s.controller.spline.interpolate(-t)),i&&"container"!==s.params.controller.by||(a=(e.maxTranslate()-e.minTranslate())/(s.maxTranslate()-s.minTranslate()),i=(t-s.minTranslate())*a+e.minTranslate()),s.params.controller.inverse&&(i=e.maxTranslate()-i),e.updateProgress(i),e.setTranslate(i,s),e.updateActiveIndex(),e.updateSlidesClasses()}if(Array.isArray(r))for(var o=0;o'),i.append(e)),e.css({height:r+"px"})):0===(e=a.find(".swiper-cube-shadow")).length&&(e=L('
            '),a.append(e)));for(var h=0;h'),v.append(E)),0===S.length&&(S=L('
            '),v.append(S)),E.length&&(E[0].style.opacity=Math.max(-b,0)),S.length&&(S[0].style.opacity=Math.max(b,0))}}if(i.css({"-webkit-transform-origin":"50% 50% -"+l/2+"px","-moz-transform-origin":"50% 50% -"+l/2+"px","-ms-transform-origin":"50% 50% -"+l/2+"px","transform-origin":"50% 50% -"+l/2+"px"}),d.shadow)if(p)e.transform("translate3d(0px, "+(r/2+d.shadowOffset)+"px, "+-r/2+"px) rotateX(90deg) rotateZ(0deg) scale("+d.shadowScale+")");else{var C=Math.abs(u)-90*Math.floor(Math.abs(u)/90),M=1.5-(Math.sin(2*C*Math.PI/360)/2+Math.cos(2*C*Math.PI/360)/2),z=d.shadowScale,P=d.shadowScale/M,k=d.shadowOffset;e.transform("scale3d("+z+", 1, "+P+") translate3d(0px, "+(n/2+k)+"px, "+-n/2/P+"px) rotateX(-90deg)")}var $=I.isSafari||I.isUiWebView?-l/2:0;i.transform("translate3d(0px,0,"+$+"px) rotateX("+(t.isHorizontal()?0:u)+"deg) rotateY("+(t.isHorizontal()?-u:0)+"deg)")},setTransition:function(e){var t=this.$el;this.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),this.params.cubeEffect.shadow&&!this.isHorizontal()&&t.find(".swiper-cube-shadow").transition(e)}},K={setTranslate:function(){for(var e=this,t=e.slides,a=e.rtlTranslate,i=0;i'),s.append(p)),0===c.length&&(c=L('
            '),s.append(c)),p.length&&(p[0].style.opacity=Math.max(-r,0)),c.length&&(c[0].style.opacity=Math.max(r,0))}s.transform("translate3d("+l+"px, "+d+"px, 0px) rotateX("+o+"deg) rotateY("+n+"deg)")}},setTransition:function(e){var a=this,t=a.slides,i=a.activeIndex,s=a.$wrapperEl;if(t.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),a.params.virtualTranslate&&0!==e){var r=!1;t.eq(i).transitionEnd(function(){if(!r&&a&&!a.destroyed){r=!0,a.animating=!1;for(var e=["webkitTransitionEnd","transitionend"],t=0;t'),v.append(E)),0===S.length&&(S=L('
            '),v.append(S)),E.length&&(E[0].style.opacity=0')}}),Object.keys(F).forEach(function(e){t.a11y[e]=F[e].bind(t)})},on:{init:function(){this.params.a11y.enabled&&(this.a11y.init(),this.a11y.updateNavigation())},toEdge:function(){this.params.a11y.enabled&&this.a11y.updateNavigation()},fromEdge:function(){this.params.a11y.enabled&&this.a11y.updateNavigation()},paginationUpdate:function(){this.params.a11y.enabled&&this.a11y.updatePagination()},destroy:function(){this.params.a11y.enabled&&this.a11y.destroy()}}},{name:"history",params:{history:{enabled:!1,replaceState:!1,key:"slides"}},create:function(){var e=this;ee.extend(e,{history:{init:R.init.bind(e),setHistory:R.setHistory.bind(e),setHistoryPopState:R.setHistoryPopState.bind(e),scrollToSlide:R.scrollToSlide.bind(e),destroy:R.destroy.bind(e)}})},on:{init:function(){this.params.history.enabled&&this.history.init()},destroy:function(){this.params.history.enabled&&this.history.destroy()},transitionEnd:function(){this.history.initialized&&this.history.setHistory(this.params.history.key,this.activeIndex)}}},{name:"hash-navigation",params:{hashNavigation:{enabled:!1,replaceState:!1,watchState:!1}},create:function(){var e=this;ee.extend(e,{hashNavigation:{initialized:!1,init:q.init.bind(e),destroy:q.destroy.bind(e),setHash:q.setHash.bind(e),onHashCange:q.onHashCange.bind(e)}})},on:{init:function(){this.params.hashNavigation.enabled&&this.hashNavigation.init()},destroy:function(){this.params.hashNavigation.enabled&&this.hashNavigation.destroy()},transitionEnd:function(){this.hashNavigation.initialized&&this.hashNavigation.setHash()}}},{name:"autoplay",params:{autoplay:{enabled:!1,delay:3e3,waitForTransition:!0,disableOnInteraction:!0,stopOnLastSlide:!1,reverseDirection:!1}},create:function(){var t=this;ee.extend(t,{autoplay:{running:!1,paused:!1,run:W.run.bind(t),start:W.start.bind(t),stop:W.stop.bind(t),pause:W.pause.bind(t),onTransitionEnd:function(e){t&&!t.destroyed&&t.$wrapperEl&&e.target===this&&(t.$wrapperEl[0].removeEventListener("transitionend",t.autoplay.onTransitionEnd),t.$wrapperEl[0].removeEventListener("webkitTransitionEnd",t.autoplay.onTransitionEnd),t.autoplay.paused=!1,t.autoplay.running?t.autoplay.run():t.autoplay.stop())}}})},on:{init:function(){this.params.autoplay.enabled&&this.autoplay.start()},beforeTransitionStart:function(e,t){this.autoplay.running&&(t||!this.params.autoplay.disableOnInteraction?this.autoplay.pause(e):this.autoplay.stop())},sliderFirstMove:function(){this.autoplay.running&&(this.params.autoplay.disableOnInteraction?this.autoplay.stop():this.autoplay.pause())},destroy:function(){this.autoplay.running&&this.autoplay.stop()}}},{name:"effect-fade",params:{fadeEffect:{crossFade:!1}},create:function(){ee.extend(this,{fadeEffect:{setTranslate:j.setTranslate.bind(this),setTransition:j.setTransition.bind(this)}})},on:{beforeInit:function(){var e=this;if("fade"===e.params.effect){e.classNames.push(e.params.containerModifierClass+"fade");var t={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!0};ee.extend(e.params,t),ee.extend(e.originalParams,t)}},setTranslate:function(){"fade"===this.params.effect&&this.fadeEffect.setTranslate()},setTransition:function(e){"fade"===this.params.effect&&this.fadeEffect.setTransition(e)}}},{name:"effect-cube",params:{cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94}},create:function(){ee.extend(this,{cubeEffect:{setTranslate:U.setTranslate.bind(this),setTransition:U.setTransition.bind(this)}})},on:{beforeInit:function(){var e=this;if("cube"===e.params.effect){e.classNames.push(e.params.containerModifierClass+"cube"),e.classNames.push(e.params.containerModifierClass+"3d");var t={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,resistanceRatio:0,spaceBetween:0,centeredSlides:!1,virtualTranslate:!0};ee.extend(e.params,t),ee.extend(e.originalParams,t)}},setTranslate:function(){"cube"===this.params.effect&&this.cubeEffect.setTranslate()},setTransition:function(e){"cube"===this.params.effect&&this.cubeEffect.setTransition(e)}}},{name:"effect-flip",params:{flipEffect:{slideShadows:!0,limitRotation:!0}},create:function(){ee.extend(this,{flipEffect:{setTranslate:K.setTranslate.bind(this),setTransition:K.setTransition.bind(this)}})},on:{beforeInit:function(){var e=this;if("flip"===e.params.effect){e.classNames.push(e.params.containerModifierClass+"flip"),e.classNames.push(e.params.containerModifierClass+"3d");var t={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!0};ee.extend(e.params,t),ee.extend(e.originalParams,t)}},setTranslate:function(){"flip"===this.params.effect&&this.flipEffect.setTranslate()},setTransition:function(e){"flip"===this.params.effect&&this.flipEffect.setTransition(e)}}},{name:"effect-coverflow",params:{coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0}},create:function(){ee.extend(this,{coverflowEffect:{setTranslate:_.setTranslate.bind(this),setTransition:_.setTransition.bind(this)}})},on:{beforeInit:function(){var e=this;"coverflow"===e.params.effect&&(e.classNames.push(e.params.containerModifierClass+"coverflow"),e.classNames.push(e.params.containerModifierClass+"3d"),e.params.watchSlidesProgress=!0,e.originalParams.watchSlidesProgress=!0)},setTranslate:function(){"coverflow"===this.params.effect&&this.coverflowEffect.setTranslate()},setTransition:function(e){"coverflow"===this.params.effect&&this.coverflowEffect.setTransition(e)}}},{name:"thumbs",params:{thumbs:{swiper:null,slideThumbActiveClass:"swiper-slide-thumb-active",thumbsContainerClass:"swiper-container-thumbs"}},create:function(){ee.extend(this,{thumbs:{swiper:null,init:Z.init.bind(this),update:Z.update.bind(this),onThumbClick:Z.onThumbClick.bind(this)}})},on:{beforeInit:function(){var e=this.params.thumbs;e&&e.swiper&&(this.thumbs.init(),this.thumbs.update(!0))},slideChange:function(){this.thumbs.swiper&&this.thumbs.update()},update:function(){this.thumbs.swiper&&this.thumbs.update()},resize:function(){this.thumbs.swiper&&this.thumbs.update()},observerUpdate:function(){this.thumbs.swiper&&this.thumbs.update()},setTransition:function(e){var t=this.thumbs.swiper;t&&t.setTransition(e)},beforeDestroy:function(){var e=this.thumbs.swiper;e&&this.thumbs.swiperCreated&&e&&e.destroy()}}}];return void 0===T.use&&(T.use=T.Class.use,T.installModule=T.Class.installModule),T.use(Q),T}); +//# sourceMappingURL=swiper.min.js.map diff --git a/assets/3rd/swiper/js/swiper.min.js.map b/assets/3rd/swiper/js/swiper.min.js.map new file mode 100755 index 00000000..479ae95c --- /dev/null +++ b/assets/3rd/swiper/js/swiper.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["swiper.js"],"names":["global","factory","exports","module","define","amd","self","Swiper","this","doc","document","body","addEventListener","removeEventListener","activeElement","blur","nodeName","querySelector","querySelectorAll","getElementById","createEvent","initEvent","createElement","children","childNodes","style","setAttribute","getElementsByTagName","location","hash","win","window","navigator","userAgent","history","CustomEvent","getComputedStyle","getPropertyValue","Image","Date","screen","setTimeout","clearTimeout","Dom7","arr","i","length","$","selector","context","els","tempParent","html","trim","indexOf","toCreate","innerHTML","push","match","split","nodeType","unique","uniqueArray","fn","prototype","Class","Methods","addClass","className","classes","j","classList","add","removeClass","remove","hasClass","contains","toggleClass","toggle","attr","attrs","value","arguments$1","arguments","getAttribute","attrName","removeAttr","removeAttribute","data","key","el","dom7ElementDataStorage","dataKey","transform","elStyle","webkitTransform","transition","duration","webkitTransitionDuration","transitionDuration","on","assign","args","len","eventType","targetSelector","listener","capture","handleLiveEvent","e","target","eventData","dom7EventData","unshift","is","apply","parents","k","handleEvent","undefined","events","event$1","dom7LiveListeners","proxyListener","event","dom7Listeners","off","handlers","handler","splice","dom7proxy","trigger","evt","detail","bubbles","cancelable","filter","dataIndex","dispatchEvent","transitionEnd","callback","dom","fireCallBack","call","outerWidth","includeMargins","styles","offsetWidth","parseFloat","outerHeight","offsetHeight","offset","box","getBoundingClientRect","clientTop","clientLeft","scrollTop","scrollY","scrollLeft","scrollX","top","left","css","props","prop","each","text","textContent","compareWith","matches","webkitMatchesSelector","msMatchesSelector","index","child","previousSibling","eq","returnIndex","append","newChild","tempDiv","firstChild","appendChild","prepend","insertBefore","next","nextElementSibling","nextAll","nextEls","prev","previousElementSibling","prevAll","prevEls","parent","parentNode","closest","find","foundElements","found","removeChild","toAdd","Object","keys","forEach","methodName","testDiv","ua","Utils","deleteProps","obj","object","nextTick","delay","now","getTranslate","axis","matrix","curTransform","transformMatrix","curStyle","WebKitCSSMatrix","map","a","replace","join","MozTransform","OTransform","MsTransform","msTransform","toString","m41","m42","parseUrlQuery","url","params","param","query","urlToParse","href","paramsPart","decodeURIComponent","isObject","o","constructor","extend","len$1","to","nextSource","keysArray","nextIndex","nextKey","desc","getOwnPropertyDescriptor","enumerable","Support","touch","Modernizr","maxTouchPoints","DocumentTouch","pointerEvents","pointerEnabled","PointerEvent","prefixedPointerEvents","msPointerEnabled","transforms3d","csstransforms3d","flexbox","observer","passiveListener","supportsPassive","opts","defineProperty","get","gestures","Browser","isIE","isEdge","isSafari","toLowerCase","isUiWebView","test","SwiperClass","eventsListeners","eventName","staticAccessors","components","configurable","priority","method","once","onceHandler","f7proxy","eventHandler","emit","Array","isArray","slice","useModulesParams","instanceParams","instance","modules","moduleName","useModules","modulesParams","moduleParams","modulePropName","moduleProp","bind","moduleEventName","create","set","use","installModule","name","proto","static","install","m","concat","defineProperties","update","updateSize","width","height","swiper","$el","clientWidth","clientHeight","isHorizontal","isVertical","parseInt","size","updateSlides","$wrapperEl","swiperSize","rtl","rtlTranslate","wrongRTL","isVirtual","virtual","enabled","previousSlidesLength","slides","slidesLength","snapGrid","slidesGrid","slidesSizesGrid","offsetBefore","slidesOffsetBefore","offsetAfter","slidesOffsetAfter","previousSnapGridLength","previousSlidesGridLength","spaceBetween","slidePosition","prevSlideSize","slidesNumberEvenToRows","slideSize","virtualSize","marginLeft","marginTop","marginRight","marginBottom","slidesPerColumn","Math","floor","ceil","slidesPerView","slidesPerColumnFill","max","newSlidesGrid","slidesPerRow","numFullColumns","slide","newSlideOrderIndex","column","row","-webkit-box-ordinal-group","-moz-box-ordinal-group","-ms-flex-order","-webkit-order","order","slideStyles","currentTransform","currentWebKitTransform","roundLengths","paddingLeft","paddingRight","boxSizing","paddingTop","paddingBottom","boxSizing$1","swiperSlideSize","centeredSlides","abs","slidesPerGroup","effect","setWrapperSize","i$1","slidesGridItem","i$2","slidesGridItem$1","centerInsufficientSlides","allSlidesSize","slideSizeValue","allSlidesOffset","snap","snapIndex","watchOverflow","checkOverflow","watchSlidesProgress","watchSlidesVisibility","updateSlidesOffset","updateAutoHeight","speed","activeSlides","newHeight","setTransition","activeIndex","swiperSlideOffset","offsetLeft","offsetTop","updateSlidesProgress","translate","offsetCenter","slideVisibleClass","visibleSlidesIndexes","visibleSlides","slideProgress","minTranslate","slideBefore","slideAfter","progress","updateProgress","translatesDiff","maxTranslate","isBeginning","isEnd","wasBeginning","wasEnd","updateSlidesClasses","activeSlide","realIndex","slideActiveClass","loop","slideDuplicateClass","slideDuplicateActiveClass","nextSlide","slideNextClass","prevSlide","slidePrevClass","slideDuplicateNextClass","slideDuplicatePrevClass","updateActiveIndex","newActiveIndex","previousIndex","previousRealIndex","previousSnapIndex","normalizeSlideIndex","updateClickedSlide","slideFound","clickedSlide","clickedIndex","slideToClickedSlide","virtualTranslate","currentTranslate","setTranslate","byController","x","y","previousTranslate","transition$1","transitionStart","runCallbacks","direction","autoHeight","dir","animating","slideTo","internal","slideIndex","preventInteractionOnTransition","initialSlide","initialized","allowSlideNext","allowSlidePrev","onSlideToWrapperTransitionEnd","destroyed","slideToLoop","newIndex","loopedSlides","slideNext","loopFix","_clientLeft","slidePrev","normalize","val","prevIndex","normalizedTranslate","normalizedSnapGrid","prevSnap","slideReset","slideToClosest","currentSnap","slidesPerViewDynamic","slideToIndex","loopCreate","loopFillGroupWithBlank","blankSlidesNum","blankNode","loopAdditionalSlides","prependSlides","appendSlides","cloneNode","diff","loopDestroy","grabCursor","setGrabCursor","moving","simulateTouch","isLocked","cursor","unsetGrabCursor","manipulation","appendSlide","prependSlide","addSlide","activeIndexBuffer","baseLength","slidesBuffer","currentSlide","removeSlide","slidesIndexes","indexToRemove","removeAllSlides","Device","device","ios","android","androidChrome","desktop","windows","iphone","ipod","ipad","cordova","phonegap","os","osVersion","webView","osVersionArr","metaViewport","minimalUi","pixelRatio","devicePixelRatio","onResize","breakpoints","setBreakpoint","freeMode","newTranslate","min","defaults","init","touchEventsTarget","edgeSwipeDetection","edgeSwipeThreshold","freeModeMomentum","freeModeMomentumRatio","freeModeMomentumBounce","freeModeMomentumBounceRatio","freeModeMomentumVelocityRatio","freeModeSticky","freeModeMinimumVelocity","breakpointsInverse","touchRatio","touchAngle","shortSwipes","longSwipes","longSwipesRatio","longSwipesMs","followFinger","allowTouchMove","threshold","touchMoveStopPropagation","touchStartPreventDefault","touchStartForcePreventDefault","touchReleaseOnEdges","uniqueNavElements","resistance","resistanceRatio","preventClicks","preventClicksPropagation","preloadImages","updateOnImagesReady","swipeHandler","noSwiping","noSwipingClass","noSwipingSelector","passiveListeners","containerModifierClass","slideClass","slideBlankClass","wrapperClass","runCallbacksOnInit","prototypes","attachEvents","touchEvents","wrapperEl","onTouchStart","touchEventsData","touches","originalEvent","isTouchEvent","type","which","button","isTouched","isMoved","allowClick","currentX","targetTouches","pageX","currentY","pageY","startX","startY","iOSEdgeSwipeDetection","iOSEdgeSwipeThreshold","allowTouchCallbacks","isScrolling","startMoving","touchStartTime","swipeDirection","allowThresholdMove","preventDefault","formElements","shouldPreventDefault","onTouchMove","preventedByNestedSwiper","diffX","diffY","sqrt","pow","atan2","PI","nested","stopPropagation","startTranslate","allowMomentumBounce","disableParentSwiper","velocities","position","time","onTouchEnd","currentPos","touchEndTime","timeDiff","lastClickTime","clickTimeout","lastMoveEvent","pop","velocityEvent","distance","velocity","momentumDuration","momentumDistance","newPosition","afterBouncePosition","needsLoopFix","doBounce","bounceAmount","stopIndex","groupSize","ratio","onClick","stopImmediatePropagation","start","passive","move","end","detachEvents","breakpoint","getBreakpoint","currentBreakpoint","breakpointOnlyParams","paramValue","breakpointParams","originalParams","directionChanged","needsReLoop","changeDirection","points","point","sort","b","innerWidth","wasLocked","navigation","addClasses","classNames","suffixes","suffix","removeClasses","images","loadImage","imageEl","src","srcset","sizes","checkForComplete","image","onReady","complete","onload","onerror","imagesLoaded","imagesToLoad","currentSrc","extendedDefaults","prototypeGroup","protoMethod","moduleParamName","swiperParams","passedParams","swipers","containerEl","newParams","touchEventsTouch","touchEventsDesktop","__proto__","spv","breakLoop","translateValue","newDirection","needUpdate","currentDirection","slideEl","destroy","deleteInstance","cleanStyles","extendDefaults","newDefaults","Device$1","Support$1","support","Browser$1","browser","Resize","resize","resizeHandler","orientationChangeHandler","Observer","func","MutationObserver","WebkitMutationObserver","attach","options","mutations","observerUpdate","requestAnimationFrame","observe","attributes","childList","characterData","observers","observeParents","containerParents","observeSlideChildren","disconnect","Observer$1","Virtual","force","ref","ref$1","addSlidesBefore","addSlidesAfter","ref$2","previousFrom","from","previousTo","previousSlidesGrid","renderSlide","previousOffset","offsetProp","slidesAfter","slidesBefore","onRendered","lazy","load","renderExternal","slidesToRender","prependIndexes","appendIndexes","cache","$slideEl","numberOfNewSlides","newCache","cachedIndex","Virtual$1","beforeInit","overwriteParams","Keyboard","handle","kc","keyCode","charCode","shiftKey","altKey","ctrlKey","metaKey","keyboard","onlyInViewport","inView","windowWidth","windowHeight","innerHeight","swiperOffset","swiperCoord","returnValue","enable","disable","Keyboard$1","Mousewheel","lastScrollTime","isSupported","element","implementation","hasFeature","isEventSupported","sX","sY","pX","pY","wheelDelta","wheelDeltaY","wheelDeltaX","HORIZONTAL_AXIS","deltaY","deltaX","deltaMode","spinX","spinY","pixelX","pixelY","handleMouseEnter","mouseEntered","handleMouseLeave","mousewheel","releaseOnEdges","delta","rtlFactor","forceToAxis","invert","sensitivity","timeout","autoplay","autoplayDisableOnInteraction","stop","getTime","eventsTarged","Navigation","$nextEl","$prevEl","disabledClass","lockClass","onPrevClick","onNextClick","nextEl","prevEl","Pagination","pagination","current","total","paginationType","bullets","firstIndex","lastIndex","midIndex","dynamicBullets","bulletSize","dynamicMainBullets","dynamicBulletIndex","bullet","$bullet","bulletIndex","bulletActiveClass","$firstDisplayedBullet","$lastDisplayedBullet","dynamicBulletsLength","bulletsOffset","formatFractionCurrent","formatFractionTotal","progressbarDirection","progressbarOpposite","scale","scaleX","scaleY","renderCustom","render","paginationHTML","numberOfBullets","renderBullet","bulletClass","renderFraction","currentClass","totalClass","renderProgressbar","progressbarFillClass","clickable","clickableClass","modifierClass","progressbarOppositeClass","hiddenClass","Scrollbar","scrollbar","dragSize","trackSize","$dragEl","newSize","newPos","hide","opacity","divider","moveDivider","display","setDragPosition","positionRatio","clientX","clientY","onDragStart","dragTimeout","onDragMove","onDragEnd","snapOnRelease","enableDraggable","activeListener","disableDraggable","$swiperEl","dragEl","draggable","Parallax","setTransform","p","currentOpacity","currentScale","parallax","parallaxEl","$parallaxEl","parallaxDuration","Zoom","getDistanceBetweenTouches","x1","y1","x2","y2","onGestureStart","zoom","gesture","fakeGestureTouched","fakeGestureMoved","scaleStart","$imageEl","$imageWrapEl","maxRatio","isScaling","onGestureChange","scaleMove","minRatio","onGestureEnd","changedTouches","touchesStart","slideWidth","slideHeight","scaledWidth","scaledHeight","minX","maxX","minY","maxY","touchesCurrent","prevPositionX","prevPositionY","prevTime","momentumDurationX","momentumDurationY","momentumDistanceX","newPositionX","momentumDistanceY","newPositionY","onTransitionEnd","out","in","touchX","touchY","translateX","translateY","imageWidth","imageHeight","translateMinX","translateMinY","translateMaxX","translateMaxY","Lazy","loadInSlide","loadInDuplicate","$images","elementClass","loadedClass","loadingClass","imageIndex","background","slideOriginalIndex","originalSlide","duplicatedSlide","slideExist","initialImageLoaded","elIndex","loadPrevNext","loadPrevNextAmount","amount","maxIndex","minIndex","Controller","LinearSpline","guess","i1","i3","binarySearch","array","interpolate","getInterpolateFunction","c","controller","spline","setTranslate$1","multiplier","controlledTranslate","controlled","control","setControlledTranslate","by","inverse","setControlledTransition","a11y","makeElFocusable","addElRole","role","addElLabel","label","disableEl","enableEl","onEnterKey","$targetEl","notify","lastSlideMessage","nextSlideMessage","firstSlideMessage","prevSlideMessage","click","message","notification","liveRegion","updateNavigation","updatePagination","bulletEl","$bulletEl","paginationBulletMessage","History","pushState","hashNavigation","paths","getPathValues","scrollToSlide","replaceState","setHistoryPopState","pathArray","pathname","part","setHistory","slugify","includes","currentState","state","HashNavigation","onHashCange","newHash","setHash","watchState","Autoplay","run","$activeSlideEl","reverseDirection","stopOnLastSlide","running","pause","paused","waitForTransition","Fade","tx","ty","slideOpacity","fadeEffect","crossFade","eventTriggered","triggerEvents","Cube","$cubeShadowEl","swiperWidth","swiperHeight","cubeEffect","wrapperRotate","shadow","slideAngle","round","tz","slideShadows","shadowBefore","shadowAfter","-webkit-transform-origin","-moz-transform-origin","-ms-transform-origin","transform-origin","shadowOffset","shadowAngle","sin","cos","scale1","shadowScale","scale2","zFactor","Flip","flipEffect","limitRotation","rotateY","rotateX","zIndex","Coverflow","coverflowEffect","center","rotate","depth","offsetMultiplier","modifier","translateZ","stretch","slideTransform","$shadowBeforeEl","$shadowAfterEl","perspectiveOrigin","Thumbs","thumbsParams","thumbs","swiperCreated","thumbsContainerClass","onThumbClick","thumbsSwiper","slideThumbActiveClass","currentIndex","initial","newThumbsIndex","currentThumbsIndex","prevThumbsIndex","nextThumbsIndex","thumbsToActivate","thumbActiveClass","hideOnClick","toEdge","fromEdge","isHidden","bulletElement","number","activeIndexChange","snapIndexChange","slidesLengthChange","snapGridLengthChange","dragClass","containerClass","zoomedSlideClass","touchStart","touchEnd","doubleTap","loadOnTransitionStart","preloaderClass","scroll","scrollbarDragMove","notificationClass","paginationUpdate","disableOnInteraction","beforeTransitionStart","sliderFirstMove","slideChange","beforeDestroy"],"mappings":";;;;;;;;;;;CAYC,SAAUA,EAAQC,GACE,iBAAZC,SAA0C,oBAAXC,OAAyBA,OAAOD,QAAUD,IAC9D,mBAAXG,QAAyBA,OAAOC,IAAMD,OAAOH,IACnDD,EAASA,GAAUM,MAAaC,OAASN,IAH5C,CAIEO,KAAM,WAAc,aAapB,IAAIC,EAA2B,oBAAbC,SAA4B,CAC5CC,KAAM,GACNC,iBAAkB,aAClBC,oBAAqB,aACrBC,cAAe,CACbC,KAAM,aACNC,SAAU,IAEZC,cAAe,WACb,OAAO,MAETC,iBAAkB,WAChB,MAAO,IAETC,eAAgB,WACd,OAAO,MAETC,YAAa,WACX,MAAO,CACLC,UAAW,eAGfC,cAAe,WACb,MAAO,CACLC,SAAU,GACVC,WAAY,GACZC,MAAO,GACPC,aAAc,aACdC,qBAAsB,WACpB,MAAO,MAIbC,SAAU,CAAEC,KAAM,KAChBnB,SAEAoB,EAAyB,oBAAXC,OAA0B,CAC1CrB,SAAUD,EACVuB,UAAW,CACTC,UAAW,IAEbL,SAAU,GACVM,QAAS,GACTC,YAAa,WACX,OAAO3B,MAETI,iBAAkB,aAClBC,oBAAqB,aACrBuB,iBAAkB,WAChB,MAAO,CACLC,iBAAkB,WAChB,MAAO,MAIbC,MAAO,aACPC,KAAM,aACNC,OAAQ,GACRC,WAAY,aACZC,aAAc,cACZX,OAgBAY,EAAO,SAAcC,GAGvB,IAFA,IAESC,EAAI,EAAGA,EAAID,EAAIE,OAAQD,GAAK,EAF1BrC,KAGJqC,GAAKD,EAAIC,GAIhB,OAPWrC,KAKNsC,OAASF,EAAIE,OAEXtC,MAGT,SAASuC,EAAEC,EAAUC,GACnB,IAAIL,EAAM,GACNC,EAAI,EACR,GAAIG,IAAaC,GACXD,aAAoBL,EACtB,OAAOK,EAGX,GAAIA,EAEF,GAAwB,iBAAbA,EAAuB,CAChC,IAAIE,EACAC,EACAC,EAAOJ,EAASK,OACpB,GAAyB,GAArBD,EAAKE,QAAQ,MAAkC,GAArBF,EAAKE,QAAQ,KAAW,CACpD,IAAIC,EAAW,MAQf,IAP4B,IAAxBH,EAAKE,QAAQ,SAAgBC,EAAW,MAChB,IAAxBH,EAAKE,QAAQ,SAAgBC,EAAW,SAChB,IAAxBH,EAAKE,QAAQ,QAAwC,IAAxBF,EAAKE,QAAQ,SAAgBC,EAAW,MAC1C,IAA3BH,EAAKE,QAAQ,YAAmBC,EAAW,SACf,IAA5BH,EAAKE,QAAQ,aAAoBC,EAAW,WAChDJ,EAAa1C,EAAIa,cAAciC,IACpBC,UAAYJ,EAClBP,EAAI,EAAGA,EAAIM,EAAW3B,WAAWsB,OAAQD,GAAK,EACjDD,EAAIa,KAAKN,EAAW3B,WAAWqB,SAUjC,IAFEK,EALGD,GAA2B,MAAhBD,EAAS,IAAeA,EAASU,MAAM,aAK9CT,GAAWxC,GAAKS,iBAAiB8B,EAASK,QAH3C,CAAC5C,EAAIU,eAAe6B,EAASK,OAAOM,MAAM,KAAK,KAKlDd,EAAI,EAAGA,EAAIK,EAAIJ,OAAQD,GAAK,EAC3BK,EAAIL,IAAMD,EAAIa,KAAKP,EAAIL,SAG1B,GAAIG,EAASY,UAAYZ,IAAalB,GAAOkB,IAAavC,EAE/DmC,EAAIa,KAAKT,QACJ,GAAsB,EAAlBA,EAASF,QAAcE,EAAS,GAAGY,SAE5C,IAAKf,EAAI,EAAGA,EAAIG,EAASF,OAAQD,GAAK,EACpCD,EAAIa,KAAKT,EAASH,IAIxB,OAAO,IAAIF,EAAKC,GAOlB,SAASiB,EAAOjB,GAEd,IADA,IAAIkB,EAAc,GACTjB,EAAI,EAAGA,EAAID,EAAIE,OAAQD,GAAK,GACE,IAAjCiB,EAAYR,QAAQV,EAAIC,KAAciB,EAAYL,KAAKb,EAAIC,IAEjE,OAAOiB,EATTf,EAAEgB,GAAKpB,EAAKqB,UACZjB,EAAEkB,MAAQtB,EACVI,EAAEJ,KAAOA,EA8nBT,IAAIuB,EAAU,CACZC,SApnBF,SAAkBC,GAChB,QAAyB,IAAdA,EACT,OAAO5D,KAGT,IADA,IAAI6D,EAAUD,EAAUT,MAAM,KACrBd,EAAI,EAAGA,EAAIwB,EAAQvB,OAAQD,GAAK,EACvC,IAAK,IAAIyB,EAAI,EAAGA,EAAI9D,KAAKsC,OAAQwB,GAAK,OACb,IAAZ9D,KAAK8D,SAAmD,IAAtB9D,KAAK8D,GAAGC,WAA6B/D,KAAK8D,GAAGC,UAAUC,IAAIH,EAAQxB,IAGpH,OAAOrC,MA2mBPiE,YAzmBF,SAAqBL,GAEnB,IADA,IAAIC,EAAUD,EAAUT,MAAM,KACrBd,EAAI,EAAGA,EAAIwB,EAAQvB,OAAQD,GAAK,EACvC,IAAK,IAAIyB,EAAI,EAAGA,EAAI9D,KAAKsC,OAAQwB,GAAK,OACb,IAAZ9D,KAAK8D,SAAmD,IAAtB9D,KAAK8D,GAAGC,WAA6B/D,KAAK8D,GAAGC,UAAUG,OAAOL,EAAQxB,IAGvH,OAAOrC,MAmmBPmE,SAjmBF,SAAkBP,GAChB,QAAK5D,KAAK,IACHA,KAAK,GAAG+D,UAAUK,SAASR,IAgmBlCS,YA9lBF,SAAqBT,GAEnB,IADA,IAAIC,EAAUD,EAAUT,MAAM,KACrBd,EAAI,EAAGA,EAAIwB,EAAQvB,OAAQD,GAAK,EACvC,IAAK,IAAIyB,EAAI,EAAGA,EAAI9D,KAAKsC,OAAQwB,GAAK,OACb,IAAZ9D,KAAK8D,SAAmD,IAAtB9D,KAAK8D,GAAGC,WAA6B/D,KAAK8D,GAAGC,UAAUO,OAAOT,EAAQxB,IAGvH,OAAOrC,MAwlBPuE,KAtlBF,SAAcC,EAAOC,GACnB,IAAIC,EAAcC,UAElB,GAAyB,IAArBA,UAAUrC,QAAiC,iBAAVkC,EAEnC,OAAIxE,KAAK,GAAaA,KAAK,GAAG4E,aAAaJ,QAC3C,EAIF,IAAK,IAAInC,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EACpC,GAA2B,IAAvBqC,EAAYpC,OAEdtC,KAAKqC,GAAGnB,aAAasD,EAAOC,QAI5B,IAAK,IAAII,KAAYL,EACnBxE,KAAKqC,GAAGwC,GAAYL,EAAMK,GAC1B7E,KAAKqC,GAAGnB,aAAa2D,EAAUL,EAAMK,IAI3C,OAAO7E,MAgkBP8E,WA7jBF,SAAoBP,GAClB,IAAK,IAAIlC,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EACpCrC,KAAKqC,GAAG0C,gBAAgBR,GAE1B,OAAOvE,MA0jBPgF,KAxjBF,SAAcC,EAAKR,GACjB,IAAIS,EACJ,QAAqB,IAAVT,EAAX,CAkBA,IAAK,IAAIpC,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,GACpC6C,EAAKlF,KAAKqC,IACF8C,yBAA0BD,EAAGC,uBAAyB,IAC9DD,EAAGC,uBAAuBF,GAAOR,EAEnC,OAAOzE,KApBL,GAFAkF,EAAKlF,KAAK,GAEF,CACN,GAAIkF,EAAGC,wBAA2BF,KAAOC,EAAGC,uBAC1C,OAAOD,EAAGC,uBAAuBF,GAGnC,IAAIG,EAAUF,EAAGN,aAAc,QAAUK,GACzC,OAAIG,QAGJ,IA2iBJC,UA5hBF,SAAmBA,GACjB,IAAK,IAAIhD,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAAG,CACvC,IAAIiD,EAAUtF,KAAKqC,GAAGpB,MACtBqE,EAAQC,gBAAkBF,EAC1BC,EAAQD,UAAYA,EAEtB,OAAOrF,MAuhBPwF,WArhBF,SAAoBC,GACM,iBAAbA,IACTA,GAAsB,MAExB,IAAK,IAAIpD,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAAG,CACvC,IAAIiD,EAAUtF,KAAKqC,GAAGpB,MACtBqE,EAAQI,yBAA2BD,EACnCH,EAAQK,mBAAqBF,EAE/B,OAAOzF,MA6gBP4F,GA1gBF,WAIE,IAHA,IAAIC,EAEAC,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GACzC,IAAIC,EAAYF,EAAK,GACjBG,EAAiBH,EAAK,GACtBI,EAAWJ,EAAK,GAChBK,EAAUL,EAAK,GAOnB,SAASM,EAAgBC,GACvB,IAAIC,EAASD,EAAEC,OACf,GAAKA,EAAL,CACA,IAAIC,EAAYF,EAAEC,OAAOE,eAAiB,GAI1C,GAHID,EAAUzD,QAAQuD,GAAK,GACzBE,EAAUE,QAAQJ,GAEhB9D,EAAE+D,GAAQI,GAAGT,GAAmBC,EAASS,MAAML,EAAQC,QAGzD,IADA,IAAIK,EAAUrE,EAAE+D,GAAQM,UACfC,EAAI,EAAGA,EAAID,EAAQtE,OAAQuE,GAAK,EACnCtE,EAAEqE,EAAQC,IAAIH,GAAGT,IAAmBC,EAASS,MAAMC,EAAQC,GAAIN,IAIzE,SAASO,EAAYT,GACnB,IAAIE,EAAYF,GAAKA,EAAEC,QAASD,EAAEC,OAAOE,eAAsB,GAC3DD,EAAUzD,QAAQuD,GAAK,GACzBE,EAAUE,QAAQJ,GAEpBH,EAASS,MAAM3G,KAAMuG,GA1BA,mBAAZT,EAAK,KACEE,GAAfH,EAASC,GAAyB,GAAII,EAAWL,EAAO,GAAIM,EAAUN,EAAO,GAC9EI,OAAiBc,GAEdZ,IAAWA,GAAU,GA0B1B,IAFA,IACIrC,EADAkD,EAAShB,EAAU7C,MAAM,KAEpBd,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAAG,CACvC,IAAI6C,EAAKlF,KAAKqC,GACd,GAAK4D,EAaH,IAAKnC,EAAI,EAAGA,EAAIkD,EAAO1E,OAAQwB,GAAK,EAAG,CACrC,IAAImD,EAAUD,EAAOlD,GAChBoB,EAAGgC,oBAAqBhC,EAAGgC,kBAAoB,IAC/ChC,EAAGgC,kBAAkBD,KAAY/B,EAAGgC,kBAAkBD,GAAW,IACtE/B,EAAGgC,kBAAkBD,GAAShE,KAAK,CACjCiD,SAAUA,EACViB,cAAef,IAEjBlB,EAAG9E,iBAAiB6G,EAASb,EAAiBD,QApBhD,IAAKrC,EAAI,EAAGA,EAAIkD,EAAO1E,OAAQwB,GAAK,EAAG,CACrC,IAAIsD,EAAQJ,EAAOlD,GACdoB,EAAGmC,gBAAiBnC,EAAGmC,cAAgB,IACvCnC,EAAGmC,cAAcD,KAAUlC,EAAGmC,cAAcD,GAAS,IAC1DlC,EAAGmC,cAAcD,GAAOnE,KAAK,CAC3BiD,SAAUA,EACViB,cAAeL,IAEjB5B,EAAG9E,iBAAiBgH,EAAON,EAAaX,IAgB9C,OAAOnG,MAycPsH,IAvcF,WAIE,IAHA,IAAIzB,EAEAC,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GACzC,IAAIC,EAAYF,EAAK,GACjBG,EAAiBH,EAAK,GACtBI,EAAWJ,EAAK,GAChBK,EAAUL,EAAK,GACI,mBAAZA,EAAK,KACEE,GAAfH,EAASC,GAAyB,GAAII,EAAWL,EAAO,GAAIM,EAAUN,EAAO,GAC9EI,OAAiBc,GAEdZ,IAAWA,GAAU,GAG1B,IADA,IAAIa,EAAShB,EAAU7C,MAAM,KACpBd,EAAI,EAAGA,EAAI2E,EAAO1E,OAAQD,GAAK,EAEtC,IADA,IAAI+E,EAAQJ,EAAO3E,GACVyB,EAAI,EAAGA,EAAI9D,KAAKsC,OAAQwB,GAAK,EAAG,CACvC,IAAIoB,EAAKlF,KAAK8D,GACVyD,OAAW,EAMf,IALKtB,GAAkBf,EAAGmC,cACxBE,EAAWrC,EAAGmC,cAAcD,GACnBnB,GAAkBf,EAAGgC,oBAC9BK,EAAWrC,EAAGgC,kBAAkBE,IAE9BG,GAAYA,EAASjF,OACvB,IAAK,IAAIuE,EAAIU,EAASjF,OAAS,EAAQ,GAALuE,EAAQA,GAAK,EAAG,CAChD,IAAIW,EAAUD,EAASV,GACnBX,GAAYsB,EAAQtB,WAAaA,GACnChB,EAAG7E,oBAAoB+G,EAAOI,EAAQL,cAAehB,GACrDoB,EAASE,OAAOZ,EAAG,IACVX,GAAYsB,EAAQtB,UAAYsB,EAAQtB,SAASwB,WAAaF,EAAQtB,SAASwB,YAAcxB,GACtGhB,EAAG7E,oBAAoB+G,EAAOI,EAAQL,cAAehB,GACrDoB,EAASE,OAAOZ,EAAG,IACTX,IACVhB,EAAG7E,oBAAoB+G,EAAOI,EAAQL,cAAehB,GACrDoB,EAASE,OAAOZ,EAAG,KAM7B,OAAO7G,MA6ZP2H,QA3ZF,WAEE,IADA,IAAI7B,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GAIzC,IAFA,IAAIiB,EAASlB,EAAK,GAAG3C,MAAM,KACvBoD,EAAYT,EAAK,GACZzD,EAAI,EAAGA,EAAI2E,EAAO1E,OAAQD,GAAK,EAEtC,IADA,IAAI+E,EAAQJ,EAAO3E,GACVyB,EAAI,EAAGA,EAAI9D,KAAKsC,OAAQwB,GAAK,EAAG,CACvC,IAAIoB,EAAKlF,KAAK8D,GACV8D,OAAM,EACV,IACEA,EAAM,IAAItG,EAAIK,YAAYyF,EAAO,CAC/BS,OAAQtB,EACRuB,SAAS,EACTC,YAAY,IAEd,MAAO1B,IACPuB,EAAM3H,EAAIW,YAAY,UAClBC,UAAUuG,GAAO,GAAM,GAC3BQ,EAAIC,OAAStB,EAGfrB,EAAGsB,cAAgBV,EAAKkC,OAAO,SAAUhD,EAAMiD,GAAa,OAAmB,EAAZA,IACnE/C,EAAGgD,cAAcN,GACjB1C,EAAGsB,cAAgB,UACZtB,EAAGsB,cAGd,OAAOxG,MA+XPmI,cA7XF,SAAuBC,GACrB,IAEI/F,EAFA2E,EAAS,CAAC,sBAAuB,iBACjCqB,EAAMrI,KAEV,SAASsI,EAAajC,GAEpB,GAAIA,EAAEC,SAAWtG,KAEjB,IADAoI,EAASG,KAAKvI,KAAMqG,GACfhE,EAAI,EAAGA,EAAI2E,EAAO1E,OAAQD,GAAK,EAClCgG,EAAIf,IAAIN,EAAO3E,GAAIiG,GAGvB,GAAIF,EACF,IAAK/F,EAAI,EAAGA,EAAI2E,EAAO1E,OAAQD,GAAK,EAClCgG,EAAIzC,GAAGoB,EAAO3E,GAAIiG,GAGtB,OAAOtI,MA6WPwI,WA3WF,SAAoBC,GAClB,GAAkB,EAAdzI,KAAKsC,OAAY,CACnB,GAAImG,EAAgB,CAElB,IAAIC,EAAS1I,KAAK0I,SAClB,OAAO1I,KAAK,GAAG2I,YAAcC,WAAWF,EAAO7G,iBAAiB,iBAAmB+G,WAAWF,EAAO7G,iBAAiB,gBAExH,OAAO7B,KAAK,GAAG2I,YAEjB,OAAO,MAmWPE,YAjWF,SAAqBJ,GACnB,GAAkB,EAAdzI,KAAKsC,OAAY,CACnB,GAAImG,EAAgB,CAElB,IAAIC,EAAS1I,KAAK0I,SAClB,OAAO1I,KAAK,GAAG8I,aAAeF,WAAWF,EAAO7G,iBAAiB,eAAiB+G,WAAWF,EAAO7G,iBAAiB,kBAEvH,OAAO7B,KAAK,GAAG8I,aAEjB,OAAO,MAyVPC,OAvVF,WACE,GAAkB,EAAd/I,KAAKsC,OAAY,CACnB,IAAI4C,EAAKlF,KAAK,GACVgJ,EAAM9D,EAAG+D,wBACT9I,EAAOF,EAAIE,KACX+I,EAAYhE,EAAGgE,WAAa/I,EAAK+I,WAAa,EAC9CC,EAAajE,EAAGiE,YAAchJ,EAAKgJ,YAAc,EACjDC,EAAYlE,IAAO5D,EAAMA,EAAI+H,QAAUnE,EAAGkE,UAC1CE,EAAapE,IAAO5D,EAAMA,EAAIiI,QAAUrE,EAAGoE,WAC/C,MAAO,CACLE,IAAMR,EAAIQ,IAAMJ,EAAaF,EAC7BO,KAAOT,EAAIS,KAAOH,EAAcH,GAIpC,OAAO,MAyUPO,IAnUF,SAAaC,EAAOlF,GAClB,IAAIpC,EACJ,GAAyB,IAArBsC,UAAUrC,OAAc,CAC1B,GAAqB,iBAAVqH,EAEJ,CACL,IAAKtH,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAEhC,IAAK,IAAIuH,KAAQD,EACf3J,KAAKqC,GAAGpB,MAAM2I,GAAQD,EAAMC,GAGhC,OAAO5J,KARP,GAAIA,KAAK,GAAM,OAAOsB,EAAIM,iBAAiB5B,KAAK,GAAI,MAAM6B,iBAAiB8H,GAW/E,GAAyB,IAArBhF,UAAUrC,QAAiC,iBAAVqH,EAAoB,CACvD,IAAKtH,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAChCrC,KAAKqC,GAAGpB,MAAM0I,GAASlF,EAEzB,OAAOzE,KAET,OAAOA,MA+SP6J,KA5SF,SAAczB,GAEZ,IAAKA,EAAY,OAAOpI,KAExB,IAAK,IAAIqC,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAEpC,IAA2C,IAAvC+F,EAASG,KAAKvI,KAAKqC,GAAIA,EAAGrC,KAAKqC,IAEjC,OAAOrC,KAIX,OAAOA,MAiSP4C,KA9RF,SAAcA,GACZ,QAAoB,IAATA,EACT,OAAO5C,KAAK,GAAKA,KAAK,GAAGgD,eAAY+D,EAGvC,IAAK,IAAI1E,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EACpCrC,KAAKqC,GAAGW,UAAYJ,EAEtB,OAAO5C,MAuRP8J,KApRF,SAAcA,GACZ,QAAoB,IAATA,EACT,OAAI9J,KAAK,GACAA,KAAK,GAAG+J,YAAYlH,OAEtB,KAGT,IAAK,IAAIR,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EACpCrC,KAAKqC,GAAG0H,YAAcD,EAExB,OAAO9J,MA0QP0G,GAxQF,SAAYlE,GACV,IACIwH,EACA3H,EAFA6C,EAAKlF,KAAK,GAGd,IAAKkF,QAA0B,IAAb1C,EAA4B,OAAO,EACrD,GAAwB,iBAAbA,EAAuB,CAChC,GAAI0C,EAAG+E,QAAW,OAAO/E,EAAG+E,QAAQzH,GAC/B,GAAI0C,EAAGgF,sBAAyB,OAAOhF,EAAGgF,sBAAsB1H,GAChE,GAAI0C,EAAGiF,kBAAqB,OAAOjF,EAAGiF,kBAAkB3H,GAG7D,IADAwH,EAAczH,EAAEC,GACXH,EAAI,EAAGA,EAAI2H,EAAY1H,OAAQD,GAAK,EACvC,GAAI2H,EAAY3H,KAAO6C,EAAM,OAAO,EAEtC,OAAO,EACF,GAAI1C,IAAavC,EAAO,OAAOiF,IAAOjF,EACxC,GAAIuC,IAAalB,EAAO,OAAO4D,IAAO5D,EAE3C,GAAIkB,EAASY,UAAYZ,aAAoBL,EAAM,CAEjD,IADA6H,EAAcxH,EAASY,SAAW,CAACZ,GAAYA,EAC1CH,EAAI,EAAGA,EAAI2H,EAAY1H,OAAQD,GAAK,EACvC,GAAI2H,EAAY3H,KAAO6C,EAAM,OAAO,EAEtC,OAAO,EAET,OAAO,GAgPPkF,MA9OF,WACE,IACI/H,EADAgI,EAAQrK,KAAK,GAEjB,GAAIqK,EAAO,CAGT,IAFAhI,EAAI,EAEuC,QAAnCgI,EAAQA,EAAMC,kBACG,IAAnBD,EAAMjH,WAAkBf,GAAK,GAEnC,OAAOA,IAsOTkI,GAjOF,SAAYH,GACV,QAAqB,IAAVA,EAAyB,OAAOpK,KAC3C,IACIwK,EADAlI,EAAStC,KAAKsC,OAElB,OACS,IAAIH,EADDG,EAAS,EAAjB8H,EACc,GAEdA,EAAQ,GACVI,EAAclI,EAAS8H,GACL,EAAqB,GACvB,CAACpK,KAAKwK,IAER,CAACxK,KAAKoK,MAsNtBK,OApNF,WAEE,IADA,IAGIC,EAHA5E,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GAIzC,IAAK,IAAIc,EAAI,EAAGA,EAAIf,EAAKxD,OAAQuE,GAAK,EAAG,CACvC6D,EAAW5E,EAAKe,GAChB,IAAK,IAAIxE,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EACpC,GAAwB,iBAAbqI,EAAuB,CAChC,IAAIC,EAAU1K,EAAIa,cAAc,OAEhC,IADA6J,EAAQ3H,UAAY0H,EACbC,EAAQC,YACb5K,KAAKqC,GAAGwI,YAAYF,EAAQC,iBAEzB,GAAIF,aAAoBvI,EAC7B,IAAK,IAAI2B,EAAI,EAAGA,EAAI4G,EAASpI,OAAQwB,GAAK,EACxC9D,KAAKqC,GAAGwI,YAAYH,EAAS5G,SAG/B9D,KAAKqC,GAAGwI,YAAYH,GAK1B,OAAO1K,MA4LP8K,QA1LF,SAAiBJ,GACf,IAAIrI,EACAyB,EACJ,IAAKzB,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAChC,GAAwB,iBAAbqI,EAAuB,CAChC,IAAIC,EAAU1K,EAAIa,cAAc,OAEhC,IADA6J,EAAQ3H,UAAY0H,EACf5G,EAAI6G,EAAQ3J,WAAWsB,OAAS,EAAQ,GAALwB,EAAQA,GAAK,EACnD9D,KAAKqC,GAAG0I,aAAaJ,EAAQ3J,WAAW8C,GAAI9D,KAAKqC,GAAGrB,WAAW,SAE5D,GAAI0J,aAAoBvI,EAC7B,IAAK2B,EAAI,EAAGA,EAAI4G,EAASpI,OAAQwB,GAAK,EACpC9D,KAAKqC,GAAG0I,aAAaL,EAAS5G,GAAI9D,KAAKqC,GAAGrB,WAAW,SAGvDhB,KAAKqC,GAAG0I,aAAaL,EAAU1K,KAAKqC,GAAGrB,WAAW,IAGtD,OAAOhB,MAyKPgL,KAvKF,SAAcxI,GACZ,OAAkB,EAAdxC,KAAKsC,OACHE,EACExC,KAAK,GAAGiL,oBAAsB1I,EAAEvC,KAAK,GAAGiL,oBAAoBvE,GAAGlE,GAC1D,IAAIL,EAAK,CAACnC,KAAK,GAAGiL,qBAEpB,IAAI9I,EAAK,IAGdnC,KAAK,GAAGiL,mBAA6B,IAAI9I,EAAK,CAACnC,KAAK,GAAGiL,qBACpD,IAAI9I,EAAK,IAEX,IAAIA,EAAK,KA4JhB+I,QA1JF,SAAiB1I,GACf,IAAI2I,EAAU,GACVjG,EAAKlF,KAAK,GACd,IAAKkF,EAAM,OAAO,IAAI/C,EAAK,IAC3B,KAAO+C,EAAG+F,oBAAoB,CAC5B,IAAID,EAAO9F,EAAG+F,mBACVzI,EACED,EAAEyI,GAAMtE,GAAGlE,IAAa2I,EAAQlI,KAAK+H,GAClCG,EAAQlI,KAAK+H,GACtB9F,EAAK8F,EAEP,OAAO,IAAI7I,EAAKgJ,IAgJhBC,KA9IF,SAAc5I,GACZ,GAAkB,EAAdxC,KAAKsC,OAAY,CACnB,IAAI4C,EAAKlF,KAAK,GACd,OAAIwC,EACE0C,EAAGmG,wBAA0B9I,EAAE2C,EAAGmG,wBAAwB3E,GAAGlE,GACxD,IAAIL,EAAK,CAAC+C,EAAGmG,yBAEf,IAAIlJ,EAAK,IAGd+C,EAAGmG,uBAAiC,IAAIlJ,EAAK,CAAC+C,EAAGmG,yBAC9C,IAAIlJ,EAAK,IAElB,OAAO,IAAIA,EAAK,KAkIhBmJ,QAhIF,SAAiB9I,GACf,IAAI+I,EAAU,GACVrG,EAAKlF,KAAK,GACd,IAAKkF,EAAM,OAAO,IAAI/C,EAAK,IAC3B,KAAO+C,EAAGmG,wBAAwB,CAChC,IAAID,EAAOlG,EAAGmG,uBACV7I,EACED,EAAE6I,GAAM1E,GAAGlE,IAAa+I,EAAQtI,KAAKmI,GAClCG,EAAQtI,KAAKmI,GACtBlG,EAAKkG,EAEP,OAAO,IAAIjJ,EAAKoJ,IAsHhBC,OApHF,SAAgBhJ,GAEd,IADA,IAAIoE,EAAU,GACLvE,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EACT,OAAvBrC,KAAKqC,GAAGoJ,aACNjJ,EACED,EAAEvC,KAAKqC,GAAGoJ,YAAY/E,GAAGlE,IAAaoE,EAAQ3D,KAAKjD,KAAKqC,GAAGoJ,YAE/D7E,EAAQ3D,KAAKjD,KAAKqC,GAAGoJ,aAI3B,OAAOlJ,EAAEc,EAAOuD,KA0GhBA,QAxGF,SAAiBpE,GAEf,IADA,IAAIoE,EAAU,GACLvE,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAEpC,IADA,IAAImJ,EAASxL,KAAKqC,GAAGoJ,WACdD,GACDhJ,EACED,EAAEiJ,GAAQ9E,GAAGlE,IAAaoE,EAAQ3D,KAAKuI,GAE3C5E,EAAQ3D,KAAKuI,GAEfA,EAASA,EAAOC,WAGpB,OAAOlJ,EAAEc,EAAOuD,KA4FhB8E,QA1FF,SAAiBlJ,GACf,IAAIkJ,EAAU1L,KACd,YAAwB,IAAbwC,EACF,IAAIL,EAAK,KAEbuJ,EAAQhF,GAAGlE,KACdkJ,EAAUA,EAAQ9E,QAAQpE,GAAU+H,GAAG,IAElCmB,IAmFPC,KAjFF,SAAcnJ,GAEZ,IADA,IAAIoJ,EAAgB,GACXvJ,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAEpC,IADA,IAAIwJ,EAAQ7L,KAAKqC,GAAG3B,iBAAiB8B,GAC5BsB,EAAI,EAAGA,EAAI+H,EAAMvJ,OAAQwB,GAAK,EACrC8H,EAAc3I,KAAK4I,EAAM/H,IAG7B,OAAO,IAAI3B,EAAKyJ,IA0EhB7K,SAxEF,SAAkByB,GAEhB,IADA,IAAIzB,EAAW,GACNsB,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAGpC,IAFA,IAAIrB,EAAahB,KAAKqC,GAAGrB,WAEhB8C,EAAI,EAAGA,EAAI9C,EAAWsB,OAAQwB,GAAK,EACrCtB,EAEiC,IAA3BxB,EAAW8C,GAAGV,UAAkBb,EAAEvB,EAAW8C,IAAI4C,GAAGlE,IAC7DzB,EAASkC,KAAKjC,EAAW8C,IAFM,IAA3B9C,EAAW8C,GAAGV,UAAkBrC,EAASkC,KAAKjC,EAAW8C,IAMnE,OAAO,IAAI3B,EAAKkB,EAAOtC,KA4DvBmD,OA1DF,WACE,IAAK,IAAI7B,EAAI,EAAGA,EAAIrC,KAAKsC,OAAQD,GAAK,EAChCrC,KAAKqC,GAAGoJ,YAAczL,KAAKqC,GAAGoJ,WAAWK,YAAY9L,KAAKqC,IAEhE,OAAOrC,MAuDPgE,IArDF,WAEE,IADA,IAAI8B,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GAEzC,IACI1D,EACAyB,EACJ,IAAKzB,EAAI,EAAGA,EAAIyD,EAAKxD,OAAQD,GAAK,EAAG,CACnC,IAAI0J,EAAQxJ,EAAEuD,EAAKzD,IACnB,IAAKyB,EAAI,EAAGA,EAAIiI,EAAMzJ,OAAQwB,GAAK,EAL3B9D,KAAAA,KAMEsC,QAAUyJ,EAAMjI,GANlB9D,KAOFsC,QAAU,EAGlB,OAVUtC,MAkDV0I,OA3VF,WACE,OAAI1I,KAAK,GAAasB,EAAIM,iBAAiB5B,KAAK,GAAI,MAC7C,KA4VTgM,OAAOC,KAAKvI,GAASwI,QAAQ,SAAUC,GACrC5J,EAAEgB,GAAG4I,GAAczI,EAAQyI,KAG7B,IAkIUlL,EAJAA,EAVJmL,EAuDEC,EA3KJC,GAAQ,CACVC,YAAa,SAAqBC,GAChC,IAAIC,EAASD,EACbR,OAAOC,KAAKQ,GAAQP,QAAQ,SAAUjH,GACpC,IACEwH,EAAOxH,GAAO,KACd,MAAOoB,IAGT,WACSoG,EAAOxH,GACd,MAAOoB,QAKbqG,SAAU,SAAkBtE,EAAUuE,GAGpC,YAFe,IAAVA,IAAmBA,EAAQ,GAEzB1K,WAAWmG,EAAUuE,IAE9BC,IAAK,WACH,OAAO7K,KAAK6K,OAEdC,aAAc,SAAsB3H,EAAI4H,GAGtC,IAAIC,EACAC,EACAC,OAJU,IAATH,IAAkBA,EAAO,KAM9B,IAAII,EAAW5L,EAAIM,iBAAiBsD,EAAI,MA+BxC,OA7BI5D,EAAI6L,iBAE+B,GADrCH,EAAeE,EAAS7H,WAAa6H,EAAS3H,iBAC7BpC,MAAM,KAAKb,SAC1B0K,EAAeA,EAAa7J,MAAM,MAAMiK,IAAI,SAAUC,GAAK,OAAOA,EAAEC,QAAQ,IAAK,OAASC,KAAK,OAIjGN,EAAkB,IAAI3L,EAAI6L,gBAAiC,SAAjBH,EAA0B,GAAKA,IAGzED,GADAE,EAAkBC,EAASM,cAAgBN,EAASO,YAAcP,EAASQ,aAAeR,EAASS,aAAeT,EAAS7H,WAAa6H,EAASrL,iBAAiB,aAAayL,QAAQ,aAAc,uBAC5KM,WAAWzK,MAAM,KAG/B,MAAT2J,IAEyBE,EAAvB1L,EAAI6L,gBAAkCF,EAAgBY,IAE/B,KAAlBd,EAAOzK,OAAgCsG,WAAWmE,EAAO,KAE5CnE,WAAWmE,EAAO,KAE7B,MAATD,IAEyBE,EAAvB1L,EAAI6L,gBAAkCF,EAAgBa,IAE/B,KAAlBf,EAAOzK,OAAgCsG,WAAWmE,EAAO,KAE5CnE,WAAWmE,EAAO,KAEnCC,GAAgB,GAEzBe,cAAe,SAAuBC,GACpC,IAEI3L,EACA4L,EACAC,EACA5L,EALA6L,EAAQ,GACRC,EAAaJ,GAAO1M,EAAIF,SAASiN,KAKrC,GAA0B,iBAAfD,GAA2BA,EAAW9L,OAK/C,IAFAA,GADA2L,GADAG,GAAwC,EAA3BA,EAAWtL,QAAQ,KAAYsL,EAAWd,QAAQ,QAAS,IAAM,IAC1DnK,MAAM,KAAK6E,OAAO,SAAUsG,GAAc,MAAsB,KAAfA,KACrDhM,OAEXD,EAAI,EAAGA,EAAIC,EAAQD,GAAK,EAC3B6L,EAAQD,EAAO5L,GAAGiL,QAAQ,QAAS,IAAInK,MAAM,KAC7CgL,EAAMI,mBAAmBL,EAAM,UAA2B,IAAbA,EAAM,QAAqBnH,EAAYwH,mBAAmBL,EAAM,KAAO,GAGxH,OAAOC,GAETK,SAAU,SAAkBC,GAC1B,MAAoB,iBAANA,GAAwB,OAANA,GAAcA,EAAEC,aAAeD,EAAEC,cAAgB1C,QAEnF2C,OAAQ,WAEN,IADA,IAAI7I,EAAO,GAAI8I,EAAQjK,UAAUrC,OACzBsM,KAAU9I,EAAM8I,GAAUjK,UAAWiK,GAG7C,IADA,IAAIC,EAAK7C,OAAOlG,EAAK,IACZzD,EAAI,EAAGA,EAAIyD,EAAKxD,OAAQD,GAAK,EAAG,CACvC,IAAIyM,EAAahJ,EAAKzD,GACtB,GAAIyM,MAAAA,EAEF,IADA,IAAIC,EAAY/C,OAAOC,KAAKD,OAAO8C,IAC1BE,EAAY,EAAGjJ,EAAMgJ,EAAUzM,OAAQ0M,EAAYjJ,EAAKiJ,GAAa,EAAG,CAC/E,IAAIC,EAAUF,EAAUC,GACpBE,EAAOlD,OAAOmD,yBAAyBL,EAAYG,QAC1ClI,IAATmI,GAAsBA,EAAKE,aACzB9C,GAAMkC,SAASK,EAAGI,KAAa3C,GAAMkC,SAASM,EAAWG,IAC3D3C,GAAMqC,OAAOE,EAAGI,GAAUH,EAAWG,KAC3B3C,GAAMkC,SAASK,EAAGI,KAAa3C,GAAMkC,SAASM,EAAWG,KACnEJ,EAAGI,GAAW,GACd3C,GAAMqC,OAAOE,EAAGI,GAAUH,EAAWG,KAErCJ,EAAGI,GAAWH,EAAWG,KAMnC,OAAOJ,IAIPQ,IACEjD,EAAUnM,EAAIa,cAAc,OACzB,CACLwO,MAAQhO,EAAIiO,YAAqC,IAAxBjO,EAAIiO,UAAUD,UACK,EAA/BhO,EAAIE,UAAUgO,gBAAwB,iBAAkBlO,GAASA,EAAImO,eAAiBxP,aAAeqB,EAAImO,eAGtHC,iBAAkBpO,EAAIE,UAAUmO,gBAAkBrO,EAAIsO,cAAiB,mBAAoBtO,EAAIE,WAA4C,EAA/BF,EAAIE,UAAUgO,gBAC1HK,wBAAyBvO,EAAIE,UAAUsO,iBAEvCtK,YACMvE,EAAQmL,EAAQnL,MACZ,eAAgBA,GAAS,qBAAsBA,GAAS,kBAAmBA,GAErF8O,aAAezO,EAAIiO,YAA+C,IAAlCjO,EAAIiO,UAAUS,kBACxC/O,EAAQmL,EAAQnL,MACZ,sBAAuBA,GAAS,mBAAoBA,GAAS,iBAAkBA,GAAS,kBAAmBA,GAAS,gBAAiBA,GAG/IgP,QAAU,WAGR,IAFA,IAAIhP,EAAQmL,EAAQnL,MAChByH,EAAS,yKAA2KvF,MAAM,KACrLd,EAAI,EAAGA,EAAIqG,EAAOpG,OAAQD,GAAK,EACtC,GAAIqG,EAAOrG,KAAMpB,EAAS,OAAO,EAEnC,OAAO,EANA,GASTiP,SACU,qBAAsB5O,GAAO,2BAA4BA,EAGnE6O,gBAAkB,WAChB,IAAIC,GAAkB,EACtB,IACE,IAAIC,EAAOrE,OAAOsE,eAAe,GAAI,UAAW,CAE9CC,IAAK,WACHH,GAAkB,KAGtB9O,EAAIlB,iBAAiB,sBAAuB,KAAMiQ,GAClD,MAAOhK,IAGT,OAAO+J,EAbQ,GAgBjBI,SACS,mBAAoBlP,IAK7BmP,EAKK,CACLC,OAAQpP,EAAIE,UAAUC,UAAUyB,MAAM,eAAiB5B,EAAIE,UAAUC,UAAUyB,MAAM,SACrFyN,SAAUrP,EAAIE,UAAUC,UAAUyB,MAAM,SACxC0N,UANIvE,EAAK/K,EAAIE,UAAUC,UAAUoP,cACD,GAAxBxE,EAAGvJ,QAAQ,WAAkBuJ,EAAGvJ,QAAQ,UAAY,GAAKuJ,EAAGvJ,QAAQ,WAAa,GAMzFgO,YAAa,+CAA+CC,KAAKzP,EAAIE,UAAUC,YAI/EuP,EAAc,SAAqB/C,QACrB,IAAXA,IAAoBA,EAAS,IAElC,IAAInO,EAAOE,KACXF,EAAKmO,OAASA,EAGdnO,EAAKmR,gBAAkB,GAEnBnR,EAAKmO,QAAUnO,EAAKmO,OAAOrI,IAC7BoG,OAAOC,KAAKnM,EAAKmO,OAAOrI,IAAIsG,QAAQ,SAAUgF,GAC5CpR,EAAK8F,GAAGsL,EAAWpR,EAAKmO,OAAOrI,GAAGsL,OAKpCC,EAAkB,CAAEC,WAAY,CAAEC,cAAc,IAEpDL,EAAYxN,UAAUoC,GAAK,SAAaoB,EAAQQ,EAAS8J,GACvD,IAAIxR,EAAOE,KACX,GAAuB,mBAAZwH,EAA0B,OAAO1H,EAC5C,IAAIyR,EAASD,EAAW,UAAY,OAKpC,OAJAtK,EAAO7D,MAAM,KAAK+I,QAAQ,SAAU9E,GAC7BtH,EAAKmR,gBAAgB7J,KAAUtH,EAAKmR,gBAAgB7J,GAAS,IAClEtH,EAAKmR,gBAAgB7J,GAAOmK,GAAQ/J,KAE/B1H,GAGTkR,EAAYxN,UAAUgO,KAAO,SAAexK,EAAQQ,EAAS8J,GAC3D,IAAIxR,EAAOE,KACX,GAAuB,mBAAZwH,EAA0B,OAAO1H,EAC5C,SAAS2R,IAEL,IADA,IAAI3L,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GAE3CyB,EAAQb,MAAM7G,EAAMgG,GACpBhG,EAAKwH,IAAIN,EAAQyK,GACbA,EAAYC,gBACPD,EAAYC,QAIvB,OADAD,EAAYC,QAAUlK,EACf1H,EAAK8F,GAAGoB,EAAQyK,EAAaH,IAGtCN,EAAYxN,UAAU8D,IAAM,SAAcN,EAAQQ,GAChD,IAAI1H,EAAOE,KACX,OAAKF,EAAKmR,iBACVjK,EAAO7D,MAAM,KAAK+I,QAAQ,SAAU9E,QACX,IAAZI,EACT1H,EAAKmR,gBAAgB7J,GAAS,GACrBtH,EAAKmR,gBAAgB7J,IAAUtH,EAAKmR,gBAAgB7J,GAAO9E,QACpExC,EAAKmR,gBAAgB7J,GAAO8E,QAAQ,SAAUyF,EAAcvH,IACtDuH,IAAiBnK,GAAYmK,EAAaD,SAAWC,EAAaD,UAAYlK,IAChF1H,EAAKmR,gBAAgB7J,GAAOK,OAAO2C,EAAO,OAK3CtK,GAGTkR,EAAYxN,UAAUoO,KAAO,WAEzB,IADA,IAAI9L,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GAE3C,IAEIiB,EACAhC,EACAvC,EAJA3C,EAAOE,KACX,OAAKF,EAAKmR,kBAIa,iBAAZnL,EAAK,IAAmB+L,MAAMC,QAAQhM,EAAK,KACpDkB,EAASlB,EAAK,GACdd,EAAOc,EAAKiM,MAAM,EAAGjM,EAAKxD,QAC1BG,EAAU3C,IAEVkH,EAASlB,EAAK,GAAGkB,OACjBhC,EAAOc,EAAK,GAAGd,KACfvC,EAAUqD,EAAK,GAAGrD,SAAW3C,IAEb+R,MAAMC,QAAQ9K,GAAUA,EAASA,EAAO7D,MAAM,MACpD+I,QAAQ,SAAU9E,GAC5B,GAAItH,EAAKmR,iBAAmBnR,EAAKmR,gBAAgB7J,GAAQ,CACvD,IAAIG,EAAW,GACfzH,EAAKmR,gBAAgB7J,GAAO8E,QAAQ,SAAUyF,GAC5CpK,EAAStE,KAAK0O,KAEhBpK,EAAS2E,QAAQ,SAAUyF,GACzBA,EAAahL,MAAMlE,EAASuC,SAI3BlF,GAGTkR,EAAYxN,UAAUwO,iBAAmB,SAA2BC,GAClE,IAAIC,EAAWlS,KACVkS,EAASC,SACdnG,OAAOC,KAAKiG,EAASC,SAASjG,QAAQ,SAAUkG,GAC9C,IAAIzS,EAASuS,EAASC,QAAQC,GAE1BzS,EAAOsO,QACT3B,GAAMqC,OAAOsD,EAAgBtS,EAAOsO,WAK1C+C,EAAYxN,UAAU6O,WAAa,SAAqBC,QAC7B,IAAlBA,IAA2BA,EAAgB,IAElD,IAAIJ,EAAWlS,KACVkS,EAASC,SACdnG,OAAOC,KAAKiG,EAASC,SAASjG,QAAQ,SAAUkG,GAC9C,IAAIzS,EAASuS,EAASC,QAAQC,GAC1BG,EAAeD,EAAcF,IAAe,GAE5CzS,EAAOuS,UACTlG,OAAOC,KAAKtM,EAAOuS,UAAUhG,QAAQ,SAAUsG,GAC7C,IAAIC,EAAa9S,EAAOuS,SAASM,GAE/BN,EAASM,GADe,mBAAfC,EACkBA,EAAWC,KAAKR,GAEhBO,IAK7B9S,EAAOiG,IAAMsM,EAAStM,IACxBoG,OAAOC,KAAKtM,EAAOiG,IAAIsG,QAAQ,SAAUyG,GACvCT,EAAStM,GAAG+M,EAAiBhT,EAAOiG,GAAG+M,MAKvChT,EAAOiT,QACTjT,EAAOiT,OAAOF,KAAKR,EAAnBvS,CAA6B4S,MAKnCpB,EAAgBC,WAAWyB,IAAM,SAAUzB,GAC7BpR,KACD8S,KADC9S,KAEN8S,IAAI1B,IAGZJ,EAAY+B,cAAgB,SAAwBpT,GAEhD,IADA,IAAIsO,EAAS,GAAIlI,EAAMpB,UAAUrC,OAAS,EAC1B,EAARyD,KAAYkI,EAAQlI,GAAQpB,UAAWoB,EAAM,GAEvD,IAAItC,EAAQzD,KACPyD,EAAMD,UAAU2O,UAAW1O,EAAMD,UAAU2O,QAAU,IAC1D,IAAIa,EAAOrT,EAAOqT,MAAWhH,OAAOC,KAAKxI,EAAMD,UAAU2O,SAAe,OAAI,IAAO7F,GAAMM,MAkBzF,OAjBAnJ,EAAMD,UAAU2O,QAAQa,GAAQrT,GAErBsT,OACTjH,OAAOC,KAAKtM,EAAOsT,OAAO/G,QAAQ,SAAUjH,GAC1CxB,EAAMD,UAAUyB,GAAOtF,EAAOsT,MAAMhO,KAIpCtF,EAAOuT,QACTlH,OAAOC,KAAKtM,EAAOuT,QAAQhH,QAAQ,SAAUjH,GAC3CxB,EAAMwB,GAAOtF,EAAOuT,OAAOjO,KAI3BtF,EAAOwT,SACTxT,EAAOwT,QAAQxM,MAAMlD,EAAOwK,GAEvBxK,GAGTuN,EAAY8B,IAAM,SAAcnT,GAE5B,IADA,IAAIsO,EAAS,GAAIlI,EAAMpB,UAAUrC,OAAS,EAC1B,EAARyD,KAAYkI,EAAQlI,GAAQpB,UAAWoB,EAAM,GAEvD,IAAItC,EAAQzD,KACZ,OAAI6R,MAAMC,QAAQnS,IAChBA,EAAOuM,QAAQ,SAAUkH,GAAK,OAAO3P,EAAMsP,cAAcK,KAClD3P,GAEFA,EAAMsP,cAAcpM,MAAMlD,EAAO,CAAE9D,GAAS0T,OAAQpF,KAG7DjC,OAAOsH,iBAAkBtC,EAAaG,GAslBtC,IAAIoC,EAAS,CACXC,WArlBF,WACE,IACIC,EACAC,EAFAC,EAAS3T,KAGT4T,EAAMD,EAAOC,IAEfH,OADiC,IAAxBE,EAAO1F,OAAOwF,MACfE,EAAO1F,OAAOwF,MAEdG,EAAI,GAAGC,YAGfH,OADkC,IAAzBC,EAAO1F,OAAOyF,OACdC,EAAO1F,OAAOyF,OAEdE,EAAI,GAAGE,aAEH,IAAVL,GAAeE,EAAOI,gBAA+B,IAAXL,GAAgBC,EAAOK,eAKtEP,EAAQA,EAAQQ,SAASL,EAAIlK,IAAI,gBAAiB,IAAMuK,SAASL,EAAIlK,IAAI,iBAAkB,IAC3FgK,EAASA,EAASO,SAASL,EAAIlK,IAAI,eAAgB,IAAMuK,SAASL,EAAIlK,IAAI,kBAAmB,IAE7F4C,GAAMqC,OAAOgF,EAAQ,CACnBF,MAAOA,EACPC,OAAQA,EACRQ,KAAMP,EAAOI,eAAiBN,EAAQC,MA4jBxCS,aAxjBF,WACE,IAAIR,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAEhBmG,EAAaT,EAAOS,WACpBC,EAAaV,EAAOO,KACpBI,EAAMX,EAAOY,aACbC,EAAWb,EAAOa,SAClBC,EAAYd,EAAOe,SAAWzG,EAAOyG,QAAQC,QAC7CC,EAAuBH,EAAYd,EAAOe,QAAQG,OAAOvS,OAASqR,EAAOkB,OAAOvS,OAChFuS,EAAST,EAAWrT,SAAU,IAAO4S,EAAO1F,OAAiB,YAC7D6G,EAAeL,EAAYd,EAAOe,QAAQG,OAAOvS,OAASuS,EAAOvS,OACjEyS,EAAW,GACXC,EAAa,GACbC,EAAkB,GAElBC,EAAejH,EAAOkH,mBACE,mBAAjBD,IACTA,EAAejH,EAAOkH,mBAAmB5M,KAAKoL,IAGhD,IAAIyB,EAAcnH,EAAOoH,kBACE,mBAAhBD,IACTA,EAAcnH,EAAOoH,kBAAkB9M,KAAKoL,IAG9C,IAAI2B,EAAyB3B,EAAOoB,SAASzS,OACzCiT,EAA2B5B,EAAOoB,SAASzS,OAE3CkT,EAAevH,EAAOuH,aACtBC,GAAiBP,EACjBQ,EAAgB,EAChBtL,EAAQ,EACZ,QAA0B,IAAfiK,EAAX,CAaA,IAAIsB,EAaAC,EAvBwB,iBAAjBJ,GAA0D,GAA7BA,EAAa1S,QAAQ,OAC3D0S,EAAgB5M,WAAW4M,EAAalI,QAAQ,IAAK,KAAO,IAAO+G,GAGrEV,EAAOkC,aAAeL,EAGlBlB,EAAOO,EAAOnL,IAAI,CAAEoM,WAAY,GAAIC,UAAW,KAC5ClB,EAAOnL,IAAI,CAAEsM,YAAa,GAAIC,aAAc,KAGtB,EAAzBhI,EAAOiI,kBAEPP,EADEQ,KAAKC,MAAMtB,EAAe7G,EAAOiI,mBAAqBpB,EAAenB,EAAO1F,OAAOiI,gBAC5DpB,EAEAqB,KAAKE,KAAKvB,EAAe7G,EAAOiI,iBAAmBjI,EAAOiI,gBAExD,SAAzBjI,EAAOqI,eAA2D,QAA/BrI,EAAOsI,sBAC5CZ,EAAyBQ,KAAKK,IAAIb,EAAwB1H,EAAOqI,cAAgBrI,EAAOiI,mBAS5F,IAHA,IAqIIO,EArIAP,EAAkBjI,EAAOiI,gBACzBQ,EAAef,EAAyBO,EACxCS,EAAiBR,KAAKC,MAAMtB,EAAe7G,EAAOiI,iBAC7C7T,EAAI,EAAGA,EAAIyS,EAAczS,GAAK,EAAG,CACxCuT,EAAY,EACZ,IAAIgB,EAAQ/B,EAAOtK,GAAGlI,GACtB,GAA6B,EAAzB4L,EAAOiI,gBAAqB,CAE9B,IAAIW,OAAqB,EACrBC,OAAS,EACTC,OAAM,EACyB,WAA/B9I,EAAOsI,qBAETQ,EAAM1U,GADNyU,EAASX,KAAKC,MAAM/T,EAAI6T,IACJA,GACPS,EAATG,GAA4BA,IAAWH,GAAkBI,IAAQb,EAAkB,IAE1EA,IADXa,GAAO,KAELA,EAAM,EACND,GAAU,GAGdD,EAAqBC,EAAWC,EAAMpB,EAA0BO,EAChEU,EACGlN,IAAI,CACHsN,4BAA6BH,EAC7BI,yBAA0BJ,EAC1BK,iBAAkBL,EAClBM,gBAAiBN,EACjBO,MAAOP,KAIXC,EAASzU,GADT0U,EAAMZ,KAAKC,MAAM/T,EAAIqU,IACDA,EAEtBE,EACGlN,IACE,WAAaiK,EAAOI,eAAiB,MAAQ,QACrC,IAARgD,GAAa9I,EAAOuH,cAAoBvH,EAAmB,aAAI,MAEjE1J,KAAK,qBAAsBuS,GAC3BvS,KAAK,kBAAmBwS,GAE7B,GAA6B,SAAzBH,EAAMlN,IAAI,WAAd,CAEA,GAA6B,SAAzBuE,EAAOqI,cAA0B,CACnC,IAAIe,EAAc/V,EAAIM,iBAAiBgV,EAAM,GAAI,MAC7CU,EAAmBV,EAAM,GAAG3V,MAAMoE,UAClCkS,EAAyBX,EAAM,GAAG3V,MAAMsE,gBAO5C,GANI+R,IACFV,EAAM,GAAG3V,MAAMoE,UAAY,QAEzBkS,IACFX,EAAM,GAAG3V,MAAMsE,gBAAkB,QAE/B0I,EAAOuJ,aACT5B,EAAYjC,EAAOI,eACf6C,EAAMpO,YAAW,GACjBoO,EAAM/N,aAAY,QAGtB,GAAI8K,EAAOI,eAAgB,CACzB,IAAIN,EAAQ7K,WAAWyO,EAAYxV,iBAAiB,UAChD4V,EAAc7O,WAAWyO,EAAYxV,iBAAiB,iBACtD6V,EAAe9O,WAAWyO,EAAYxV,iBAAiB,kBACvDiU,EAAalN,WAAWyO,EAAYxV,iBAAiB,gBACrDmU,EAAcpN,WAAWyO,EAAYxV,iBAAiB,iBACtD8V,EAAYN,EAAYxV,iBAAiB,cAE3C+T,EADE+B,GAA2B,eAAdA,EACHlE,EAAQqC,EAAaE,EAErBvC,EAAQgE,EAAcC,EAAe5B,EAAaE,MAE3D,CACL,IAAItC,EAAS9K,WAAWyO,EAAYxV,iBAAiB,WACjD+V,EAAahP,WAAWyO,EAAYxV,iBAAiB,gBACrDgW,EAAgBjP,WAAWyO,EAAYxV,iBAAiB,mBACxDkU,EAAYnN,WAAWyO,EAAYxV,iBAAiB,eACpDoU,EAAerN,WAAWyO,EAAYxV,iBAAiB,kBACvDiW,EAAcT,EAAYxV,iBAAiB,cAE7C+T,EADEkC,GAA+B,eAAhBA,EACLpE,EAASqC,EAAYE,EAErBvC,EAASkE,EAAaC,EAAgB9B,EAAYE,EAIhEqB,IACFV,EAAM,GAAG3V,MAAMoE,UAAYiS,GAEzBC,IACFX,EAAM,GAAG3V,MAAMsE,gBAAkBgS,GAE/BtJ,EAAOuJ,eAAgB5B,EAAYO,KAAKC,MAAMR,SAElDA,GAAavB,GAAepG,EAAOqI,cAAgB,GAAKd,GAAiBvH,EAAOqI,cAC5ErI,EAAOuJ,eAAgB5B,EAAYO,KAAKC,MAAMR,IAE9Cf,EAAOxS,KACLsR,EAAOI,eACTc,EAAOxS,GAAGpB,MAAMwS,MAAQmC,EAAY,KAEpCf,EAAOxS,GAAGpB,MAAMyS,OAASkC,EAAY,MAIvCf,EAAOxS,KACTwS,EAAOxS,GAAG0V,gBAAkBnC,GAE9BX,EAAgBhS,KAAK2S,GAGjB3H,EAAO+J,gBACTvC,EAAgBA,EAAiBG,EAAY,EAAMF,EAAgB,EAAKF,EAClD,IAAlBE,GAA6B,IAANrT,IAAWoT,EAAgBA,EAAiBpB,EAAa,EAAKmB,GAC/E,IAANnT,IAAWoT,EAAgBA,EAAiBpB,EAAa,EAAKmB,GAC9DW,KAAK8B,IAAIxC,GAAiB,OAAYA,EAAgB,GACtDxH,EAAOuJ,eAAgB/B,EAAgBU,KAAKC,MAAMX,IAClD,EAAUxH,EAAOiK,gBAAmB,GAAKnD,EAAS9R,KAAKwS,GAC3DT,EAAW/R,KAAKwS,KAEZxH,EAAOuJ,eAAgB/B,EAAgBU,KAAKC,MAAMX,IAClD,EAAUxH,EAAOiK,gBAAmB,GAAKnD,EAAS9R,KAAKwS,GAC3DT,EAAW/R,KAAKwS,GAChBA,EAAgBA,EAAgBG,EAAYJ,GAG9C7B,EAAOkC,aAAeD,EAAYJ,EAElCE,EAAgBE,EAEhBxL,GAAS,GAcX,GAZAuJ,EAAOkC,YAAcM,KAAKK,IAAI7C,EAAOkC,YAAaxB,GAAce,EAI9Dd,GAAOE,IAA+B,UAAlBvG,EAAOkK,QAAwC,cAAlBlK,EAAOkK,SACxD/D,EAAW1K,IAAI,CAAE+J,MAASE,EAAOkC,YAAc5H,EAAOuH,aAAgB,OAEnEnG,GAAQY,UAAWhC,EAAOmK,iBACzBzE,EAAOI,eAAkBK,EAAW1K,IAAI,CAAE+J,MAASE,EAAOkC,YAAc5H,EAAOuH,aAAgB,OAC5FpB,EAAW1K,IAAI,CAAEgK,OAAUC,EAAOkC,YAAc5H,EAAOuH,aAAgB,QAGnD,EAAzBvH,EAAOiI,kBACTvC,EAAOkC,aAAeD,EAAY3H,EAAOuH,cAAgBG,EACzDhC,EAAOkC,YAAcM,KAAKE,KAAK1C,EAAOkC,YAAc5H,EAAOiI,iBAAmBjI,EAAOuH,aACjF7B,EAAOI,eAAkBK,EAAW1K,IAAI,CAAE+J,MAASE,EAAOkC,YAAc5H,EAAOuH,aAAgB,OAC5FpB,EAAW1K,IAAI,CAAEgK,OAAUC,EAAOkC,YAAc5H,EAAOuH,aAAgB,OAC1EvH,EAAO+J,gBAAgB,CACzBvB,EAAgB,GAChB,IAAK,IAAI4B,EAAM,EAAGA,EAAMtD,EAASzS,OAAQ+V,GAAO,EAAG,CACjD,IAAIC,EAAiBvD,EAASsD,GAC1BpK,EAAOuJ,eAAgBc,EAAiBnC,KAAKC,MAAMkC,IACnDvD,EAASsD,GAAO1E,EAAOkC,YAAcd,EAAS,IAAM0B,EAAcxT,KAAKqV,GAE7EvD,EAAW0B,EAKf,IAAKxI,EAAO+J,eAAgB,CAC1BvB,EAAgB,GAChB,IAAK,IAAI8B,EAAM,EAAGA,EAAMxD,EAASzS,OAAQiW,GAAO,EAAG,CACjD,IAAIC,EAAmBzD,EAASwD,GAC5BtK,EAAOuJ,eAAgBgB,EAAmBrC,KAAKC,MAAMoC,IACrDzD,EAASwD,IAAQ5E,EAAOkC,YAAcxB,GACxCoC,EAAcxT,KAAKuV,GAGvBzD,EAAW0B,EACmF,EAA1FN,KAAKC,MAAMzC,EAAOkC,YAAcxB,GAAc8B,KAAKC,MAAMrB,EAASA,EAASzS,OAAS,KACtFyS,EAAS9R,KAAK0Q,EAAOkC,YAAcxB,GAYvC,GATwB,IAApBU,EAASzS,SAAgByS,EAAW,CAAC,IAEb,IAAxB9G,EAAOuH,eACL7B,EAAOI,eACLO,EAAOO,EAAOnL,IAAI,CAAEoM,WAAaN,EAAe,OAC7CX,EAAOnL,IAAI,CAAEsM,YAAcR,EAAe,OAC1CX,EAAOnL,IAAI,CAAEuM,aAAeT,EAAe,QAGlDvH,EAAOwK,yBAA0B,CACnC,IAAIC,EAAgB,EAKpB,GAJAzD,EAAgB/I,QAAQ,SAAUyM,GAChCD,GAAiBC,GAAkB1K,EAAOuH,aAAevH,EAAOuH,aAAe,MAEjFkD,GAAiBzK,EAAOuH,cACJnB,EAAY,CAC9B,IAAIuE,GAAmBvE,EAAaqE,GAAiB,EACrD3D,EAAS7I,QAAQ,SAAU2M,EAAMC,GAC/B/D,EAAS+D,GAAaD,EAAOD,IAE/B5D,EAAW9I,QAAQ,SAAU2M,EAAMC,GACjC9D,EAAW8D,GAAaD,EAAOD,KAKrCtM,GAAMqC,OAAOgF,EAAQ,CACnBkB,OAAQA,EACRE,SAAUA,EACVC,WAAYA,EACZC,gBAAiBA,IAGfH,IAAiBF,GACnBjB,EAAO/B,KAAK,sBAEVmD,EAASzS,SAAWgT,IAClB3B,EAAO1F,OAAO8K,eAAiBpF,EAAOqF,gBAC1CrF,EAAO/B,KAAK,yBAEVoD,EAAW1S,SAAWiT,GACxB5B,EAAO/B,KAAK,2BAGV3D,EAAOgL,qBAAuBhL,EAAOiL,wBACvCvF,EAAOwF,uBAiSTC,iBA7RF,SAA2BC,GACzB,IAGIhX,EAHAsR,EAAS3T,KACTsZ,EAAe,GACfC,EAAY,EAQhB,GANqB,iBAAVF,EACT1F,EAAO6F,cAAcH,IACF,IAAVA,GACT1F,EAAO6F,cAAc7F,EAAO1F,OAAOoL,OAGD,SAAhC1F,EAAO1F,OAAOqI,eAA0D,EAA9B3C,EAAO1F,OAAOqI,cAC1D,IAAKjU,EAAI,EAAGA,EAAI8T,KAAKE,KAAK1C,EAAO1F,OAAOqI,eAAgBjU,GAAK,EAAG,CAC9D,IAAI+H,EAAQuJ,EAAO8F,YAAcpX,EACjC,GAAI+H,EAAQuJ,EAAOkB,OAAOvS,OAAU,MACpCgX,EAAarW,KAAK0Q,EAAOkB,OAAOtK,GAAGH,GAAO,SAG5CkP,EAAarW,KAAK0Q,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,aAAa,IAIzD,IAAKpX,EAAI,EAAGA,EAAIiX,EAAahX,OAAQD,GAAK,EACxC,QAA+B,IAApBiX,EAAajX,GAAoB,CAC1C,IAAIqR,EAAS4F,EAAajX,GAAGyG,aAC7ByQ,EAAqBA,EAAT7F,EAAqBA,EAAS6F,EAK1CA,GAAa5F,EAAOS,WAAW1K,IAAI,SAAW6P,EAAY,OAgQ9DJ,mBA7PF,WAGE,IAFA,IACItE,EADS7U,KACO6U,OACXxS,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EACtCwS,EAAOxS,GAAGqX,kBAHC1Z,KAG0B+T,eAAiBc,EAAOxS,GAAGsX,WAAa9E,EAAOxS,GAAGuX,WA0PzFC,qBAtPF,SAA+BC,QACV,IAAdA,IAAuBA,EAAa9Z,MAAQA,KAAK8Z,WAAc,GAEpE,IAAInG,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAEhB4G,EAASlB,EAAOkB,OAChBP,EAAMX,EAAOY,aAEjB,GAAsB,IAAlBM,EAAOvS,OAAX,MAC2C,IAAhCuS,EAAO,GAAG6E,mBAAqC/F,EAAOwF,qBAEjE,IAAIY,GAAgBD,EAChBxF,IAAOyF,EAAeD,GAG1BjF,EAAO5Q,YAAYgK,EAAO+L,mBAE1BrG,EAAOsG,qBAAuB,GAC9BtG,EAAOuG,cAAgB,GAEvB,IAAK,IAAI7X,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAAG,CACzC,IAAIuU,EAAQ/B,EAAOxS,GACf8X,GACDJ,GAAgB9L,EAAO+J,eAAiBrE,EAAOyG,eAAiB,GAAMxD,EAAM8C,oBAC1E9C,EAAMmB,gBAAkB9J,EAAOuH,cACpC,GAAIvH,EAAOiL,sBAAuB,CAChC,IAAImB,IAAgBN,EAAenD,EAAM8C,mBACrCY,EAAaD,EAAc1G,EAAOsB,gBAAgB5S,IACtB,GAAfgY,GAAoBA,EAAc1G,EAAOO,MAC/B,EAAboG,GAAkBA,GAAc3G,EAAOO,MACvCmG,GAAe,GAAKC,GAAc3G,EAAOO,QAErDP,EAAOuG,cAAcjX,KAAK2T,GAC1BjD,EAAOsG,qBAAqBhX,KAAKZ,GACjCwS,EAAOtK,GAAGlI,GAAGsB,SAASsK,EAAO+L,oBAGjCpD,EAAM2D,SAAWjG,GAAO6F,EAAgBA,EAE1CxG,EAAOuG,cAAgB3X,EAAEoR,EAAOuG,iBA+MhCM,eA5MF,SAAyBV,QACJ,IAAdA,IAAuBA,EAAa9Z,MAAQA,KAAK8Z,WAAc,GAEpE,IAAInG,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAEhBwM,EAAiB9G,EAAO+G,eAAiB/G,EAAOyG,eAChDG,EAAW5G,EAAO4G,SAClBI,EAAchH,EAAOgH,YACrBC,EAAQjH,EAAOiH,MACfC,EAAeF,EACfG,EAASF,EACU,IAAnBH,EAGFG,EADAD,IADAJ,EAAW,IAKXI,GADAJ,GAAYT,EAAYnG,EAAOyG,gBAAkB,IACvB,EAC1BQ,EAAoB,GAAZL,GAEVjO,GAAMqC,OAAOgF,EAAQ,CACnB4G,SAAUA,EACVI,YAAaA,EACbC,MAAOA,KAGL3M,EAAOgL,qBAAuBhL,EAAOiL,wBAAyBvF,EAAOkG,qBAAqBC,GAE1Fa,IAAgBE,GAClBlH,EAAO/B,KAAK,yBAEVgJ,IAAUE,GACZnH,EAAO/B,KAAK,oBAETiJ,IAAiBF,GAAiBG,IAAWF,IAChDjH,EAAO/B,KAAK,YAGd+B,EAAO/B,KAAK,WAAY2I,IAsKxBQ,oBAnKF,WACE,IAWIC,EAXArH,EAAS3T,KAET6U,EAASlB,EAAOkB,OAChB5G,EAAS0F,EAAO1F,OAChBmG,EAAaT,EAAOS,WACpBqF,EAAc9F,EAAO8F,YACrBwB,EAAYtH,EAAOsH,UACnBxG,EAAYd,EAAOe,SAAWzG,EAAOyG,QAAQC,QAEjDE,EAAO5Q,YAAcgK,EAAuB,iBAAI,IAAOA,EAAqB,eAAI,IAAOA,EAAqB,eAAI,IAAOA,EAAgC,0BAAI,IAAOA,EAA8B,wBAAI,IAAOA,EAA8B,0BAIvO+M,EADEvG,EACYd,EAAOS,WAAWzI,KAAM,IAAOsC,EAAiB,WAAI,6BAAgCwL,EAAc,MAElG5E,EAAOtK,GAAGkP,IAId9V,SAASsK,EAAOiN,kBAExBjN,EAAOkN,OAELH,EAAY7W,SAAS8J,EAAOmN,qBAC9BhH,EACGrT,SAAU,IAAOkN,EAAiB,WAAI,SAAYA,EAA0B,oBAAI,8BAAiCgN,EAAY,MAC7HtX,SAASsK,EAAOoN,2BAEnBjH,EACGrT,SAAU,IAAOkN,EAAiB,WAAI,IAAOA,EAA0B,oBAAI,6BAAgCgN,EAAY,MACvHtX,SAASsK,EAAOoN,4BAIvB,IAAIC,EAAYN,EAAY9P,QAAS,IAAO+C,EAAiB,YAAI1D,GAAG,GAAG5G,SAASsK,EAAOsN,gBACnFtN,EAAOkN,MAA6B,IAArBG,EAAUhZ,SAC3BgZ,EAAYzG,EAAOtK,GAAG,IACZ5G,SAASsK,EAAOsN,gBAG5B,IAAIC,EAAYR,EAAY1P,QAAS,IAAO2C,EAAiB,YAAI1D,GAAG,GAAG5G,SAASsK,EAAOwN,gBACnFxN,EAAOkN,MAA6B,IAArBK,EAAUlZ,SAC3BkZ,EAAY3G,EAAOtK,IAAI,IACb5G,SAASsK,EAAOwN,gBAExBxN,EAAOkN,OAELG,EAAUnX,SAAS8J,EAAOmN,qBAC5BhH,EACGrT,SAAU,IAAOkN,EAAiB,WAAI,SAAYA,EAA0B,oBAAI,8BAAkCqN,EAAU/W,KAAK,2BAA8B,MAC/JZ,SAASsK,EAAOyN,yBAEnBtH,EACGrT,SAAU,IAAOkN,EAAiB,WAAI,IAAOA,EAA0B,oBAAI,6BAAiCqN,EAAU/W,KAAK,2BAA8B,MACzJZ,SAASsK,EAAOyN,yBAEjBF,EAAUrX,SAAS8J,EAAOmN,qBAC5BhH,EACGrT,SAAU,IAAOkN,EAAiB,WAAI,SAAYA,EAA0B,oBAAI,8BAAkCuN,EAAUjX,KAAK,2BAA8B,MAC/JZ,SAASsK,EAAO0N,yBAEnBvH,EACGrT,SAAU,IAAOkN,EAAiB,WAAI,IAAOA,EAA0B,oBAAI,6BAAiCuN,EAAUjX,KAAK,2BAA8B,MACzJZ,SAASsK,EAAO0N,2BAoGvBC,kBA/FF,SAA4BC,GAC1B,IASI/C,EATAnF,EAAS3T,KACT8Z,EAAYnG,EAAOY,aAAeZ,EAAOmG,WAAanG,EAAOmG,UAC7D9E,EAAarB,EAAOqB,WACpBD,EAAWpB,EAAOoB,SAClB9G,EAAS0F,EAAO1F,OAChB6N,EAAgBnI,EAAO8F,YACvBsC,EAAoBpI,EAAOsH,UAC3Be,EAAoBrI,EAAOmF,UAC3BW,EAAcoC,EAElB,QAA2B,IAAhBpC,EAA6B,CACtC,IAAK,IAAIpX,EAAI,EAAGA,EAAI2S,EAAW1S,OAAQD,GAAK,OACT,IAAtB2S,EAAW3S,EAAI,GACpByX,GAAa9E,EAAW3S,IAAMyX,EAAY9E,EAAW3S,EAAI,IAAO2S,EAAW3S,EAAI,GAAK2S,EAAW3S,IAAM,EACvGoX,EAAcpX,EACLyX,GAAa9E,EAAW3S,IAAMyX,EAAY9E,EAAW3S,EAAI,KAClEoX,EAAcpX,EAAI,GAEXyX,GAAa9E,EAAW3S,KACjCoX,EAAcpX,GAId4L,EAAOgO,sBACLxC,EAAc,QAA4B,IAAhBA,KAA+BA,EAAc,GAS/E,IALEX,EADiC,GAA/B/D,EAASjS,QAAQgX,GACP/E,EAASjS,QAAQgX,GAEjB3D,KAAKC,MAAMqD,EAAcxL,EAAOiK,kBAE7BnD,EAASzS,SAAUwW,EAAY/D,EAASzS,OAAS,GAC9DmX,IAAgBqC,EAApB,CASA,IAAIb,EAAYhH,SAASN,EAAOkB,OAAOtK,GAAGkP,GAAalV,KAAK,4BAA8BkV,EAAa,IAEvGnN,GAAMqC,OAAOgF,EAAQ,CACnBmF,UAAWA,EACXmC,UAAWA,EACXa,cAAeA,EACfrC,YAAaA,IAEf9F,EAAO/B,KAAK,qBACZ+B,EAAO/B,KAAK,mBACRmK,IAAsBd,GACxBtH,EAAO/B,KAAK,mBAEd+B,EAAO/B,KAAK,oBArBNkH,IAAckD,IAChBrI,EAAOmF,UAAYA,EACnBnF,EAAO/B,KAAK,qBA2DhBsK,mBArCF,SAA6B7V,GAC3B,IAAIsN,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChB2I,EAAQrU,EAAE8D,EAAEC,QAAQoF,QAAS,IAAOuC,EAAiB,YAAI,GACzDkO,GAAa,EACjB,GAAIvF,EACF,IAAK,IAAIvU,EAAI,EAAGA,EAAIsR,EAAOkB,OAAOvS,OAAQD,GAAK,EACzCsR,EAAOkB,OAAOxS,KAAOuU,IAASuF,GAAa,GAInD,IAAIvF,IAASuF,EAUX,OAFAxI,EAAOyI,kBAAerV,OACtB4M,EAAO0I,kBAAetV,GARtB4M,EAAOyI,aAAexF,EAClBjD,EAAOe,SAAWf,EAAO1F,OAAOyG,QAAQC,QAC1ChB,EAAO0I,aAAepI,SAAS1R,EAAEqU,GAAOrS,KAAK,2BAA4B,IAEzEoP,EAAO0I,aAAe9Z,EAAEqU,GAAOxM,QAO/B6D,EAAOqO,0BAA+CvV,IAAxB4M,EAAO0I,cAA8B1I,EAAO0I,eAAiB1I,EAAO8F,aACpG9F,EAAO2I,wBAuFX,IAAIxC,EAAY,CACdjN,aAxEF,SAAuBC,QACP,IAATA,IAAkBA,EAAO9M,KAAK+T,eAAiB,IAAM,KAE1D,IAEI9F,EAFSjO,KAEOiO,OAChBqG,EAHStU,KAGIuU,aACbuF,EAJS9Z,KAIU8Z,UACnB1F,EALSpU,KAKWoU,WAExB,GAAInG,EAAOsO,iBACT,OAAOjI,GAAOwF,EAAYA,EAG5B,IAAI0C,EAAmBlQ,GAAMO,aAAauH,EAAW,GAAItH,GAGzD,OAFIwH,IAAOkI,GAAoBA,GAExBA,GAAoB,GAwD3BC,aArDF,SAAuB3C,EAAW4C,GAChC,IAAI/I,EAAS3T,KACTsU,EAAMX,EAAOY,aACbtG,EAAS0F,EAAO1F,OAChBmG,EAAaT,EAAOS,WACpBmG,EAAW5G,EAAO4G,SAClBoC,EAAI,EACJC,EAAI,EAGJjJ,EAAOI,eACT4I,EAAIrI,GAAOwF,EAAYA,EAEvB8C,EAAI9C,EAGF7L,EAAOuJ,eACTmF,EAAIxG,KAAKC,MAAMuG,GACfC,EAAIzG,KAAKC,MAAMwG,IAGZ3O,EAAOsO,mBACNlN,GAAQU,aAAgBqE,EAAW/O,UAAW,eAAiBsX,EAAI,OAASC,EAAI,YAC7ExI,EAAW/O,UAAW,aAAesX,EAAI,OAASC,EAAI,QAE/DjJ,EAAOkJ,kBAAoBlJ,EAAOmG,UAClCnG,EAAOmG,UAAYnG,EAAOI,eAAiB4I,EAAIC,EAI/C,IAAInC,EAAiB9G,EAAO+G,eAAiB/G,EAAOyG,gBAC7B,IAAnBK,EACY,GAECX,EAAYnG,EAAOyG,gBAAkB,KAElCG,GAClB5G,EAAO6G,eAAeV,GAGxBnG,EAAO/B,KAAK,eAAgB+B,EAAOmG,UAAW4C,IAc9CtC,aAXF,WACE,OAASpa,KAAK+U,SAAS,IAWvB2F,aARF,WACE,OAAS1a,KAAK+U,SAAS/U,KAAK+U,SAASzS,OAAS,KAoFhD,IAAIwa,EAAe,CACjBtD,cA3EF,SAAwB/T,EAAUiX,GACnB1c,KAENoU,WAAW5O,WAAWC,GAFhBzF,KAIN4R,KAAK,gBAAiBnM,EAAUiX,IAuEvCK,gBApEF,SAA0BC,EAAcC,QAChB,IAAjBD,IAA0BA,GAAe,GAE9C,IAAIrJ,EAAS3T,KACTyZ,EAAc9F,EAAO8F,YACrBxL,EAAS0F,EAAO1F,OAChB6N,EAAgBnI,EAAOmI,cACvB7N,EAAOiP,YACTvJ,EAAOyF,mBAGT,IAAI+D,EAAMF,EASV,GARKE,IACgCA,EAAjBrB,EAAdrC,EAAqC,OAChCA,EAAcqC,EAAuB,OACjC,SAGfnI,EAAO/B,KAAK,mBAERoL,GAAgBvD,IAAgBqC,EAAe,CACjD,GAAY,UAARqB,EAEF,YADAxJ,EAAO/B,KAAK,6BAGd+B,EAAO/B,KAAK,8BACA,SAARuL,EACFxJ,EAAO/B,KAAK,4BAEZ+B,EAAO/B,KAAK,8BAwChBzJ,cAnCF,SAA0B6U,EAAcC,QAChB,IAAjBD,IAA0BA,GAAe,GAE9C,IAAIrJ,EAAS3T,KACTyZ,EAAc9F,EAAO8F,YACrBqC,EAAgBnI,EAAOmI,cAC3BnI,EAAOyJ,WAAY,EACnBzJ,EAAO6F,cAAc,GAErB,IAAI2D,EAAMF,EASV,GARKE,IACgCA,EAAjBrB,EAAdrC,EAAqC,OAChCA,EAAcqC,EAAuB,OACjC,SAGfnI,EAAO/B,KAAK,iBAERoL,GAAgBvD,IAAgBqC,EAAe,CACjD,GAAY,UAARqB,EAEF,YADAxJ,EAAO/B,KAAK,2BAGd+B,EAAO/B,KAAK,4BACA,SAARuL,EACFxJ,EAAO/B,KAAK,0BAEZ+B,EAAO/B,KAAK,6BA2QlB,IAAIgF,EAAQ,CACVyG,QAjQF,SAAkBjT,EAAOiP,EAAO2D,EAAcM,QAC7B,IAAVlT,IAAmBA,EAAQ,QACjB,IAAViP,IAAmBA,EAAQrZ,KAAKiO,OAAOoL,YACtB,IAAjB2D,IAA0BA,GAAe,GAE9C,IAAIrJ,EAAS3T,KACTud,EAAanT,EACbmT,EAAa,IAAKA,EAAa,GAEnC,IAAItP,EAAS0F,EAAO1F,OAChB8G,EAAWpB,EAAOoB,SAClBC,EAAarB,EAAOqB,WACpB8G,EAAgBnI,EAAOmI,cACvBrC,EAAc9F,EAAO8F,YACrBnF,EAAMX,EAAOY,aACjB,GAAIZ,EAAOyJ,WAAanP,EAAOuP,+BAC7B,OAAO,EAGT,IAAI1E,EAAY3C,KAAKC,MAAMmH,EAAatP,EAAOiK,gBAC3CY,GAAa/D,EAASzS,SAAUwW,EAAY/D,EAASzS,OAAS,IAE7DmX,GAAexL,EAAOwP,cAAgB,MAAQ3B,GAAiB,IAAMkB,GACxErJ,EAAO/B,KAAK,0BAGd,IAuBIqL,EAvBAnD,GAAa/E,EAAS+D,GAM1B,GAHAnF,EAAO6G,eAAeV,GAGlB7L,EAAOgO,oBACT,IAAK,IAAI5Z,EAAI,EAAGA,EAAI2S,EAAW1S,OAAQD,GAAK,GACrC8T,KAAKC,MAAkB,IAAZ0D,IAAoB3D,KAAKC,MAAsB,IAAhBpB,EAAW3S,MACxDkb,EAAalb,GAKnB,GAAIsR,EAAO+J,aAAeH,IAAe9D,EAAa,CACpD,IAAK9F,EAAOgK,gBAAkB7D,EAAYnG,EAAOmG,WAAaA,EAAYnG,EAAOyG,eAC/E,OAAO,EAET,IAAKzG,EAAOiK,gBAAkB9D,EAAYnG,EAAOmG,WAAaA,EAAYnG,EAAO+G,iBAC1EjB,GAAe,KAAO8D,EAAc,OAAO,EAWpD,OANgCN,EAAfxD,EAAb8D,EAAwC,OACnCA,EAAa9D,EAA2B,OAC9B,QAIdnF,IAAQwF,IAAcnG,EAAOmG,YAAgBxF,GAAOwF,IAAcnG,EAAOmG,WAC5EnG,EAAOiI,kBAAkB2B,GAErBtP,EAAOiP,YACTvJ,EAAOyF,mBAETzF,EAAOoH,sBACe,UAAlB9M,EAAOkK,QACTxE,EAAO8I,aAAa3C,GAEJ,UAAdmD,IACFtJ,EAAOoJ,gBAAgBC,EAAcC,GACrCtJ,EAAOxL,cAAc6U,EAAcC,KAE9B,IAGK,IAAV5D,GAAgBhK,GAAQ7J,YAS1BmO,EAAO6F,cAAcH,GACrB1F,EAAO8I,aAAa3C,GACpBnG,EAAOiI,kBAAkB2B,GACzB5J,EAAOoH,sBACPpH,EAAO/B,KAAK,wBAAyByH,EAAOiE,GAC5C3J,EAAOoJ,gBAAgBC,EAAcC,GAChCtJ,EAAOyJ,YACVzJ,EAAOyJ,WAAY,EACdzJ,EAAOkK,gCACVlK,EAAOkK,8BAAgC,SAAuBxX,GACvDsN,IAAUA,EAAOmK,WAClBzX,EAAEC,SAAWtG,OACjB2T,EAAOS,WAAW,GAAG/T,oBAAoB,gBAAiBsT,EAAOkK,+BACjElK,EAAOS,WAAW,GAAG/T,oBAAoB,sBAAuBsT,EAAOkK,+BACvElK,EAAOkK,8BAAgC,YAChClK,EAAOkK,8BACdlK,EAAOxL,cAAc6U,EAAcC,MAGvCtJ,EAAOS,WAAW,GAAGhU,iBAAiB,gBAAiBuT,EAAOkK,+BAC9DlK,EAAOS,WAAW,GAAGhU,iBAAiB,sBAAuBuT,EAAOkK,kCA5BtElK,EAAO6F,cAAc,GACrB7F,EAAO8I,aAAa3C,GACpBnG,EAAOiI,kBAAkB2B,GACzB5J,EAAOoH,sBACPpH,EAAO/B,KAAK,wBAAyByH,EAAOiE,GAC5C3J,EAAOoJ,gBAAgBC,EAAcC,GACrCtJ,EAAOxL,cAAc6U,EAAcC,KA0B9B,IAwJPc,YArJF,SAAsB3T,EAAOiP,EAAO2D,EAAcM,QACjC,IAAVlT,IAAmBA,EAAQ,QACjB,IAAViP,IAAmBA,EAAQrZ,KAAKiO,OAAOoL,YACtB,IAAjB2D,IAA0BA,GAAe,GAE9C,IACIgB,EAAW5T,EAKf,OANapK,KAEFiO,OAAOkN,OAChB6C,GAHWhe,KAGQie,cAHRje,KAMCqd,QAAQW,EAAU3E,EAAO2D,EAAcM,IA2IrDY,UAvIF,SAAoB7E,EAAO2D,EAAcM,QACxB,IAAVjE,IAAmBA,EAAQrZ,KAAKiO,OAAOoL,YACtB,IAAjB2D,IAA0BA,GAAe,GAE9C,IAAIrJ,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBmP,EAAYzJ,EAAOyJ,UACvB,OAAInP,EAAOkN,MACLiC,IACJzJ,EAAOwK,UAEPxK,EAAOyK,YAAczK,EAAOS,WAAW,GAAGjL,WACnCwK,EAAO0J,QAAQ1J,EAAO8F,YAAcxL,EAAOiK,eAAgBmB,EAAO2D,EAAcM,IAElF3J,EAAO0J,QAAQ1J,EAAO8F,YAAcxL,EAAOiK,eAAgBmB,EAAO2D,EAAcM,IA0HvFe,UAtHF,SAAoBhF,EAAO2D,EAAcM,QACxB,IAAVjE,IAAmBA,EAAQrZ,KAAKiO,OAAOoL,YACtB,IAAjB2D,IAA0BA,GAAe,GAE9C,IAAIrJ,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBmP,EAAYzJ,EAAOyJ,UACnBrI,EAAWpB,EAAOoB,SAClBC,EAAarB,EAAOqB,WACpBT,EAAeZ,EAAOY,aAE1B,GAAItG,EAAOkN,KAAM,CACf,GAAIiC,EAAa,OAAO,EACxBzJ,EAAOwK,UAEPxK,EAAOyK,YAAczK,EAAOS,WAAW,GAAGjL,WAG5C,SAASmV,EAAUC,GACjB,OAAIA,EAAM,GAAapI,KAAKC,MAAMD,KAAK8B,IAAIsG,IACpCpI,KAAKC,MAAMmI,GAEpB,IAMIC,EANAC,EAAsBH,EALV/J,EAAeZ,EAAOmG,WAAanG,EAAOmG,WAMtD4E,EAAqB3J,EAAS3H,IAAI,SAAUmR,GAAO,OAAOD,EAAUC,KAIpEI,GAHuB3J,EAAW5H,IAAI,SAAUmR,GAAO,OAAOD,EAAUC,KAE1DxJ,EAAS2J,EAAmB5b,QAAQ2b,IACvC1J,EAAS2J,EAAmB5b,QAAQ2b,GAAuB,IAM1E,YAJwB,IAAbE,IACTH,EAAYxJ,EAAWlS,QAAQ6b,IACf,IAAKH,EAAY7K,EAAO8F,YAAc,GAEjD9F,EAAO0J,QAAQmB,EAAWnF,EAAO2D,EAAcM,IAsFtDsB,WAlFF,SAAqBvF,EAAO2D,EAAcM,GAKxC,YAJe,IAAVjE,IAAmBA,EAAQrZ,KAAKiO,OAAOoL,YACtB,IAAjB2D,IAA0BA,GAAe,GAEjChd,KACCqd,QADDrd,KACgByZ,YAAaJ,EAAO2D,EAAcM,IA8E/DuB,eA1EF,SAAyBxF,EAAO2D,EAAcM,QAC7B,IAAVjE,IAAmBA,EAAQrZ,KAAKiO,OAAOoL,YACtB,IAAjB2D,IAA0BA,GAAe,GAE9C,IAAIrJ,EAAS3T,KACToK,EAAQuJ,EAAO8F,YACfX,EAAY3C,KAAKC,MAAMhM,EAAQuJ,EAAO1F,OAAOiK,gBAEjD,GAAIY,EAAYnF,EAAOoB,SAASzS,OAAS,EAAG,CAC1C,IAAIwX,EAAYnG,EAAOY,aAAeZ,EAAOmG,WAAanG,EAAOmG,UAE7DgF,EAAcnL,EAAOoB,SAAS+D,IACnBnF,EAAOoB,SAAS+D,EAAY,GAECgG,GAAe,EAAtDhF,EAAYgF,IACf1U,EAAQuJ,EAAO1F,OAAOiK,gBAI1B,OAAOvE,EAAO0J,QAAQjT,EAAOiP,EAAO2D,EAAcM,IAwDlDhB,oBArDF,WACE,IAMIrB,EANAtH,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBmG,EAAaT,EAAOS,WAEpBkC,EAAyC,SAAzBrI,EAAOqI,cAA2B3C,EAAOoL,uBAAyB9Q,EAAOqI,cACzF0I,EAAerL,EAAO0I,aAE1B,GAAIpO,EAAOkN,KAAM,CACf,GAAIxH,EAAOyJ,UAAa,OACxBnC,EAAYhH,SAAS1R,EAAEoR,EAAOyI,cAAc7X,KAAK,2BAA4B,IACzE0J,EAAO+J,eAENgH,EAAerL,EAAOsK,aAAgB3H,EAAgB,GACnD0I,EAAgBrL,EAAOkB,OAAOvS,OAASqR,EAAOsK,aAAiB3H,EAAgB,GAEnF3C,EAAOwK,UACPa,EAAe5K,EACZrT,SAAU,IAAOkN,EAAiB,WAAI,6BAAgCgN,EAAY,WAAehN,EAA0B,oBAAI,KAC/H1D,GAAG,GACHH,QAEHkC,GAAMI,SAAS,WACbiH,EAAO0J,QAAQ2B,MAGjBrL,EAAO0J,QAAQ2B,GAERA,EAAerL,EAAOkB,OAAOvS,OAASgU,GAC/C3C,EAAOwK,UACPa,EAAe5K,EACZrT,SAAU,IAAOkN,EAAiB,WAAI,6BAAgCgN,EAAY,WAAehN,EAA0B,oBAAI,KAC/H1D,GAAG,GACHH,QAEHkC,GAAMI,SAAS,WACbiH,EAAO0J,QAAQ2B,MAGjBrL,EAAO0J,QAAQ2B,QAGjBrL,EAAO0J,QAAQ2B,KA0GnB,IAAI7D,EAAO,CACT8D,WA7FF,WACE,IAAItL,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBmG,EAAaT,EAAOS,WAExBA,EAAWrT,SAAU,IAAOkN,EAAiB,WAAI,IAAOA,EAA0B,qBAAI/J,SAEtF,IAAI2Q,EAAST,EAAWrT,SAAU,IAAOkN,EAAiB,YAE1D,GAAIA,EAAOiR,uBAAwB,CACjC,IAAIC,EAAiBlR,EAAOiK,eAAkBrD,EAAOvS,OAAS2L,EAAOiK,eACrE,GAAIiH,IAAmBlR,EAAOiK,eAAgB,CAC5C,IAAK,IAAI7V,EAAI,EAAGA,EAAI8c,EAAgB9c,GAAK,EAAG,CAC1C,IAAI+c,EAAY7c,EAAEtC,EAAIa,cAAc,QAAQ6C,SAAWsK,EAAiB,WAAI,IAAOA,EAAsB,iBACzGmG,EAAW3J,OAAO2U,GAEpBvK,EAAST,EAAWrT,SAAU,IAAOkN,EAAiB,aAI7B,SAAzBA,EAAOqI,eAA6BrI,EAAOgQ,eAAgBhQ,EAAOgQ,aAAepJ,EAAOvS,QAE5FqR,EAAOsK,aAAehK,SAAShG,EAAOgQ,cAAgBhQ,EAAOqI,cAAe,IAC5E3C,EAAOsK,cAAgBhQ,EAAOoR,qBAC1B1L,EAAOsK,aAAepJ,EAAOvS,SAC/BqR,EAAOsK,aAAepJ,EAAOvS,QAG/B,IAAIgd,EAAgB,GAChBC,EAAe,GACnB1K,EAAOhL,KAAK,SAAUO,EAAOlF,GAC3B,IAAI0R,EAAQrU,EAAE2C,GACVkF,EAAQuJ,EAAOsK,cAAgBsB,EAAatc,KAAKiC,GACjDkF,EAAQyK,EAAOvS,QAAU8H,GAASyK,EAAOvS,OAASqR,EAAOsK,cAAgBqB,EAAcrc,KAAKiC,GAChG0R,EAAMrS,KAAK,0BAA2B6F,KAExC,IAAK,IAAIiO,EAAM,EAAGA,EAAMkH,EAAajd,OAAQ+V,GAAO,EAClDjE,EAAW3J,OAAOlI,EAAEgd,EAAalH,GAAKmH,WAAU,IAAO7b,SAASsK,EAAOmN,sBAEzE,IAAK,IAAI7C,EAAM+G,EAAchd,OAAS,EAAU,GAAPiW,EAAUA,GAAO,EACxDnE,EAAWtJ,QAAQvI,EAAE+c,EAAc/G,GAAKiH,WAAU,IAAO7b,SAASsK,EAAOmN,uBAsD3E+C,QAlDF,WACE,IASIH,EATArK,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBwL,EAAc9F,EAAO8F,YACrB5E,EAASlB,EAAOkB,OAChBoJ,EAAetK,EAAOsK,aACtBL,EAAiBjK,EAAOiK,eACxBD,EAAiBhK,EAAOgK,eACxB5I,EAAWpB,EAAOoB,SAClBT,EAAMX,EAAOY,aAEjBZ,EAAOiK,gBAAiB,EACxBjK,EAAOgK,gBAAiB,EAExB,IACI8B,GADiB1K,EAAS0E,GACH9F,EAAO9G,eAI9B4M,EAAcwE,GAChBD,EAAYnJ,EAAOvS,OAAyB,EAAf2b,EAAqBxE,EAClDuE,GAAYC,EACOtK,EAAO0J,QAAQW,EAAU,GAAG,GAAO,IACzB,IAATyB,GAClB9L,EAAO8I,cAAcnI,GAAOX,EAAOmG,UAAYnG,EAAOmG,WAAa2F,KAElC,SAAzBxR,EAAOqI,eAA0D,EAAf2H,GAAfxE,GAAqCA,GAAe5E,EAAOvS,OAAS2b,KAEjHD,GAAYnJ,EAAOvS,OAASmX,EAAcwE,EAC1CD,GAAYC,EACStK,EAAO0J,QAAQW,EAAU,GAAG,GAAO,IACzB,IAATyB,GACpB9L,EAAO8I,cAAcnI,GAAOX,EAAOmG,UAAYnG,EAAOmG,WAAa2F,IAGvE9L,EAAOiK,eAAiBA,EACxBjK,EAAOgK,eAAiBA,GAexB+B,YAZF,WACE,IACItL,EADSpU,KACWoU,WACpBnG,EAFSjO,KAEOiO,OAChB4G,EAHS7U,KAGO6U,OACpBT,EAAWrT,SAAU,IAAOkN,EAAiB,WAAI,IAAOA,EAA0B,oBAAI,KAAQA,EAAiB,WAAI,IAAOA,EAAsB,iBAAI/J,SACpJ2Q,EAAO/P,WAAW,6BAyBpB,IAAI6a,EAAa,CACfC,cAjBF,SAAwBC,GAEtB,KAAIxQ,GAAQC,QADCtP,KACgBiO,OAAO6R,eADvB9f,KACgDiO,OAAO8K,eADvD/Y,KAC+E+f,UAA5F,CACA,IAAI7a,EAFSlF,KAEGkF,GAChBA,EAAGjE,MAAM+e,OAAS,OAClB9a,EAAGjE,MAAM+e,OAASH,EAAS,mBAAqB,eAChD3a,EAAGjE,MAAM+e,OAASH,EAAS,eAAiB,YAC5C3a,EAAGjE,MAAM+e,OAASH,EAAS,WAAa,SAWxCI,gBARF,WAEM5Q,GAAQC,OADCtP,KACgBiO,OAAO8K,eADvB/Y,KAC+C+f,WAD/C/f,KAENkF,GAAGjE,MAAM+e,OAAS,MAqK3B,IAAIE,EAAe,CACjBC,YA9JF,SAAsBtL,GACpB,IAAIlB,EAAS3T,KACToU,EAAaT,EAAOS,WACpBnG,EAAS0F,EAAO1F,OAIpB,GAHIA,EAAOkN,MACTxH,EAAO+L,cAEa,iBAAX7K,GAAuB,WAAYA,EAC5C,IAAK,IAAIxS,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAClCwS,EAAOxS,IAAM+R,EAAW3J,OAAOoK,EAAOxS,SAG5C+R,EAAW3J,OAAOoK,GAEhB5G,EAAOkN,MACTxH,EAAOsL,aAEHhR,EAAOiC,UAAYb,GAAQa,UAC/ByD,EAAOJ,UA6IT6M,aAzIF,SAAuBvL,GACrB,IAAIlB,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBmG,EAAaT,EAAOS,WACpBqF,EAAc9F,EAAO8F,YAErBxL,EAAOkN,MACTxH,EAAO+L,cAET,IAAI7D,EAAiBpC,EAAc,EACnC,GAAsB,iBAAX5E,GAAuB,WAAYA,EAAQ,CACpD,IAAK,IAAIxS,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAClCwS,EAAOxS,IAAM+R,EAAWtJ,QAAQ+J,EAAOxS,IAE7CwZ,EAAiBpC,EAAc5E,EAAOvS,YAEtC8R,EAAWtJ,QAAQ+J,GAEjB5G,EAAOkN,MACTxH,EAAOsL,aAEHhR,EAAOiC,UAAYb,GAAQa,UAC/ByD,EAAOJ,SAETI,EAAO0J,QAAQxB,EAAgB,GAAG,IAkHlCwE,SA/GF,SAAmBjW,EAAOyK,GACxB,IAAIlB,EAAS3T,KACToU,EAAaT,EAAOS,WACpBnG,EAAS0F,EAAO1F,OAEhBqS,EADc3M,EAAO8F,YAErBxL,EAAOkN,OACTmF,GAAqB3M,EAAOsK,aAC5BtK,EAAO+L,cACP/L,EAAOkB,OAAST,EAAWrT,SAAU,IAAOkN,EAAiB,aAE/D,IAAIsS,EAAa5M,EAAOkB,OAAOvS,OAC/B,GAAI8H,GAAS,EACXuJ,EAAOyM,aAAavL,QAGtB,GAAa0L,GAATnW,EACFuJ,EAAOwM,YAAYtL,OADrB,CAOA,IAHA,IAAIgH,EAAqCzR,EAApBkW,EAA4BA,EAAoB,EAAIA,EAErEE,EAAe,GACVne,EAAIke,EAAa,EAAQnW,GAAL/H,EAAYA,GAAK,EAAG,CAC/C,IAAIoe,EAAe9M,EAAOkB,OAAOtK,GAAGlI,GACpCoe,EAAavc,SACbsc,EAAa/Z,QAAQga,GAGvB,GAAsB,iBAAX5L,GAAuB,WAAYA,EAAQ,CACpD,IAAK,IAAIwD,EAAM,EAAGA,EAAMxD,EAAOvS,OAAQ+V,GAAO,EACxCxD,EAAOwD,IAAQjE,EAAW3J,OAAOoK,EAAOwD,IAE9CwD,EAAqCzR,EAApBkW,EAA4BA,EAAoBzL,EAAOvS,OAASge,OAEjFlM,EAAW3J,OAAOoK,GAGpB,IAAK,IAAI0D,EAAM,EAAGA,EAAMiI,EAAale,OAAQiW,GAAO,EAClDnE,EAAW3J,OAAO+V,EAAajI,IAG7BtK,EAAOkN,MACTxH,EAAOsL,aAEHhR,EAAOiC,UAAYb,GAAQa,UAC/ByD,EAAOJ,SAELtF,EAAOkN,KACTxH,EAAO0J,QAAQxB,EAAiBlI,EAAOsK,aAAc,GAAG,GAExDtK,EAAO0J,QAAQxB,EAAgB,GAAG,KA6DpC6E,YAzDF,SAAsBC,GACpB,IAAIhN,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBmG,EAAaT,EAAOS,WAGpBkM,EAFc3M,EAAO8F,YAGrBxL,EAAOkN,OACTmF,GAAqB3M,EAAOsK,aAC5BtK,EAAO+L,cACP/L,EAAOkB,OAAST,EAAWrT,SAAU,IAAOkN,EAAiB,aAE/D,IACI2S,EADA/E,EAAiByE,EAGrB,GAA6B,iBAAlBK,GAA8B,WAAYA,EAAe,CAClE,IAAK,IAAIte,EAAI,EAAGA,EAAIse,EAAcre,OAAQD,GAAK,EAC7Cue,EAAgBD,EAActe,GAC1BsR,EAAOkB,OAAO+L,IAAkBjN,EAAOkB,OAAOtK,GAAGqW,GAAe1c,SAChE0c,EAAgB/E,IAAkBA,GAAkB,GAE1DA,EAAiB1F,KAAKK,IAAIqF,EAAgB,QAE1C+E,EAAgBD,EACZhN,EAAOkB,OAAO+L,IAAkBjN,EAAOkB,OAAOtK,GAAGqW,GAAe1c,SAChE0c,EAAgB/E,IAAkBA,GAAkB,GACxDA,EAAiB1F,KAAKK,IAAIqF,EAAgB,GAGxC5N,EAAOkN,MACTxH,EAAOsL,aAGHhR,EAAOiC,UAAYb,GAAQa,UAC/ByD,EAAOJ,SAELtF,EAAOkN,KACTxH,EAAO0J,QAAQxB,EAAiBlI,EAAOsK,aAAc,GAAG,GAExDtK,EAAO0J,QAAQxB,EAAgB,GAAG,IAmBpCgF,gBAfF,WAIE,IAHA,IAEIF,EAAgB,GACXte,EAAI,EAAGA,EAHHrC,KAGc6U,OAAOvS,OAAQD,GAAK,EAC7Cse,EAAc1d,KAAKZ,GAJRrC,KAMN0gB,YAAYC,KAWjBG,EAAU,WACZ,IAAIzU,EAAK/K,EAAIE,UAAUC,UAEnBsf,EAAS,CACXC,KAAK,EACLC,SAAS,EACTC,eAAe,EACfC,SAAS,EACTC,SAAS,EACTC,QAAQ,EACRC,MAAM,EACNC,MAAM,EACNC,QAASlgB,EAAIkgB,SAAWlgB,EAAImgB,SAC5BA,SAAUngB,EAAIkgB,SAAWlgB,EAAImgB,UAG3BL,EAAU/U,EAAGnJ,MAAM,qCACnB+d,EAAU5U,EAAGnJ,MAAM,+BACnBqe,EAAOlV,EAAGnJ,MAAM,wBAChBoe,EAAOjV,EAAGnJ,MAAM,2BAChBme,GAAUE,GAAQlV,EAAGnJ,MAAM,8BA+C/B,GA3CIke,IACFL,EAAOW,GAAK,UACZX,EAAOY,UAAYP,EAAQ,GAC3BL,EAAOK,SAAU,GAGfH,IAAYG,IACdL,EAAOW,GAAK,UACZX,EAAOY,UAAYV,EAAQ,GAC3BF,EAAOE,SAAU,EACjBF,EAAOG,cAAsD,GAAtC7U,EAAGwE,cAAc/N,QAAQ,YAE9Cye,GAAQF,GAAUC,KACpBP,EAAOW,GAAK,MACZX,EAAOC,KAAM,GAGXK,IAAWC,IACbP,EAAOY,UAAYN,EAAO,GAAG/T,QAAQ,KAAM,KAC3CyT,EAAOM,QAAS,GAEdE,IACFR,EAAOY,UAAYJ,EAAK,GAAGjU,QAAQ,KAAM,KACzCyT,EAAOQ,MAAO,GAEZD,IACFP,EAAOY,UAAYL,EAAK,GAAKA,EAAK,GAAGhU,QAAQ,KAAM,KAAO,KAC1DyT,EAAOM,QAAS,GAGdN,EAAOC,KAAOD,EAAOY,WAAuC,GAA1BtV,EAAGvJ,QAAQ,aACR,OAAnCie,EAAOY,UAAUxe,MAAM,KAAK,KAC9B4d,EAAOY,UAAYtV,EAAGwE,cAAc1N,MAAM,YAAY,GAAGA,MAAM,KAAK,IAKxE4d,EAAOI,UAAYJ,EAAOW,IAAMX,EAAOE,SAAWF,EAAOa,SAGzDb,EAAOa,SAAWP,GAAUE,GAAQD,IAASjV,EAAGnJ,MAAM,8BAGlD6d,EAAOW,IAAoB,QAAdX,EAAOW,GAAc,CACpC,IAAIG,EAAed,EAAOY,UAAUxe,MAAM,KACtC2e,EAAe7hB,EAAIQ,cAAc,yBACrCsgB,EAAOgB,WAAahB,EAAOa,UACrBN,GAAQD,KACU,EAAlBQ,EAAa,IAAW,EAA2B,GAAL,EAAlBA,EAAa,GAAoC,EAAJ,EAAlBA,EAAa,KACrEC,GAA8E,GAA9DA,EAAald,aAAa,WAAW9B,QAAQ,cAOpE,OAHAie,EAAOiB,WAAa1gB,EAAI2gB,kBAAoB,EAGrClB,EAhFI,GAsnBb,SAASmB,IACP,IAAIvO,EAAS3T,KAETiO,EAAS0F,EAAO1F,OAChB/I,EAAKyO,EAAOzO,GAEhB,IAAIA,GAAyB,IAAnBA,EAAGyD,YAAb,CAGIsF,EAAOkU,aACTxO,EAAOyO,gBAIT,IAAIzE,EAAiBhK,EAAOgK,eACxBC,EAAiBjK,EAAOiK,eACxB7I,EAAWpB,EAAOoB,SAStB,GANApB,EAAOgK,gBAAiB,EACxBhK,EAAOiK,gBAAiB,EAExBjK,EAAOH,aACPG,EAAOQ,eAEHlG,EAAOoU,SAAU,CACnB,IAAIC,EAAenM,KAAKoM,IAAIpM,KAAKK,IAAI7C,EAAOmG,UAAWnG,EAAO+G,gBAAiB/G,EAAOyG,gBACtFzG,EAAO8I,aAAa6F,GACpB3O,EAAOiI,oBACPjI,EAAOoH,sBAEH9M,EAAOiP,YACTvJ,EAAOyF,wBAGTzF,EAAOoH,uBACuB,SAAzB9M,EAAOqI,eAAmD,EAAvBrI,EAAOqI,gBAAsB3C,EAAOiH,QAAUjH,EAAO1F,OAAO+J,eAClGrE,EAAO0J,QAAQ1J,EAAOkB,OAAOvS,OAAS,EAAG,GAAG,GAAO,GAEnDqR,EAAO0J,QAAQ1J,EAAO8F,YAAa,GAAG,GAAO,GAIjD9F,EAAOiK,eAAiBA,EACxBjK,EAAOgK,eAAiBA,EAEpBhK,EAAO1F,OAAO8K,eAAiBhE,IAAapB,EAAOoB,UACrDpB,EAAOqF,iBA6TX,IAEIwJ,EAAW,CACbC,MAAM,EACNxF,UAAW,aACXyF,kBAAmB,YACnBjF,aAAc,EACdpE,MAAO,IAEPmE,gCAAgC,EAGhCmF,oBAAoB,EACpBC,mBAAoB,GAGpBP,UAAU,EACVQ,kBAAkB,EAClBC,sBAAuB,EACvBC,wBAAwB,EACxBC,4BAA6B,EAC7BC,8BAA+B,EAC/BC,gBAAgB,EAChBC,wBAAyB,IAGzBjG,YAAY,EAGZ9E,gBAAgB,EAGhBmE,kBAAkB,EAGlBpE,OAAQ,QAGRgK,iBAAapb,EACbqc,oBAAoB,EAGpB5N,aAAc,EACdc,cAAe,EACfJ,gBAAiB,EACjBK,oBAAqB,SACrB2B,eAAgB,EAChBF,gBAAgB,EAChB7C,mBAAoB,EACpBE,kBAAmB,EACnB4G,qBAAqB,EACrBxD,0BAA0B,EAG1BM,eAAe,EAGfvB,cAAc,EAGd6L,WAAY,EACZC,WAAY,GACZxD,eAAe,EACfyD,aAAa,EACbC,YAAY,EACZC,gBAAiB,GACjBC,aAAc,IACdC,cAAc,EACdC,gBAAgB,EAChBC,UAAW,EACXC,0BAA0B,EAC1BC,0BAA0B,EAC1BC,+BAA+B,EAC/BC,qBAAqB,EAGrBC,mBAAmB,EAGnBC,YAAY,EACZC,gBAAiB,IAGjBnL,qBAAqB,EACrBC,uBAAuB,EAGvByG,YAAY,EAGZ0E,eAAe,EACfC,0BAA0B,EAC1BhI,qBAAqB,EAGrBiI,eAAe,EACfC,qBAAqB,EAGrBrJ,MAAM,EACNkE,qBAAsB,EACtBpB,aAAc,KACdiB,wBAAwB,EAGxBtB,gBAAgB,EAChBD,gBAAgB,EAChB8G,aAAc,KACdC,WAAW,EACXC,eAAgB,oBAChBC,kBAAmB,KAGnBC,kBAAkB,EAGlBC,uBAAwB,oBACxBC,WAAY,eACZC,gBAAiB,+BACjB9J,iBAAkB,sBAClBG,0BAA2B,gCAC3BrB,kBAAmB,uBACnBoB,oBAAqB,yBACrBG,eAAgB,oBAChBG,wBAAyB,8BACzBD,eAAgB,oBAChBE,wBAAyB,8BACzBsJ,aAAc,iBAGdC,oBAAoB,GAKlBC,EAAa,CACf5R,OAAQA,EACRuG,UAAWA,EACXtU,WAAYsX,EACZlG,MAAOA,EACPuE,KAAMA,EACNwE,WAAYA,EACZO,aAAcA,EACdlZ,OAtWW,CACXoe,aAxFF,WACE,IAAIzR,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChBoX,EAAc1R,EAAO0R,YACrBngB,EAAKyO,EAAOzO,GACZogB,EAAY3R,EAAO2R,UAGrB3R,EAAO4R,aAzmBX,SAAuBne,GACrB,IAAIuM,EAAS3T,KACTgF,EAAO2O,EAAO6R,gBACdvX,EAAS0F,EAAO1F,OAChBwX,EAAU9R,EAAO8R,QACrB,IAAI9R,EAAOyJ,YAAanP,EAAOuP,+BAA/B,CAGA,IAAInX,EAAIe,EAGR,GAFIf,EAAEqf,gBAAiBrf,EAAIA,EAAEqf,eAC7B1gB,EAAK2gB,aAA0B,eAAXtf,EAAEuf,MACjB5gB,EAAK2gB,gBAAgB,UAAWtf,IAAiB,IAAZA,EAAEwf,WACvC7gB,EAAK2gB,cAAgB,WAAYtf,GAAgB,EAAXA,EAAEyf,QACzC9gB,EAAK+gB,WAAa/gB,EAAKghB,SAC3B,GAAI/X,EAAOyW,WAAaniB,EAAE8D,EAAEC,QAAQoF,QAAQuC,EAAO2W,kBAAoB3W,EAAO2W,kBAAqB,IAAO3W,EAAqB,gBAAI,GACjI0F,EAAOsS,YAAa,OAGtB,IAAIhY,EAAOwW,cACJliB,EAAE8D,GAAGqF,QAAQuC,EAAOwW,cAAc,GADzC,CAIAgB,EAAQS,SAAsB,eAAX7f,EAAEuf,KAAwBvf,EAAE8f,cAAc,GAAGC,MAAQ/f,EAAE+f,MAC1EX,EAAQY,SAAsB,eAAXhgB,EAAEuf,KAAwBvf,EAAE8f,cAAc,GAAGG,MAAQjgB,EAAEigB,MAC1E,IAAIC,EAASd,EAAQS,SACjBM,EAASf,EAAQY,SAIjB1D,EAAqB1U,EAAO0U,oBAAsB1U,EAAOwY,sBACzD7D,EAAqB3U,EAAO2U,oBAAsB3U,EAAOyY,sBAC7D,IACE/D,KACK4D,GAAU3D,GACX2D,GAAUjlB,EAAIU,OAAOyR,MAAQmP,GAHnC,CAuBA,GAfAtW,GAAMqC,OAAO3J,EAAM,CACjB+gB,WAAW,EACXC,SAAS,EACTW,qBAAqB,EACrBC,iBAAa7f,EACb8f,iBAAa9f,IAGf0e,EAAQc,OAASA,EACjBd,EAAQe,OAASA,EACjBxhB,EAAK8hB,eAAiBxa,GAAMM,MAC5B+G,EAAOsS,YAAa,EACpBtS,EAAOH,aACPG,EAAOoT,oBAAiBhgB,EACD,EAAnBkH,EAAO4V,YAAiB7e,EAAKgiB,oBAAqB,GACvC,eAAX3gB,EAAEuf,KAAuB,CAC3B,IAAIqB,GAAiB,EACjB1kB,EAAE8D,EAAEC,QAAQI,GAAG1B,EAAKkiB,gBAAiBD,GAAiB,GAExDhnB,EAAIK,eACDiC,EAAEtC,EAAIK,eAAeoG,GAAG1B,EAAKkiB,eAC7BjnB,EAAIK,gBAAkB+F,EAAEC,QAE3BrG,EAAIK,cAAcC,OAGpB,IAAI4mB,EAAuBF,GAAkBtT,EAAOiQ,gBAAkB3V,EAAO8V,0BACzE9V,EAAO+V,+BAAiCmD,IAC1C9gB,EAAE4gB,iBAGNtT,EAAO/B,KAAK,aAAcvL,OAmiBWqM,KAAKiB,GACxCA,EAAOyT,YAjiBX,SAAsBhgB,GACpB,IAAIuM,EAAS3T,KACTgF,EAAO2O,EAAO6R,gBACdvX,EAAS0F,EAAO1F,OAChBwX,EAAU9R,EAAO8R,QACjBnR,EAAMX,EAAOY,aACblO,EAAIe,EAER,GADIf,EAAEqf,gBAAiBrf,EAAIA,EAAEqf,eACxB1gB,EAAK+gB,WAMV,IAAI/gB,EAAK2gB,cAA2B,cAAXtf,EAAEuf,KAA3B,CACA,IAAIQ,EAAmB,cAAX/f,EAAEuf,KAAuBvf,EAAE8f,cAAc,GAAGC,MAAQ/f,EAAE+f,MAC9DE,EAAmB,cAAXjgB,EAAEuf,KAAuBvf,EAAE8f,cAAc,GAAGG,MAAQjgB,EAAEigB,MAClE,GAAIjgB,EAAEghB,wBAGJ,OAFA5B,EAAQc,OAASH,OACjBX,EAAQe,OAASF,GAGnB,IAAK3S,EAAOiQ,eAYV,OAVAjQ,EAAOsS,YAAa,OAChBjhB,EAAK+gB,YACPzZ,GAAMqC,OAAO8W,EAAS,CACpBc,OAAQH,EACRI,OAAQF,EACRJ,SAAUE,EACVC,SAAUC,IAEZthB,EAAK8hB,eAAiBxa,GAAMM,QAIhC,GAAI5H,EAAK2gB,cAAgB1X,EAAOgW,sBAAwBhW,EAAOkN,KAC7D,GAAIxH,EAAOK,cAET,GACGsS,EAAQb,EAAQe,QAAU7S,EAAOmG,WAAanG,EAAO+G,gBAClD4L,EAAQb,EAAQe,QAAU7S,EAAOmG,WAAanG,EAAOyG,eAIzD,OAFApV,EAAK+gB,WAAY,OACjB/gB,EAAKghB,SAAU,QAGZ,GACJI,EAAQX,EAAQc,QAAU5S,EAAOmG,WAAanG,EAAO+G,gBAClD0L,EAAQX,EAAQc,QAAU5S,EAAOmG,WAAanG,EAAOyG,eAEzD,OAGJ,GAAIpV,EAAK2gB,cAAgB1lB,EAAIK,eACvB+F,EAAEC,SAAWrG,EAAIK,eAAiBiC,EAAE8D,EAAEC,QAAQI,GAAG1B,EAAKkiB,cAGxD,OAFAliB,EAAKghB,SAAU,OACfrS,EAAOsS,YAAa,GAOxB,GAHIjhB,EAAK2hB,qBACPhT,EAAO/B,KAAK,YAAavL,KAEvBA,EAAE8f,eAA0C,EAAzB9f,EAAE8f,cAAc7jB,QAAvC,CAEAmjB,EAAQS,SAAWE,EACnBX,EAAQY,SAAWC,EAEnB,IAKMhD,EALFgE,EAAQ7B,EAAQS,SAAWT,EAAQc,OACnCgB,EAAQ9B,EAAQY,SAAWZ,EAAQe,OACvC,KAAI7S,EAAO1F,OAAO4V,WAAa1N,KAAKqR,KAAMrR,KAAKsR,IAAKH,EAAO,GAAQnR,KAAKsR,IAAKF,EAAO,IAAQ5T,EAAO1F,OAAO4V,WAsB1G,QApBgC,IAArB7e,EAAK4hB,cAETjT,EAAOI,gBAAkB0R,EAAQY,WAAaZ,EAAQe,QAAY7S,EAAOK,cAAgByR,EAAQS,WAAaT,EAAQc,OACzHvhB,EAAK4hB,aAAc,EAGsB,IAApCU,EAAQA,EAAUC,EAAQA,IAC7BjE,EAA6D,IAA/CnN,KAAKuR,MAAMvR,KAAK8B,IAAIsP,GAAQpR,KAAK8B,IAAIqP,IAAiBnR,KAAKwR,GACzE3iB,EAAK4hB,YAAcjT,EAAOI,eAAiBuP,EAAarV,EAAOqV,WAAc,GAAKA,EAAarV,EAAOqV,aAIxGte,EAAK4hB,aACPjT,EAAO/B,KAAK,oBAAqBvL,QAEH,IAArBrB,EAAK6hB,cACVpB,EAAQS,WAAaT,EAAQc,QAAUd,EAAQY,WAAaZ,EAAQe,SACtExhB,EAAK6hB,aAAc,IAGnB7hB,EAAK4hB,YACP5hB,EAAK+gB,WAAY,OAGnB,GAAK/gB,EAAK6hB,YAAV,CAGAlT,EAAOsS,YAAa,EACpB5f,EAAE4gB,iBACEhZ,EAAO6V,2BAA6B7V,EAAO2Z,QAC7CvhB,EAAEwhB,kBAGC7iB,EAAKghB,UACJ/X,EAAOkN,MACTxH,EAAOwK,UAETnZ,EAAK8iB,eAAiBnU,EAAO9G,eAC7B8G,EAAO6F,cAAc,GACjB7F,EAAOyJ,WACTzJ,EAAOS,WAAWzM,QAAQ,qCAE5B3C,EAAK+iB,qBAAsB,GAEvB9Z,EAAO0R,aAAyC,IAA1BhM,EAAOgK,iBAAqD,IAA1BhK,EAAOiK,gBACjEjK,EAAOiM,eAAc,GAEvBjM,EAAO/B,KAAK,kBAAmBvL,IAEjCsN,EAAO/B,KAAK,aAAcvL,GAC1BrB,EAAKghB,SAAU,EAEf,IAAIvG,EAAO9L,EAAOI,eAAiBuT,EAAQC,EAC3C9B,EAAQhG,KAAOA,EAEfA,GAAQxR,EAAOoV,WACX/O,IAAOmL,GAAQA,GAEnB9L,EAAOoT,eAAwB,EAAPtH,EAAW,OAAS,OAC5Cza,EAAKwX,iBAAmBiD,EAAOza,EAAK8iB,eAEpC,IAAIE,GAAsB,EACtB5D,EAAkBnW,EAAOmW,gBA0B7B,GAzBInW,EAAOgW,sBACTG,EAAkB,GAER,EAAP3E,GAAYza,EAAKwX,iBAAmB7I,EAAOyG,gBAC9C4N,GAAsB,EAClB/Z,EAAOkW,aAAcnf,EAAKwX,iBAAoB7I,EAAOyG,eAAiB,EAAMjE,KAAKsR,KAAO9T,EAAOyG,eAAiBpV,EAAK8iB,eAAiBrI,EAAO2E,KACxI3E,EAAO,GAAKza,EAAKwX,iBAAmB7I,EAAO+G,iBACpDsN,GAAsB,EAClB/Z,EAAOkW,aAAcnf,EAAKwX,iBAAoB7I,EAAO+G,eAAiB,EAAMvE,KAAKsR,IAAM9T,EAAO+G,eAAiB1V,EAAK8iB,eAAiBrI,EAAO2E,KAG9I4D,IACF3hB,EAAEghB,yBAA0B,IAIzB1T,EAAOgK,gBAA4C,SAA1BhK,EAAOoT,gBAA6B/hB,EAAKwX,iBAAmBxX,EAAK8iB,iBAC7F9iB,EAAKwX,iBAAmBxX,EAAK8iB,iBAE1BnU,EAAOiK,gBAA4C,SAA1BjK,EAAOoT,gBAA6B/hB,EAAKwX,iBAAmBxX,EAAK8iB,iBAC7F9iB,EAAKwX,iBAAmBxX,EAAK8iB,gBAKR,EAAnB7Z,EAAO4V,UAAe,CACxB,KAAI1N,KAAK8B,IAAIwH,GAAQxR,EAAO4V,WAAa7e,EAAKgiB,oBAW5C,YADAhiB,EAAKwX,iBAAmBxX,EAAK8iB,gBAT7B,IAAK9iB,EAAKgiB,mBAMR,OALAhiB,EAAKgiB,oBAAqB,EAC1BvB,EAAQc,OAASd,EAAQS,SACzBT,EAAQe,OAASf,EAAQY,SACzBrhB,EAAKwX,iBAAmBxX,EAAK8iB,oBAC7BrC,EAAQhG,KAAO9L,EAAOI,eAAiB0R,EAAQS,SAAWT,EAAQc,OAASd,EAAQY,SAAWZ,EAAQe,QASvGvY,EAAO0V,gBAGR1V,EAAOoU,UAAYpU,EAAOgL,qBAAuBhL,EAAOiL,yBAC1DvF,EAAOiI,oBACPjI,EAAOoH,uBAEL9M,EAAOoU,WAEsB,IAA3Brd,EAAKijB,WAAW3lB,QAClB0C,EAAKijB,WAAWhlB,KAAK,CACnBilB,SAAUzC,EAAQ9R,EAAOI,eAAiB,SAAW,UACrDoU,KAAMnjB,EAAK8hB,iBAGf9hB,EAAKijB,WAAWhlB,KAAK,CACnBilB,SAAUzC,EAAQ9R,EAAOI,eAAiB,WAAa,YACvDoU,KAAM7b,GAAMM,SAIhB+G,EAAO6G,eAAexV,EAAKwX,kBAE3B7I,EAAO8I,aAAazX,EAAKwX,2BA/LnBxX,EAAK6hB,aAAe7hB,EAAK4hB,aAC3BjT,EAAO/B,KAAK,oBAAqBvL,IAuhBFqM,KAAKiB,GACtCA,EAAOyU,WAvVX,SAAqBhhB,GACnB,IAAIuM,EAAS3T,KACTgF,EAAO2O,EAAO6R,gBAEdvX,EAAS0F,EAAO1F,OAChBwX,EAAU9R,EAAO8R,QACjBnR,EAAMX,EAAOY,aACbH,EAAaT,EAAOS,WACpBY,EAAarB,EAAOqB,WACpBD,EAAWpB,EAAOoB,SAClB1O,EAAIe,EAMR,GALIf,EAAEqf,gBAAiBrf,EAAIA,EAAEqf,eACzB1gB,EAAK2hB,qBACPhT,EAAO/B,KAAK,WAAYvL,GAE1BrB,EAAK2hB,qBAAsB,GACtB3hB,EAAK+gB,UAMR,OALI/gB,EAAKghB,SAAW/X,EAAO0R,YACzBhM,EAAOiM,eAAc,GAEvB5a,EAAKghB,SAAU,OACfhhB,EAAK6hB,aAAc,GAIjB5Y,EAAO0R,YAAc3a,EAAKghB,SAAWhhB,EAAK+gB,aAAwC,IAA1BpS,EAAOgK,iBAAqD,IAA1BhK,EAAOiK,iBACnGjK,EAAOiM,eAAc,GAIvB,IAmCIyI,EAnCAC,EAAehc,GAAMM,MACrB2b,EAAWD,EAAetjB,EAAK8hB,eAwBnC,GArBInT,EAAOsS,aACTtS,EAAOuI,mBAAmB7V,GAC1BsN,EAAO/B,KAAK,MAAOvL,GACfkiB,EAAW,KAA6C,IAArCD,EAAetjB,EAAKwjB,gBACrCxjB,EAAKyjB,cAAgBvmB,aAAa8C,EAAKyjB,cAC3CzjB,EAAKyjB,aAAenc,GAAMI,SAAS,WAC5BiH,IAAUA,EAAOmK,WACtBnK,EAAO/B,KAAK,QAASvL,IACpB,MAEDkiB,EAAW,KAAQD,EAAetjB,EAAKwjB,cAAiB,MACtDxjB,EAAKyjB,cAAgBvmB,aAAa8C,EAAKyjB,cAC3C9U,EAAO/B,KAAK,YAAavL,KAI7BrB,EAAKwjB,cAAgBlc,GAAMM,MAC3BN,GAAMI,SAAS,WACRiH,EAAOmK,YAAanK,EAAOsS,YAAa,MAG1CjhB,EAAK+gB,YAAc/gB,EAAKghB,UAAYrS,EAAOoT,gBAAmC,IAAjBtB,EAAQhG,MAAcza,EAAKwX,mBAAqBxX,EAAK8iB,eAIrH,OAHA9iB,EAAK+gB,WAAY,EACjB/gB,EAAKghB,SAAU,OACfhhB,EAAK6hB,aAAc,GAcrB,GAXA7hB,EAAK+gB,WAAY,EACjB/gB,EAAKghB,SAAU,EACfhhB,EAAK6hB,aAAc,EAIjBwB,EADEpa,EAAO0V,aACIrP,EAAMX,EAAOmG,WAAanG,EAAOmG,WAEhC9U,EAAKwX,iBAGjBvO,EAAOoU,SAAX,CACE,GAAIgG,GAAc1U,EAAOyG,eAEvB,YADAzG,EAAO0J,QAAQ1J,EAAO8F,aAGxB,GAAI4O,GAAc1U,EAAO+G,eAMvB,YALI/G,EAAOkB,OAAOvS,OAASyS,EAASzS,OAClCqR,EAAO0J,QAAQtI,EAASzS,OAAS,GAEjCqR,EAAO0J,QAAQ1J,EAAOkB,OAAOvS,OAAS,IAK1C,GAAI2L,EAAO4U,iBAAkB,CAC3B,GAA6B,EAAzB7d,EAAKijB,WAAW3lB,OAAY,CAC9B,IAAIomB,EAAgB1jB,EAAKijB,WAAWU,MAChCC,EAAgB5jB,EAAKijB,WAAWU,MAEhCE,EAAWH,EAAcR,SAAWU,EAAcV,SAClDC,EAAOO,EAAcP,KAAOS,EAAcT,KAC9CxU,EAAOmV,SAAWD,EAAWV,EAC7BxU,EAAOmV,UAAY,EACf3S,KAAK8B,IAAItE,EAAOmV,UAAY7a,EAAOkV,0BACrCxP,EAAOmV,SAAW,IAIT,IAAPX,GAAmD,IAApC7b,GAAMM,MAAQ8b,EAAcP,QAC7CxU,EAAOmV,SAAW,QAGpBnV,EAAOmV,SAAW,EAEpBnV,EAAOmV,UAAY7a,EAAOgV,8BAE1Bje,EAAKijB,WAAW3lB,OAAS,EACzB,IAAIymB,EAAmB,IAAO9a,EAAO6U,sBACjCkG,EAAmBrV,EAAOmV,SAAWC,EAErCE,EAActV,EAAOmG,UAAYkP,EACjC1U,IAAO2U,GAAeA,GAE1B,IACIC,EAEAC,EAHAC,GAAW,EAEXC,EAA2C,GAA5BlT,KAAK8B,IAAItE,EAAOmV,UAAiB7a,EAAO+U,4BAE3D,GAAIiG,EAActV,EAAO+G,eACnBzM,EAAO8U,wBACLkG,EAActV,EAAO+G,gBAAkB2O,IACzCJ,EAActV,EAAO+G,eAAiB2O,GAExCH,EAAsBvV,EAAO+G,eAC7B0O,GAAW,EACXpkB,EAAK+iB,qBAAsB,GAE3BkB,EAActV,EAAO+G,eAEnBzM,EAAOkN,MAAQlN,EAAO+J,iBAAkBmR,GAAe,QACtD,GAAIF,EAActV,EAAOyG,eAC1BnM,EAAO8U,wBACLkG,EAActV,EAAOyG,eAAiBiP,IACxCJ,EAActV,EAAOyG,eAAiBiP,GAExCH,EAAsBvV,EAAOyG,eAC7BgP,GAAW,EACXpkB,EAAK+iB,qBAAsB,GAE3BkB,EAActV,EAAOyG,eAEnBnM,EAAOkN,MAAQlN,EAAO+J,iBAAkBmR,GAAe,QACtD,GAAIlb,EAAOiV,eAAgB,CAEhC,IADA,IAAI5H,EACKxX,EAAI,EAAGA,EAAIiR,EAASzS,OAAQwB,GAAK,EACxC,GAAIiR,EAASjR,IAAMmlB,EAAa,CAC9B3N,EAAYxX,EACZ,MASJmlB,IAJEA,EADE9S,KAAK8B,IAAIlD,EAASuG,GAAa2N,GAAe9S,KAAK8B,IAAIlD,EAASuG,EAAY,GAAK2N,IAA0C,SAA1BtV,EAAOoT,eAC5FhS,EAASuG,GAETvG,EAASuG,EAAY,IAUvC,GANI6N,GACFxV,EAAOnC,KAAK,gBAAiB,WAC3BmC,EAAOwK,YAIa,IAApBxK,EAAOmV,SAEPC,EADEzU,EACiB6B,KAAK8B,MAAMgR,EAActV,EAAOmG,WAAanG,EAAOmV,UAEpD3S,KAAK8B,KAAKgR,EAActV,EAAOmG,WAAanG,EAAOmV,eAEnE,GAAI7a,EAAOiV,eAEhB,YADAvP,EAAOkL,iBAIL5Q,EAAO8U,wBAA0BqG,GACnCzV,EAAO6G,eAAe0O,GACtBvV,EAAO6F,cAAcuP,GACrBpV,EAAO8I,aAAawM,GACpBtV,EAAOoJ,iBAAgB,EAAMpJ,EAAOoT,gBACpCpT,EAAOyJ,WAAY,EACnBhJ,EAAWjM,cAAc,WAClBwL,IAAUA,EAAOmK,WAAc9Y,EAAK+iB,sBACzCpU,EAAO/B,KAAK,kBAEZ+B,EAAO6F,cAAcvL,EAAOoL,OAC5B1F,EAAO8I,aAAayM,GACpB9U,EAAWjM,cAAc,WAClBwL,IAAUA,EAAOmK,WACtBnK,EAAOxL,sBAGFwL,EAAOmV,UAChBnV,EAAO6G,eAAeyO,GACtBtV,EAAO6F,cAAcuP,GACrBpV,EAAO8I,aAAawM,GACpBtV,EAAOoJ,iBAAgB,EAAMpJ,EAAOoT,gBAC/BpT,EAAOyJ,YACVzJ,EAAOyJ,WAAY,EACnBhJ,EAAWjM,cAAc,WAClBwL,IAAUA,EAAOmK,WACtBnK,EAAOxL,oBAIXwL,EAAO6G,eAAeyO,GAGxBtV,EAAOiI,oBACPjI,EAAOoH,2BACF,GAAI9M,EAAOiV,eAEhB,YADAvP,EAAOkL,mBAIJ5Q,EAAO4U,kBAAoB0F,GAAYta,EAAOyV,gBACjD/P,EAAO6G,iBACP7G,EAAOiI,oBACPjI,EAAOoH,2BAnJX,CA2JA,IAFA,IAAIuO,EAAY,EACZC,EAAY5V,EAAOsB,gBAAgB,GAC9B5S,EAAI,EAAGA,EAAI2S,EAAW1S,OAAQD,GAAK4L,EAAOiK,oBACI,IAA1ClD,EAAW3S,EAAI4L,EAAOiK,gBAC3BmQ,GAAcrT,EAAW3S,IAAMgmB,EAAarT,EAAW3S,EAAI4L,EAAOiK,kBAEpEqR,EAAYvU,GADZsU,EAAYjnB,GACe4L,EAAOiK,gBAAkBlD,EAAW3S,IAExDgmB,GAAcrT,EAAW3S,KAClCinB,EAAYjnB,EACZknB,EAAYvU,EAAWA,EAAW1S,OAAS,GAAK0S,EAAWA,EAAW1S,OAAS,IAKnF,IAAIknB,GAASnB,EAAarT,EAAWsU,IAAcC,EAEnD,GAAIhB,EAAWta,EAAOyV,aAAc,CAElC,IAAKzV,EAAOuV,WAEV,YADA7P,EAAO0J,QAAQ1J,EAAO8F,aAGM,SAA1B9F,EAAOoT,iBACLyC,GAASvb,EAAOwV,gBAAmB9P,EAAO0J,QAAQiM,EAAYrb,EAAOiK,gBAClEvE,EAAO0J,QAAQiM,IAEM,SAA1B3V,EAAOoT,iBACLyC,EAAS,EAAIvb,EAAOwV,gBAAoB9P,EAAO0J,QAAQiM,EAAYrb,EAAOiK,gBACvEvE,EAAO0J,QAAQiM,QAEnB,CAEL,IAAKrb,EAAOsV,YAEV,YADA5P,EAAO0J,QAAQ1J,EAAO8F,aAGM,SAA1B9F,EAAOoT,gBACTpT,EAAO0J,QAAQiM,EAAYrb,EAAOiK,gBAEN,SAA1BvE,EAAOoT,gBACTpT,EAAO0J,QAAQiM,MA6Ec5W,KAAKiB,GAGtCA,EAAO8V,QAxBT,SAAkBpjB,GACHrG,KACDimB,aADCjmB,KAEAiO,OAAOoW,eAAiBhe,EAAE4gB,iBAF1BjnB,KAGAiO,OAAOqW,0BAHPtkB,KAG0Cod,YACnD/W,EAAEwhB,kBACFxhB,EAAEqjB,8BAkBmBhX,KAAKiB,GAE9B,IAAIrN,EAAsC,cAA7B2H,EAAOyU,kBAAoCxd,EAAKogB,EACzDnf,IAAY8H,EAAO2Z,OAIrB,GAAKvY,GAAQC,QAAUD,GAAQK,gBAAiBL,GAAQQ,sBAIjD,CACL,GAAIR,GAAQC,MAAO,CACjB,IAAIa,IAAwC,eAAtBkV,EAAYsE,QAA0Bta,GAAQc,kBAAmBlC,EAAO4W,mBAAmB,CAAE+E,SAAS,EAAMzjB,SAAS,GAC3IG,EAAOlG,iBAAiBilB,EAAYsE,MAAOhW,EAAO4R,aAAcpV,GAChE7J,EAAOlG,iBAAiBilB,EAAYwE,KAAMlW,EAAOyT,YAAa/X,GAAQc,gBAAkB,CAAEyZ,SAAS,EAAOzjB,QAASA,GAAYA,GAC/HG,EAAOlG,iBAAiBilB,EAAYyE,IAAKnW,EAAOyU,WAAYjY,IAEzDlC,EAAO6R,gBAAkBgB,EAAOE,MAAQF,EAAOG,SAAahT,EAAO6R,gBAAkBzQ,GAAQC,OAASwR,EAAOE,OAChH1a,EAAOlG,iBAAiB,YAAauT,EAAO4R,cAAc,GAC1DtlB,EAAIG,iBAAiB,YAAauT,EAAOyT,YAAajhB,GACtDlG,EAAIG,iBAAiB,UAAWuT,EAAOyU,YAAY,SAbrD9hB,EAAOlG,iBAAiBilB,EAAYsE,MAAOhW,EAAO4R,cAAc,GAChEtlB,EAAIG,iBAAiBilB,EAAYwE,KAAMlW,EAAOyT,YAAajhB,GAC3DlG,EAAIG,iBAAiBilB,EAAYyE,IAAKnW,EAAOyU,YAAY,IAevDna,EAAOoW,eAAiBpW,EAAOqW,2BACjChe,EAAOlG,iBAAiB,QAASuT,EAAO8V,SAAS,GAKrD9V,EAAO/N,GAAIkb,EAAOE,KAAOF,EAAOG,QAAU,0CAA4C,wBAA0BiB,GAAU,IA6C1H6H,aA1CF,WACE,IAAIpW,EAAS3T,KAETiO,EAAS0F,EAAO1F,OAChBoX,EAAc1R,EAAO0R,YACrBngB,EAAKyO,EAAOzO,GACZogB,EAAY3R,EAAO2R,UAEnBhf,EAAsC,cAA7B2H,EAAOyU,kBAAoCxd,EAAKogB,EACzDnf,IAAY8H,EAAO2Z,OAIrB,GAAKvY,GAAQC,QAAUD,GAAQK,gBAAiBL,GAAQQ,sBAIjD,CACL,GAAIR,GAAQC,MAAO,CACjB,IAAIa,IAAwC,iBAAtBkV,EAAYsE,QAA4Bta,GAAQc,kBAAmBlC,EAAO4W,mBAAmB,CAAE+E,SAAS,EAAMzjB,SAAS,GAC7IG,EAAOjG,oBAAoBglB,EAAYsE,MAAOhW,EAAO4R,aAAcpV,GACnE7J,EAAOjG,oBAAoBglB,EAAYwE,KAAMlW,EAAOyT,YAAajhB,GACjEG,EAAOjG,oBAAoBglB,EAAYyE,IAAKnW,EAAOyU,WAAYjY,IAE5DlC,EAAO6R,gBAAkBgB,EAAOE,MAAQF,EAAOG,SAAahT,EAAO6R,gBAAkBzQ,GAAQC,OAASwR,EAAOE,OAChH1a,EAAOjG,oBAAoB,YAAasT,EAAO4R,cAAc,GAC7DtlB,EAAII,oBAAoB,YAAasT,EAAOyT,YAAajhB,GACzDlG,EAAII,oBAAoB,UAAWsT,EAAOyU,YAAY,SAbxD9hB,EAAOjG,oBAAoBglB,EAAYsE,MAAOhW,EAAO4R,cAAc,GACnEtlB,EAAII,oBAAoBglB,EAAYwE,KAAMlW,EAAOyT,YAAajhB,GAC9DlG,EAAII,oBAAoBglB,EAAYyE,IAAKnW,EAAOyU,YAAY,IAe1Dna,EAAOoW,eAAiBpW,EAAOqW,2BACjChe,EAAOjG,oBAAoB,QAASsT,EAAO8V,SAAS,GAKxD9V,EAAOrM,IAAKwZ,EAAOE,KAAOF,EAAOG,QAAU,0CAA4C,wBAA0BiB,KA0WjHC,YAlRgB,CAAEC,cAhFpB,WACE,IAAIzO,EAAS3T,KACTyZ,EAAc9F,EAAO8F,YACrBiE,EAAc/J,EAAO+J,YACrBO,EAAetK,EAAOsK,kBAAoC,IAAjBA,IAA0BA,EAAe,GACtF,IAAIhQ,EAAS0F,EAAO1F,OAChBkU,EAAclU,EAAOkU,YACzB,GAAKA,KAAgBA,GAAmD,IAApCnW,OAAOC,KAAKkW,GAAa7f,QAA7D,CAGA,IAAI0nB,EAAarW,EAAOsW,cAAc9H,GAEtC,GAAI6H,GAAcrW,EAAOuW,oBAAsBF,EAAY,CACzD,IAAIG,EAAuBH,KAAc7H,EAAcA,EAAY6H,QAAcjjB,EAC7EojB,GACF,CAAC,gBAAiB,eAAgB,kBAAkBje,QAAQ,SAAUgC,GACpE,IAAIkc,EAAaD,EAAqBjc,QACZ,IAAfkc,IAITD,EAAqBjc,GAHT,kBAAVA,GAA6C,SAAfkc,GAAwC,SAAfA,EAEtC,kBAAVlc,EACqBtF,WAAWwhB,GAEXnW,SAASmW,EAAY,IAJrB,UASpC,IAAIC,EAAmBF,GAAwBxW,EAAO2W,eAClDC,EAAmBF,EAAiBpN,WAAaoN,EAAiBpN,YAAchP,EAAOgP,UACvFuN,EAAcvc,EAAOkN,OAASkP,EAAiB/T,gBAAkBrI,EAAOqI,eAAiBiU,GAEzFA,GAAoB7M,GACtB/J,EAAO8W,kBAGTne,GAAMqC,OAAOgF,EAAO1F,OAAQoc,GAE5B/d,GAAMqC,OAAOgF,EAAQ,CACnBiQ,eAAgBjQ,EAAO1F,OAAO2V,eAC9BjG,eAAgBhK,EAAO1F,OAAO0P,eAC9BC,eAAgBjK,EAAO1F,OAAO2P,iBAGhCjK,EAAOuW,kBAAoBF,EAEvBQ,GAAe9M,IACjB/J,EAAO+L,cACP/L,EAAOsL,aACPtL,EAAOQ,eACPR,EAAO0J,QAAS5D,EAAcwE,EAAgBtK,EAAOsK,aAAc,GAAG,IAGxEtK,EAAO/B,KAAK,aAAcyY,MA2BoBJ,cAvBlD,SAAwB9H,GAGtB,GAAKA,EAAL,CACA,IAAI6H,GAAa,EACbU,EAAS,GACb1e,OAAOC,KAAKkW,GAAajW,QAAQ,SAAUye,GACzCD,EAAOznB,KAAK0nB,KAEdD,EAAOE,KAAK,SAAUvd,EAAGwd,GAAK,OAAO5W,SAAS5G,EAAG,IAAM4G,SAAS4W,EAAG,MACnE,IAAK,IAAIxoB,EAAI,EAAGA,EAAIqoB,EAAOpoB,OAAQD,GAAK,EAAG,CACzC,IAAIsoB,EAAQD,EAAOroB,GAVRrC,KAWAiO,OAAOmV,mBACZuH,GAASrpB,EAAIwpB,aACfd,EAAaW,GAENA,GAASrpB,EAAIwpB,aAAed,IACrCA,EAAaW,GAGjB,OAAOX,GAAc,SAsRrBhR,cAjJoB,CAAEA,cAjBxB,WACE,IAAIrF,EAAS3T,KACT+qB,EAAYpX,EAAOoM,SAEvBpM,EAAOoM,SAAsC,IAA3BpM,EAAOoB,SAASzS,OAClCqR,EAAOgK,gBAAkBhK,EAAOoM,SAChCpM,EAAOiK,gBAAkBjK,EAAOoM,SAG5BgL,IAAcpX,EAAOoM,UAAYpM,EAAO/B,KAAK+B,EAAOoM,SAAW,OAAS,UAExEgL,GAAaA,IAAcpX,EAAOoM,WACpCpM,EAAOiH,OAAQ,EACfjH,EAAOqX,WAAWzX,YAsJpB1P,QA9NY,CAAEonB,WApDhB,WACE,IACIC,EADSlrB,KACWkrB,WACpBjd,EAFSjO,KAEOiO,OAChBqG,EAHStU,KAGIsU,IACbV,EAJS5T,KAII4T,IACbuX,EAAW,GAEfA,EAASloB,KAAK,eACdkoB,EAASloB,KAAKgL,EAAOgP,WAEjBhP,EAAOoU,UACT8I,EAASloB,KAAK,aAEXoM,GAAQY,SACXkb,EAASloB,KAAK,cAEZgL,EAAOiP,YACTiO,EAASloB,KAAK,cAEZqR,GACF6W,EAASloB,KAAK,OAEa,EAAzBgL,EAAOiI,iBACTiV,EAASloB,KAAK,YAEZ6d,EAAOG,SACTkK,EAASloB,KAAK,WAEZ6d,EAAOE,KACTmK,EAASloB,KAAK,QAGXwN,EAAQC,MAAQD,EAAQE,UAAYtB,GAAQK,eAAiBL,GAAQQ,wBACxEsb,EAASloB,KAAM,OAAUgL,EAAgB,WAG3Ckd,EAASjf,QAAQ,SAAUkf,GACzBF,EAAWjoB,KAAKgL,EAAO6W,uBAAyBsG,KAGlDxX,EAAIjQ,SAASunB,EAAW3d,KAAK,OAWS8d,cARxC,WACE,IACIzX,EADS5T,KACI4T,IACbsX,EAFSlrB,KAEWkrB,WAExBtX,EAAI3P,YAAYinB,EAAW3d,KAAK,QAkOhC+d,OAzKW,CACXC,UArDF,SAAoBC,EAASC,EAAKC,EAAQC,EAAOC,EAAkBxjB,GACjE,IAAIyjB,EACJ,SAASC,IACH1jB,GAAYA,IAEbojB,EAAQO,UAAaH,EAmBxBE,IAlBIL,IACFI,EAAQ,IAAIvqB,EAAIQ,OACVkqB,OAASF,EACfD,EAAMI,QAAUH,EACZH,IACFE,EAAMF,MAAQA,GAEZD,IACFG,EAAMH,OAASA,GAEbD,IACFI,EAAMJ,IAAMA,IAGdK,KAkCJvH,cA1BF,WACE,IAAI5Q,EAAS3T,KAEb,SAAS8rB,IACH,MAAOnY,GAA8CA,IAAUA,EAAOmK,iBAC9C/W,IAAxB4M,EAAOuY,eAA8BvY,EAAOuY,cAAgB,GAC5DvY,EAAOuY,eAAiBvY,EAAOwY,aAAa7pB,SAC1CqR,EAAO1F,OAAOuW,qBAAuB7Q,EAAOJ,SAChDI,EAAO/B,KAAK,iBANhB+B,EAAOwY,aAAexY,EAAOC,IAAIjI,KAAK,OAStC,IAAK,IAAItJ,EAAI,EAAGA,EAAIsR,EAAOwY,aAAa7pB,OAAQD,GAAK,EAAG,CACtD,IAAImpB,EAAU7X,EAAOwY,aAAa9pB,GAClCsR,EAAO4X,UACLC,EACAA,EAAQY,YAAcZ,EAAQ5mB,aAAa,OAC3C4mB,EAAQE,QAAUF,EAAQ5mB,aAAa,UACvC4mB,EAAQG,OAASH,EAAQ5mB,aAAa,UACtC,EACAknB,OAiLFO,EAAmB,GAEnBtsB,EAAuB,SAAUiR,GACnC,SAASjR,IAIP,IAHA,IAAI8F,EAIAX,EACA+I,EAHAnI,EAAO,GAAIC,EAAMpB,UAAUrC,OACvByD,KAAQD,EAAMC,GAAQpB,UAAWoB,GAGrB,IAAhBD,EAAKxD,QAAgBwD,EAAK,GAAG4I,aAAe5I,EAAK,GAAG4I,cAAgB1C,OACtEiC,EAASnI,EAAK,IAEEZ,GAAfW,EAASC,GAAkB,GAAImI,EAASpI,EAAO,IAE7CoI,IAAUA,EAAS,IAExBA,EAAS3B,GAAMqC,OAAO,GAAIV,GACtB/I,IAAO+I,EAAO/I,KAAM+I,EAAO/I,GAAKA,GAEpC8L,EAAYzI,KAAKvI,KAAMiO,GAEvBjC,OAAOC,KAAKkZ,GAAYjZ,QAAQ,SAAUogB,GACxCtgB,OAAOC,KAAKkZ,EAAWmH,IAAiBpgB,QAAQ,SAAUqgB,GACnDxsB,EAAOyD,UAAU+oB,KACpBxsB,EAAOyD,UAAU+oB,GAAepH,EAAWmH,GAAgBC,QAMjE,IAAI5Y,EAAS3T,UACiB,IAAnB2T,EAAOxB,UAChBwB,EAAOxB,QAAU,IAEnBnG,OAAOC,KAAK0H,EAAOxB,SAASjG,QAAQ,SAAUkG,GAC5C,IAAIzS,EAASgU,EAAOxB,QAAQC,GAC5B,GAAIzS,EAAOsO,OAAQ,CACjB,IAAIue,EAAkBxgB,OAAOC,KAAKtM,EAAOsO,QAAQ,GAC7CsE,EAAe5S,EAAOsO,OAAOue,GACjC,GAA4B,iBAAjBja,GAA8C,OAAjBA,EAAyB,OACjE,KAAMia,KAAmBve,GAAU,YAAasE,GAAiB,QACjC,IAA5BtE,EAAOue,KACTve,EAAOue,GAAmB,CAAE7X,SAAS,IAGF,iBAA5B1G,EAAOue,IACT,YAAave,EAAOue,KAEzBve,EAAOue,GAAiB7X,SAAU,GAE/B1G,EAAOue,KAAoBve,EAAOue,GAAmB,CAAE7X,SAAS,OAKzE,IAAI8X,EAAengB,GAAMqC,OAAO,GAAI6T,GACpC7O,EAAO3B,iBAAiBya,GAGxB9Y,EAAO1F,OAAS3B,GAAMqC,OAAO,GAAI8d,EAAcJ,EAAkBpe,GACjE0F,EAAO2W,eAAiBhe,GAAMqC,OAAO,GAAIgF,EAAO1F,QAChD0F,EAAO+Y,aAAepgB,GAAMqC,OAAO,GAAIV,GAMvC,IAAI2F,GAHJD,EAAOpR,EAAIA,GAGCoR,EAAO1F,OAAO/I,IAG1B,GAFAA,EAAK0O,EAAI,GAET,CAIA,GAAiB,EAAbA,EAAItR,OAAY,CAClB,IAAIqqB,EAAU,GAKd,OAJA/Y,EAAI/J,KAAK,SAAUO,EAAOwiB,GACxB,IAAIC,EAAYvgB,GAAMqC,OAAO,GAAIV,EAAQ,CAAE/I,GAAI0nB,IAC/CD,EAAQ1pB,KAAK,IAAIlD,EAAO8sB,MAEnBF,EAGTznB,EAAGyO,OAASA,EACZC,EAAI5O,KAAK,SAAU2O,GAGnB,IAmDQrE,EACA6R,EApDJ/M,EAAaR,EAAI7S,SAAU,IAAO4S,EAAO1F,OAAmB,cAwHhE,OArHA3B,GAAMqC,OAAOgF,EAAQ,CACnBC,IAAKA,EACL1O,GAAIA,EACJkP,WAAYA,EACZkR,UAAWlR,EAAW,GAGtB8W,WAAY,GAGZrW,OAAQtS,IACRyS,WAAY,GACZD,SAAU,GACVE,gBAAiB,GAGjBlB,aAAc,WACZ,MAAmC,eAA5BJ,EAAO1F,OAAOgP,WAEvBjJ,WAAY,WACV,MAAmC,aAA5BL,EAAO1F,OAAOgP,WAGvB3I,IAA+B,QAAzBpP,EAAGiY,IAAItM,eAAoD,QAAzB+C,EAAIlK,IAAI,aAChD6K,aAA0C,eAA5BZ,EAAO1F,OAAOgP,YAAwD,QAAzB/X,EAAGiY,IAAItM,eAAoD,QAAzB+C,EAAIlK,IAAI,cACrG8K,SAAwC,gBAA9BJ,EAAW1K,IAAI,WAGzB+P,YAAa,EACbwB,UAAW,EAGXN,aAAa,EACbC,OAAO,EAGPd,UAAW,EACX+C,kBAAmB,EACnBtC,SAAU,EACVuO,SAAU,EACV1L,WAAW,EAGXO,eAAgBhK,EAAO1F,OAAO0P,eAC9BC,eAAgBjK,EAAO1F,OAAO2P,eAG9ByH,aACM/V,EAAQ,CAAC,aAAc,YAAa,YACpC6R,EAAU,CAAC,YAAa,YAAa,WACrC9R,GAAQK,cACVyR,EAAU,CAAC,cAAe,cAAe,aAChC9R,GAAQQ,wBACjBsR,EAAU,CAAC,gBAAiB,gBAAiB,gBAE/CxN,EAAOmZ,iBAAmB,CACxBnD,MAAOra,EAAM,GACbua,KAAMva,EAAM,GACZwa,IAAKxa,EAAM,IAEbqE,EAAOoZ,mBAAqB,CAC1BpD,MAAOxI,EAAQ,GACf0I,KAAM1I,EAAQ,GACd2I,IAAK3I,EAAQ,IAER9R,GAAQC,QAAUqE,EAAO1F,OAAO6R,cAAgBnM,EAAOmZ,iBAAmBnZ,EAAOoZ,oBAE1FvH,gBAAiB,CACfO,eAAWhf,EACXif,aAASjf,EACT4f,yBAAqB5f,EACrB+f,oBAAgB/f,EAChB6f,iBAAa7f,EACbyV,sBAAkBzV,EAClB+gB,oBAAgB/gB,EAChBigB,wBAAoBjgB,EAEpBmgB,aAAc,iDAEdsB,cAAelc,GAAMM,MACrB6b,kBAAc1hB,EAEdkhB,WAAY,GACZF,yBAAqBhhB,EACrB4e,kBAAc5e,EACd8f,iBAAa9f,GAIfkf,YAAY,EAGZrC,eAAgBjQ,EAAO1F,OAAO2V,eAE9B6B,QAAS,CACPc,OAAQ,EACRC,OAAQ,EACRN,SAAU,EACVG,SAAU,EACV5G,KAAM,GAIR0M,aAAc,GACdD,aAAc,IAKhBvY,EAAOtB,aAGHsB,EAAO1F,OAAOwU,MAChB9O,EAAO8O,OAIF9O,GAGJ3C,IAAcjR,EAAOitB,UAAYhc,GAItC,IAAIG,EAAkB,CAAEkb,iBAAkB,CAAEhb,cAAc,GAAOmR,SAAU,CAAEnR,cAAc,GAAO5N,MAAO,CAAE4N,cAAc,GAAO9O,EAAG,CAAE8O,cAAc,IA4QnJ,QA/QAtR,EAAOyD,UAAYwI,OAAO4G,OAAQ5B,GAAeA,EAAYxN,YAC5CkL,YAAc3O,GAIxByD,UAAUub,qBAAuB,WACtC,IAAIpL,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChB4G,EAASlB,EAAOkB,OAChBG,EAAarB,EAAOqB,WACpBX,EAAaV,EAAOO,KACpBuF,EAAc9F,EAAO8F,YACrBwT,EAAM,EACV,GAAIhf,EAAO+J,eAAgB,CAGzB,IAFA,IACIkV,EADAtX,EAAYf,EAAO4E,GAAa1B,gBAE3B1V,EAAIoX,EAAc,EAAGpX,EAAIwS,EAAOvS,OAAQD,GAAK,EAChDwS,EAAOxS,KAAO6qB,IAEhBD,GAAO,EACS5Y,GAFhBuB,GAAaf,EAAOxS,GAAG0V,mBAEOmV,GAAY,IAG9C,IAAK,IAAI7U,EAAMoB,EAAc,EAAU,GAAPpB,EAAUA,GAAO,EAC3CxD,EAAOwD,KAAS6U,IAElBD,GAAO,EACS5Y,GAFhBuB,GAAaf,EAAOwD,GAAKN,mBAEKmV,GAAY,SAI9C,IAAK,IAAI3U,EAAMkB,EAAc,EAAGlB,EAAM1D,EAAOvS,OAAQiW,GAAO,EACtDvD,EAAWuD,GAAOvD,EAAWyE,GAAepF,IAC9C4Y,GAAO,GAIb,OAAOA,GAGTltB,EAAOyD,UAAU+P,OAAS,WACxB,IAAII,EAAS3T,KACb,GAAK2T,IAAUA,EAAOmK,UAAtB,CACA,IAAI/I,EAAWpB,EAAOoB,SAClB9G,EAAS0F,EAAO1F,OAEhBA,EAAOkU,aACTxO,EAAOyO,gBAETzO,EAAOH,aACPG,EAAOQ,eACPR,EAAO6G,iBACP7G,EAAOoH,sBAUHpH,EAAO1F,OAAOoU,UAChB5F,IACI9I,EAAO1F,OAAOiP,YAChBvJ,EAAOyF,sBAG4B,SAAhCzF,EAAO1F,OAAOqI,eAA0D,EAA9B3C,EAAO1F,OAAOqI,gBAAsB3C,EAAOiH,QAAUjH,EAAO1F,OAAO+J,eACnGrE,EAAO0J,QAAQ1J,EAAOkB,OAAOvS,OAAS,EAAG,GAAG,GAAO,GAEnDqR,EAAO0J,QAAQ1J,EAAO8F,YAAa,GAAG,GAAO,KAG1DgD,IAGAxO,EAAO8K,eAAiBhE,IAAapB,EAAOoB,UAC9CpB,EAAOqF,gBAETrF,EAAO/B,KAAK,UA1BZ,SAAS6K,IACP,IAAI0Q,EAAiBxZ,EAAOY,cAAmC,EAApBZ,EAAOmG,UAAiBnG,EAAOmG,UACtEwI,EAAenM,KAAKoM,IAAIpM,KAAKK,IAAI2W,EAAgBxZ,EAAO+G,gBAAiB/G,EAAOyG,gBACpFzG,EAAO8I,aAAa6F,GACpB3O,EAAOiI,oBACPjI,EAAOoH,wBAwBXhb,EAAOyD,UAAUinB,gBAAkB,SAA0B2C,EAAcC,QACrD,IAAfA,IAAwBA,GAAa,GAE1C,IAAI1Z,EAAS3T,KACTstB,EAAmB3Z,EAAO1F,OAAOgP,UAKrC,OAJKmQ,IAEHA,EAAoC,eAArBE,EAAoC,WAAa,cAE7DF,IAAiBE,GAAuC,eAAjBF,GAAkD,aAAjBA,IAIpD,aAArBE,IACF3Z,EAAOC,IACJ3P,YAAc0P,EAAO1F,OAA6B,uBAAI,yBACtDtK,SAAU,GAAMgQ,EAAO1F,OAA6B,uBAAImf,IAEtD3c,EAAQC,MAAQD,EAAQE,UAAYtB,GAAQK,eAAiBL,GAAQQ,wBACxE8D,EAAOC,IAAIjQ,SAAWgQ,EAAO1F,OAA6B,uBAAI,OAASmf,IAGlD,eAArBE,IACF3Z,EAAOC,IACJ3P,YAAc0P,EAAO1F,OAA6B,uBAAI,6BACtDtK,SAAU,GAAMgQ,EAAO1F,OAA6B,uBAAImf,IAEtD3c,EAAQC,MAAQD,EAAQE,UAAYtB,GAAQK,eAAiBL,GAAQQ,wBACxE8D,EAAOC,IAAIjQ,SAAWgQ,EAAO1F,OAA6B,uBAAI,OAASmf,IAI3EzZ,EAAO1F,OAAOgP,UAAYmQ,EAE1BzZ,EAAOkB,OAAOhL,KAAK,SAAU0T,EAAYgQ,GAClB,aAAjBH,EACFG,EAAQtsB,MAAMwS,MAAQ,GAEtB8Z,EAAQtsB,MAAMyS,OAAS,KAI3BC,EAAO/B,KAAK,mBACRyb,GAAc1Z,EAAOJ,UAjChBI,GAsCX5T,EAAOyD,UAAUif,KAAO,WACtB,IAAI9O,EAAS3T,KACT2T,EAAO+J,cAEX/J,EAAO/B,KAAK,cAGR+B,EAAO1F,OAAOkU,aAChBxO,EAAOyO,gBAITzO,EAAOsX,aAGHtX,EAAO1F,OAAOkN,MAChBxH,EAAOsL,aAITtL,EAAOH,aAGPG,EAAOQ,eAEHR,EAAO1F,OAAO8K,eAChBpF,EAAOqF,gBAILrF,EAAO1F,OAAO0R,YAChBhM,EAAOiM,gBAGLjM,EAAO1F,OAAOsW,eAChB5Q,EAAO4Q,gBAIL5Q,EAAO1F,OAAOkN,KAChBxH,EAAO0J,QAAQ1J,EAAO1F,OAAOwP,aAAe9J,EAAOsK,aAAc,EAAGtK,EAAO1F,OAAOiX,oBAElFvR,EAAO0J,QAAQ1J,EAAO1F,OAAOwP,aAAc,EAAG9J,EAAO1F,OAAOiX,oBAI9DvR,EAAOyR,eAGPzR,EAAO+J,aAAc,EAGrB/J,EAAO/B,KAAK,UAGd7R,EAAOyD,UAAUgqB,QAAU,SAAkBC,EAAgBC,QACnC,IAAnBD,IAA4BA,GAAiB,QAC7B,IAAhBC,IAAyBA,GAAc,GAE5C,IAAI/Z,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAChB2F,EAAMD,EAAOC,IACbQ,EAAaT,EAAOS,WACpBS,EAASlB,EAAOkB,OAEpB,YAA6B,IAAlBlB,EAAO1F,QAA0B0F,EAAOmK,YAInDnK,EAAO/B,KAAK,iBAGZ+B,EAAO+J,aAAc,EAGrB/J,EAAOoW,eAGH9b,EAAOkN,MACTxH,EAAO+L,cAILgO,IACF/Z,EAAO0X,gBACPzX,EAAI9O,WAAW,SACfsP,EAAWtP,WAAW,SAClB+P,GAAUA,EAAOvS,QACnBuS,EACG5Q,YAAY,CACXgK,EAAO+L,kBACP/L,EAAOiN,iBACPjN,EAAOsN,eACPtN,EAAOwN,gBAAiBlO,KAAK,MAC9BzI,WAAW,SACXA,WAAW,2BACXA,WAAW,sBACXA,WAAW,oBAIlB6O,EAAO/B,KAAK,WAGZ5F,OAAOC,KAAK0H,EAAO1C,iBAAiB/E,QAAQ,SAAUgF,GACpDyC,EAAOrM,IAAI4J,MAGU,IAAnBuc,IACF9Z,EAAOC,IAAI,GAAGD,OAAS,KACvBA,EAAOC,IAAI5O,KAAK,SAAU,MAC1BsH,GAAMC,YAAYoH,IAEpBA,EAAOmK,WAAY,GA/CV,MAoDX/d,EAAO4tB,eAAiB,SAAyBC,GAC/CthB,GAAMqC,OAAO0d,EAAkBuB,IAGjCzc,EAAgBkb,iBAAiB9b,IAAM,WACrC,OAAO8b,GAGTlb,EAAgBqR,SAASjS,IAAM,WAC7B,OAAOiS,GAGTrR,EAAgB1N,MAAM8M,IAAM,WAC1B,OAAOS,GAGTG,EAAgB5O,EAAEgO,IAAM,WACtB,OAAOhO,GAGTyJ,OAAOsH,iBAAkBvT,EAAQoR,GAE1BpR,EAjeiB,CAkexBiR,GAEE6c,EAAW,CACb7a,KAAM,SACNC,MAAO,CACL8N,OAAQD,GAEV5N,OAAQ,CACN6N,OAAQD,IAIRgN,EAAY,CACd9a,KAAM,UACNC,MAAO,CACL8a,QAAS1e,IAEX6D,OAAQ,CACN6a,QAAS1e,KAIT2e,EAAY,CACdhb,KAAM,UACNC,MAAO,CACLgb,QAASxd,GAEXyC,OAAQ,CACN+a,QAASxd,IAITyd,EAAS,CACXlb,KAAM,SACNJ,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnBwa,OAAQ,CACNC,cAAe,WACRza,IAAUA,EAAOmK,WAAcnK,EAAO+J,cAC3C/J,EAAO/B,KAAK,gBACZ+B,EAAO/B,KAAK,YAEdyc,yBAA0B,WACnB1a,IAAUA,EAAOmK,WAAcnK,EAAO+J,aAC3C/J,EAAO/B,KAAK,0BAKpBhM,GAAI,CACF6c,KAAM,WAGJnhB,EAAIlB,iBAAiB,SAFRJ,KAEyBmuB,OAAOC,eAG7C9sB,EAAIlB,iBAAiB,oBALRJ,KAKoCmuB,OAAOE,2BAE1Db,QAAS,WAEPlsB,EAAIjB,oBAAoB,SADXL,KAC4BmuB,OAAOC,eAChD9sB,EAAIjB,oBAAoB,oBAFXL,KAEuCmuB,OAAOE,6BAK7DC,EAAW,CACbC,KAAMjtB,EAAIktB,kBAAoBltB,EAAImtB,uBAClCC,OAAQ,SAAgBpoB,EAAQqoB,QACb,IAAZA,IAAqBA,EAAU,IAEpC,IAAIhb,EAAS3T,KAGTkQ,EAAW,IADIoe,EAASC,KACI,SAAUK,GAIxC,GAAyB,IAArBA,EAAUtsB,OAAd,CAIA,IAAIusB,EAAiB,WACnBlb,EAAO/B,KAAK,iBAAkBgd,EAAU,KAGtCttB,EAAIwtB,sBACNxtB,EAAIwtB,sBAAsBD,GAE1BvtB,EAAIW,WAAW4sB,EAAgB,QAV/Blb,EAAO/B,KAAK,iBAAkBgd,EAAU,MAc5C1e,EAAS6e,QAAQzoB,EAAQ,CACvB0oB,gBAA0C,IAAvBL,EAAQK,YAAoCL,EAAQK,WACvEC,eAAwC,IAAtBN,EAAQM,WAAmCN,EAAQM,UACrEC,mBAAgD,IAA1BP,EAAQO,eAAuCP,EAAQO,gBAG/Evb,EAAOzD,SAASif,UAAUlsB,KAAKiN,IAEjCuS,KAAM,WACJ,IAAI9O,EAAS3T,KACb,GAAKqP,GAAQa,UAAayD,EAAO1F,OAAOiC,SAAxC,CACA,GAAIyD,EAAO1F,OAAOmhB,eAEhB,IADA,IAAIC,EAAmB1b,EAAOC,IAAIhN,UACzBvE,EAAI,EAAGA,EAAIgtB,EAAiB/sB,OAAQD,GAAK,EAChDsR,EAAOzD,SAASwe,OAAOW,EAAiBhtB,IAI5CsR,EAAOzD,SAASwe,OAAO/a,EAAOC,IAAI,GAAI,CAAEqb,UAAWtb,EAAO1F,OAAOqhB,uBAGjE3b,EAAOzD,SAASwe,OAAO/a,EAAOS,WAAW,GAAI,CAAE4a,YAAY,MAE7DxB,QAAS,WACMxtB,KACNkQ,SAASif,UAAUjjB,QAAQ,SAAUgE,GAC1CA,EAASqf,eAFEvvB,KAINkQ,SAASif,UAAY,KAI5BK,EAAa,CACfxc,KAAM,WACN/E,OAAQ,CACNiC,UAAU,EACVkf,gBAAgB,EAChBE,sBAAsB,GAExB1c,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnBkQ,SAAU,CACRuS,KAAM6L,EAAS7L,KAAK/P,KAHX1S,MAIT0uB,OAAQJ,EAASI,OAAOhc,KAJf1S,MAKTwtB,QAASc,EAASd,QAAQ9a,KALjB1S,MAMTmvB,UAAW,OAIjBvpB,GAAI,CACF6c,KAAM,WACSziB,KACNkQ,SAASuS,QAElB+K,QAAS,WACMxtB,KACNkQ,SAASsd,aAKlBiC,EAAU,CACZlc,OAAQ,SAAgBmc,GACtB,IAAI/b,EAAS3T,KACT2vB,EAAMhc,EAAO1F,OACbqI,EAAgBqZ,EAAIrZ,cACpB4B,EAAiByX,EAAIzX,eACrBF,EAAiB2X,EAAI3X,eACrB4X,EAAQjc,EAAO1F,OAAOyG,QACtBmb,EAAkBD,EAAMC,gBACxBC,EAAiBF,EAAME,eACvBC,EAAQpc,EAAOe,QACfsb,EAAeD,EAAME,KACrBC,EAAaH,EAAMlhB,GACnBgG,EAASkb,EAAMlb,OACfsb,EAAqBJ,EAAM/a,WAC3Bob,EAAcL,EAAMK,YACpBC,EAAiBN,EAAMhnB,OAC3B4K,EAAOiI,oBACP,IAEI0U,EAIAC,EACAC,EAPA/W,EAAc9F,EAAO8F,aAAe,EAGb6W,EAAvB3c,EAAOY,aAA6B,QACpBZ,EAAOI,eAAiB,OAAS,MAIjDiE,GACFuY,EAAcpa,KAAKC,MAAME,EAAgB,GAAK4B,EAAiB2X,EAC/DW,EAAera,KAAKC,MAAME,EAAgB,GAAK4B,EAAiB4X,IAEhES,EAAcja,GAAiB4B,EAAiB,GAAK2X,EACrDW,EAAetY,EAAiB4X,GAElC,IAAIG,EAAO9Z,KAAKK,KAAKiD,GAAe,GAAK+W,EAAc,GACnD3hB,EAAKsH,KAAKoM,KAAK9I,GAAe,GAAK8W,EAAa1b,EAAOvS,OAAS,GAChEyG,GAAU4K,EAAOqB,WAAWib,IAAS,IAAMtc,EAAOqB,WAAW,IAAM,GASvE,SAASyb,IACP9c,EAAOQ,eACPR,EAAO6G,iBACP7G,EAAOoH,sBACHpH,EAAO+c,MAAQ/c,EAAO1F,OAAOyiB,KAAK/b,SACpChB,EAAO+c,KAAKC,OAIhB,GAhBArkB,GAAMqC,OAAOgF,EAAOe,QAAS,CAC3Bub,KAAMA,EACNphB,GAAIA,EACJ9F,OAAQA,EACRiM,WAAYrB,EAAOqB,aAYjBgb,IAAiBC,GAAQC,IAAerhB,IAAO6gB,EAKjD,OAJI/b,EAAOqB,aAAemb,GAAsBpnB,IAAWsnB,GACzD1c,EAAOkB,OAAOnL,IAAI4mB,EAAavnB,EAAS,WAE1C4K,EAAO6G,iBAGT,GAAI7G,EAAO1F,OAAOyG,QAAQkc,eAcxB,OAbAjd,EAAO1F,OAAOyG,QAAQkc,eAAeroB,KAAKoL,EAAQ,CAChD5K,OAAQA,EACRknB,KAAMA,EACNphB,GAAIA,EACJgG,OAAS,WAEP,IADA,IAAIgc,EAAiB,GACZxuB,EAAI4tB,EAAM5tB,GAAKwM,EAAIxM,GAAK,EAC/BwuB,EAAe5tB,KAAK4R,EAAOxS,IAE7B,OAAOwuB,EALD,UAQVJ,IAGF,IAAIK,EAAiB,GACjBC,EAAgB,GACpB,GAAIrB,EACF/b,EAAOS,WAAWzI,KAAM,IAAOgI,EAAO1F,OAAiB,YAAI/J,cAE3D,IAAK,IAAI7B,EAAI2tB,EAAc3tB,GAAK6tB,EAAY7tB,GAAK,GAC3CA,EAAI4tB,GAAYphB,EAAJxM,IACdsR,EAAOS,WAAWzI,KAAM,IAAOgI,EAAO1F,OAAiB,WAAI,6BAAgC5L,EAAI,MAAQ6B,SAI7G,IAAK,IAAImU,EAAM,EAAGA,EAAMxD,EAAOvS,OAAQ+V,GAAO,EACjC4X,GAAP5X,GAAeA,GAAOxJ,SACE,IAAfqhB,GAA8BR,EACvCqB,EAAc9tB,KAAKoV,IAET6X,EAAN7X,GAAoB0Y,EAAc9tB,KAAKoV,GACvCA,EAAM2X,GAAgBc,EAAe7tB,KAAKoV,KAIpD0Y,EAAc7kB,QAAQ,SAAU9B,GAC9BuJ,EAAOS,WAAW3J,OAAO2lB,EAAYvb,EAAOzK,GAAQA,MAEtD0mB,EAAelG,KAAK,SAAUvd,EAAGwd,GAAK,OAAOA,EAAIxd,IAAMnB,QAAQ,SAAU9B,GACvEuJ,EAAOS,WAAWtJ,QAAQslB,EAAYvb,EAAOzK,GAAQA,MAEvDuJ,EAAOS,WAAWrT,SAAS,iBAAiB2I,IAAI4mB,EAAavnB,EAAS,MACtE0nB,KAEFL,YAAa,SAAqBxZ,EAAOxM,GACvC,IAAIuJ,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAOyG,QAC3B,GAAIzG,EAAO+iB,OAASrd,EAAOe,QAAQsc,MAAM5mB,GACvC,OAAOuJ,EAAOe,QAAQsc,MAAM5mB,GAE9B,IAAI6mB,EAAWhjB,EAAOmiB,YAClB7tB,EAAE0L,EAAOmiB,YAAY7nB,KAAKoL,EAAQiD,EAAOxM,IACzC7H,EAAG,eAAmBoR,EAAO1F,OAAiB,WAAI,8BAAkC7D,EAAQ,KAAQwM,EAAQ,UAGhH,OAFKqa,EAAS1sB,KAAK,4BAA8B0sB,EAAS1sB,KAAK,0BAA2B6F,GACtF6D,EAAO+iB,QAASrd,EAAOe,QAAQsc,MAAM5mB,GAAS6mB,GAC3CA,GAET9Q,YAAa,SAAqBtL,GAEhC,GAAsB,iBAAXA,GAAuB,WAAYA,EAC5C,IAAK,IAAIxS,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAClCwS,EAAOxS,IAHFrC,KAGe0U,QAAQG,OAAO5R,KAAK4R,EAAOxS,SAH1CrC,KAMJ0U,QAAQG,OAAO5R,KAAK4R,GANhB7U,KAQN0U,QAAQnB,QAAO,IAExB6M,aAAc,SAAsBvL,GAClC,IAAIlB,EAAS3T,KACTyZ,EAAc9F,EAAO8F,YACrBoC,EAAiBpC,EAAc,EAC/ByX,EAAoB,EAExB,GAAIrf,MAAMC,QAAQ+C,GAAS,CACzB,IAAK,IAAIxS,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAClCwS,EAAOxS,IAAMsR,EAAOe,QAAQG,OAAOpO,QAAQoO,EAAOxS,IAExDwZ,EAAiBpC,EAAc5E,EAAOvS,OACtC4uB,EAAoBrc,EAAOvS,YAE3BqR,EAAOe,QAAQG,OAAOpO,QAAQoO,GAEhC,GAAIlB,EAAO1F,OAAOyG,QAAQsc,MAAO,CAC/B,IAAIA,EAAQrd,EAAOe,QAAQsc,MACvBG,EAAW,GACfnlB,OAAOC,KAAK+kB,GAAO9kB,QAAQ,SAAUklB,GACnCD,EAASld,SAASmd,EAAa,IAAMF,GAAqBF,EAAMI,KAElEzd,EAAOe,QAAQsc,MAAQG,EAEzBxd,EAAOe,QAAQnB,QAAO,GACtBI,EAAO0J,QAAQxB,EAAgB,IAEjC6E,YAAa,SAAqBC,GAChC,IAAIhN,EAAS3T,KACb,GAAI,MAAO2gB,EAAX,CACA,IAAIlH,EAAc9F,EAAO8F,YACzB,GAAI5H,MAAMC,QAAQ6O,GAChB,IAAK,IAAIte,EAAIse,EAAcre,OAAS,EAAQ,GAALD,EAAQA,GAAK,EAClDsR,EAAOe,QAAQG,OAAOpN,OAAOkZ,EAActe,GAAI,GAC3CsR,EAAO1F,OAAOyG,QAAQsc,cACjBrd,EAAOe,QAAQsc,MAAMrQ,EAActe,IAExCse,EAActe,GAAKoX,IAAeA,GAAe,GACrDA,EAActD,KAAKK,IAAIiD,EAAa,QAGtC9F,EAAOe,QAAQG,OAAOpN,OAAOkZ,EAAe,GACxChN,EAAO1F,OAAOyG,QAAQsc,cACjBrd,EAAOe,QAAQsc,MAAMrQ,GAE1BA,EAAgBlH,IAAeA,GAAe,GAClDA,EAActD,KAAKK,IAAIiD,EAAa,GAEtC9F,EAAOe,QAAQnB,QAAO,GACtBI,EAAO0J,QAAQ5D,EAAa,KAE9BoH,gBAAiB,WACf,IAAIlN,EAAS3T,KACb2T,EAAOe,QAAQG,OAAS,GACpBlB,EAAO1F,OAAOyG,QAAQsc,QACxBrd,EAAOe,QAAQsc,MAAQ,IAEzBrd,EAAOe,QAAQnB,QAAO,GACtBI,EAAO0J,QAAQ,EAAG,KAIlBgU,EAAY,CACdre,KAAM,UACN/E,OAAQ,CACNyG,QAAS,CACPC,SAAS,EACTE,OAAQ,GACRmc,OAAO,EACPZ,YAAa,KACbQ,eAAgB,KAChBf,gBAAiB,EACjBC,eAAgB,IAGpBld,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnBe,QAAS,CACPnB,OAAQkc,EAAQlc,OAAOb,KAAKiB,GAC5BwM,YAAasP,EAAQtP,YAAYzN,KAAKiB,GACtCyM,aAAcqP,EAAQrP,aAAa1N,KAAKiB,GACxC+M,YAAa+O,EAAQ/O,YAAYhO,KAAKiB,GACtCkN,gBAAiB4O,EAAQ5O,gBAAgBnO,KAAKiB,GAC9Cyc,YAAaX,EAAQW,YAAY1d,KAAKiB,GACtCkB,OAAQlB,EAAO1F,OAAOyG,QAAQG,OAC9Bmc,MAAO,OAIbprB,GAAI,CACF0rB,WAAY,WACV,IAAI3d,EAAS3T,KACb,GAAK2T,EAAO1F,OAAOyG,QAAQC,QAA3B,CACAhB,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,WACjE,IAAIsjB,EAAkB,CACpBtY,qBAAqB,GAEvB3M,GAAMqC,OAAOgF,EAAO1F,OAAQsjB,GAC5BjlB,GAAMqC,OAAOgF,EAAO2W,eAAgBiH,GAE/B5d,EAAO1F,OAAOwP,cACjB9J,EAAOe,QAAQnB,WAGnBkJ,aAAc,WACCzc,KACDiO,OAAOyG,QAAQC,SADd3U,KAEN0U,QAAQnB,YAKjBie,EAAW,CACbC,OAAQ,SAAgBrqB,GACtB,IAAIuM,EAAS3T,KACTsU,EAAMX,EAAOY,aACblO,EAAIe,EACJf,EAAEqf,gBAAiBrf,EAAIA,EAAEqf,eAC7B,IAAIgM,EAAKrrB,EAAEsrB,SAAWtrB,EAAEurB,SAExB,IAAKje,EAAOgK,iBAAoBhK,EAAOI,gBAAyB,KAAP2d,GAAe/d,EAAOK,cAAuB,KAAP0d,GAC7F,OAAO,EAET,IAAK/d,EAAOiK,iBAAoBjK,EAAOI,gBAAyB,KAAP2d,GAAe/d,EAAOK,cAAuB,KAAP0d,GAC7F,OAAO,EAET,KAAIrrB,EAAEwrB,UAAYxrB,EAAEyrB,QAAUzrB,EAAE0rB,SAAW1rB,EAAE2rB,SAGzC/xB,EAAIK,eAAiBL,EAAIK,cAAcE,WAA0D,UAA7CP,EAAIK,cAAcE,SAASqQ,eAA0E,aAA7C5Q,EAAIK,cAAcE,SAASqQ,gBAA3I,CAGA,GAAI8C,EAAO1F,OAAOgkB,SAASC,iBAA0B,KAAPR,GAAoB,KAAPA,GAAoB,KAAPA,GAAoB,KAAPA,GAAY,CAC/F,IAAIS,GAAS,EAEb,GAAoE,EAAhExe,EAAOC,IAAIhN,QAAS,IAAO+M,EAAO1F,OAAiB,YAAI3L,QAAsF,IAAxEqR,EAAOC,IAAIhN,QAAS,IAAO+M,EAAO1F,OAAuB,kBAAI3L,OACpI,OAEF,IAAI8vB,EAAc9wB,EAAIwpB,WAClBuH,EAAe/wB,EAAIgxB,YACnBC,EAAe5e,EAAOC,IAAI7K,SAC1BuL,IAAOie,EAAa9oB,MAAQkK,EAAOC,IAAI,GAAGtK,YAM9C,IALA,IAAIkpB,EAAc,CAChB,CAACD,EAAa9oB,KAAM8oB,EAAa/oB,KACjC,CAAC+oB,EAAa9oB,KAAOkK,EAAOF,MAAO8e,EAAa/oB,KAChD,CAAC+oB,EAAa9oB,KAAM8oB,EAAa/oB,IAAMmK,EAAOD,QAC9C,CAAC6e,EAAa9oB,KAAOkK,EAAOF,MAAO8e,EAAa/oB,IAAMmK,EAAOD,SACtDrR,EAAI,EAAGA,EAAImwB,EAAYlwB,OAAQD,GAAK,EAAG,CAC9C,IAAIsoB,EAAQ6H,EAAYnwB,GAEV,GAAZsoB,EAAM,IAAWA,EAAM,IAAMyH,GACd,GAAZzH,EAAM,IAAWA,EAAM,IAAM0H,IAEhCF,GAAS,GAGb,IAAKA,EAAU,OAEbxe,EAAOI,gBACE,KAAP2d,GAAoB,KAAPA,IACXrrB,EAAE4gB,eAAkB5gB,EAAE4gB,iBACnB5gB,EAAEosB,aAAc,IAEb,KAAPf,IAAcpd,GAAgB,KAAPod,GAAapd,IAAQX,EAAOuK,aAC5C,KAAPwT,IAAcpd,GAAgB,KAAPod,GAAapd,IAAQX,EAAO0K,cAE7C,KAAPqT,GAAoB,KAAPA,IACXrrB,EAAE4gB,eAAkB5gB,EAAE4gB,iBACnB5gB,EAAEosB,aAAc,GAEd,KAAPf,GAAa/d,EAAOuK,YACb,KAAPwT,GAAa/d,EAAO0K,aAE1B1K,EAAO/B,KAAK,WAAY8f,KAG1BgB,OAAQ,WACO1yB,KACFiyB,SAAStd,UACpBpS,EAAEtC,GAAK2F,GAAG,UAFG5F,KAEeiyB,SAASR,QAFxBzxB,KAGNiyB,SAAStd,SAAU,IAE5Bge,QAAS,WACM3yB,KACDiyB,SAAStd,UACrBpS,EAAEtC,GAAKqH,IAAI,UAFEtH,KAEgBiyB,SAASR,QAFzBzxB,KAGNiyB,SAAStd,SAAU,KAI1Bie,EAAa,CACf5f,KAAM,WACN/E,OAAQ,CACNgkB,SAAU,CACRtd,SAAS,EACTud,gBAAgB,IAGpBtf,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnBiyB,SAAU,CACRtd,SAAS,EACT+d,OAAQlB,EAASkB,OAAOhgB,KAJf1S,MAKT2yB,QAASnB,EAASmB,QAAQjgB,KALjB1S,MAMTyxB,OAAQD,EAASC,OAAO/e,KANf1S,UAUf4F,GAAI,CACF6c,KAAM,WACSziB,KACFiO,OAAOgkB,SAAStd,SADd3U,KAEJiyB,SAASS,UAGpBlF,QAAS,WACMxtB,KACFiyB,SAAStd,SADP3U,KAEJiyB,SAASU,aA6BxB,IAAIE,EAAa,CACfC,eAAgBxmB,GAAMM,MACtBxF,OACoD,EAA9C9F,EAAIE,UAAUC,UAAUqB,QAAQ,WAA0B,iBA1BlE,WACE,IAAIoO,EAAY,UACZ6hB,EAAc7hB,KAAajR,EAE/B,IAAK8yB,EAAa,CAChB,IAAIC,EAAU/yB,EAAIa,cAAc,OAChCkyB,EAAQ9xB,aAAagQ,EAAW,WAChC6hB,EAA4C,mBAAvBC,EAAQ9hB,GAc/B,OAXK6hB,GACA9yB,EAAIgzB,gBACJhzB,EAAIgzB,eAAeC,aAGuB,IAA1CjzB,EAAIgzB,eAAeC,WAAW,GAAI,MAGrCH,EAAc9yB,EAAIgzB,eAAeC,WAAW,eAAgB,QAGvDH,EAMEI,GAAqB,QAAU,aAExC7U,UAAW,SAAmBjY,GAE5B,IAII+sB,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EAkDT,MA/CI,WAAYltB,IACdgtB,EAAKhtB,EAAEwB,QAEL,eAAgBxB,IAClBgtB,GAAMhtB,EAAEmtB,WAAa,KAEnB,gBAAiBntB,IACnBgtB,GAAMhtB,EAAEotB,YAAc,KAEpB,gBAAiBptB,IACnB+sB,GAAM/sB,EAAEqtB,YAAc,KAIpB,SAAUrtB,GAAKA,EAAEyG,OAASzG,EAAEstB,kBAC9BP,EAAKC,EACLA,EAAK,GAGPC,EA7BiB,GA6BZF,EACLG,EA9BiB,GA8BZF,EAED,WAAYhtB,IACdktB,EAAKltB,EAAEutB,QAEL,WAAYvtB,IACditB,EAAKjtB,EAAEwtB,SAGJP,GAAMC,IAAOltB,EAAEytB,YACE,IAAhBztB,EAAEytB,WACJR,GAxCc,GAyCdC,GAzCc,KA2CdD,GA1Cc,IA2CdC,GA3Cc,MAgDdD,IAAOF,IACTA,EAAME,EAAK,GAAM,EAAI,GAEnBC,IAAOF,IACTA,EAAME,EAAK,GAAM,EAAI,GAGhB,CACLQ,MAAOX,EACPY,MAAOX,EACPY,OAAQX,EACRY,OAAQX,IAGZY,iBAAkB,WACHn0B,KACNo0B,cAAe,GAExBC,iBAAkB,WACHr0B,KACNo0B,cAAe,GAExB3C,OAAQ,SAAgBrqB,GACtB,IAAIf,EAAIe,EACJuM,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAOqmB,WAE3B,IAAK3gB,EAAOygB,eAAiBnmB,EAAOsmB,eAAkB,OAAO,EAEzDluB,EAAEqf,gBAAiBrf,EAAIA,EAAEqf,eAC7B,IAAI8O,EAAQ,EACRC,EAAY9gB,EAAOY,cAAgB,EAAI,EAEvCvP,EAAO6tB,EAAWvU,UAAUjY,GAEhC,GAAI4H,EAAOymB,YACT,GAAI/gB,EAAOI,eAAgB,CACzB,KAAIoC,KAAK8B,IAAIjT,EAAKivB,QAAU9d,KAAK8B,IAAIjT,EAAKkvB,SACnC,OAAO,EADuCM,EAAQxvB,EAAKivB,OAASQ,MAEtE,CAAA,KAAIte,KAAK8B,IAAIjT,EAAKkvB,QAAU/d,KAAK8B,IAAIjT,EAAKivB,SAC1C,OAAO,EAD8CO,EAAQxvB,EAAKkvB,YAGzEM,EAAQre,KAAK8B,IAAIjT,EAAKivB,QAAU9d,KAAK8B,IAAIjT,EAAKkvB,SAAWlvB,EAAKivB,OAASQ,GAAazvB,EAAKkvB,OAG3F,GAAc,IAAVM,EAAe,OAAO,EAI1B,GAFIvmB,EAAO0mB,SAAUH,GAASA,GAEzB7gB,EAAO1F,OAAOoU,SAaZ,CAED1O,EAAO1F,OAAOkN,MAChBxH,EAAOwK,UAET,IAAI+J,EAAWvU,EAAO9G,eAAkB2nB,EAAQvmB,EAAO2mB,YACnD/Z,EAAelH,EAAOgH,YACtBG,EAASnH,EAAOiH,MA2BpB,GAzBIsN,GAAYvU,EAAOyG,iBAAkB8N,EAAWvU,EAAOyG,gBACvD8N,GAAYvU,EAAO+G,iBAAkBwN,EAAWvU,EAAO+G,gBAE3D/G,EAAO6F,cAAc,GACrB7F,EAAO8I,aAAayL,GACpBvU,EAAO6G,iBACP7G,EAAOiI,oBACPjI,EAAOoH,wBAEDF,GAAgBlH,EAAOgH,cAAkBG,GAAUnH,EAAOiH,QAC9DjH,EAAOoH,sBAGLpH,EAAO1F,OAAOiV,iBAChBhhB,aAAayR,EAAO2gB,WAAWO,SAC/BlhB,EAAO2gB,WAAWO,QAAUvoB,GAAMI,SAAS,WACzCiH,EAAOkL,kBACN,MAGLlL,EAAO/B,KAAK,SAAUvL,GAGlBsN,EAAO1F,OAAO6mB,UAAYnhB,EAAO1F,OAAO8mB,8BAAgCphB,EAAOmhB,SAASE,OAExF9M,IAAavU,EAAOyG,gBAAkB8N,IAAavU,EAAO+G,eAAkB,OAAO,MA/C5D,CAC3B,GAAqD,GAAjDpO,GAAMM,MAAQ+G,EAAO2gB,WAAWxB,eAClC,GAAI0B,EAAQ,EACV,GAAM7gB,EAAOiH,QAASjH,EAAO1F,OAAOkN,MAAUxH,EAAOyJ,WAG9C,GAAInP,EAAOsmB,eAAkB,OAAO,OAFzC5gB,EAAOuK,YACPvK,EAAO/B,KAAK,SAAUvL,QAEnB,GAAMsN,EAAOgH,cAAehH,EAAO1F,OAAOkN,MAAUxH,EAAOyJ,WAG3D,GAAInP,EAAOsmB,eAAkB,OAAO,OAFzC5gB,EAAO0K,YACP1K,EAAO/B,KAAK,SAAUvL,GAG1BsN,EAAO2gB,WAAWxB,gBAAiB,IAAKxxB,EAAIS,MAAQkzB,UAwCtD,OAFI5uB,EAAE4gB,eAAkB5gB,EAAE4gB,iBACnB5gB,EAAEosB,aAAc,GAChB,GAETC,OAAQ,WACN,IAAI/e,EAAS3T,KACb,IAAK6yB,EAAWzrB,MAAS,OAAO,EAChC,GAAIuM,EAAO2gB,WAAW3f,QAAW,OAAO,EACxC,IAAIrO,EAASqN,EAAOC,IAQpB,MAP8C,cAA1CD,EAAO1F,OAAOqmB,WAAWY,eAC3B5uB,EAAS/D,EAAEoR,EAAO1F,OAAOqmB,WAAWY,eAEtC5uB,EAAOV,GAAG,aAAc+N,EAAO2gB,WAAWH,kBAC1C7tB,EAAOV,GAAG,aAAc+N,EAAO2gB,WAAWD,kBAC1C/tB,EAAOV,GAAGitB,EAAWzrB,MAAOuM,EAAO2gB,WAAW7C,QAC9C9d,EAAO2gB,WAAW3f,SAAU,GAG9Bge,QAAS,WACP,IAAIhf,EAAS3T,KACb,IAAK6yB,EAAWzrB,MAAS,OAAO,EAChC,IAAKuM,EAAO2gB,WAAW3f,QAAW,OAAO,EACzC,IAAIrO,EAASqN,EAAOC,IAMpB,MAL8C,cAA1CD,EAAO1F,OAAOqmB,WAAWY,eAC3B5uB,EAAS/D,EAAEoR,EAAO1F,OAAOqmB,WAAWY,eAEtC5uB,EAAOgB,IAAIurB,EAAWzrB,MAAOuM,EAAO2gB,WAAW7C,UAC/C9d,EAAO2gB,WAAW3f,SAAU,KA2C5BwgB,EAAa,CACf5hB,OAAQ,WAEN,IAAII,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAO+c,WAE3B,IAAIrX,EAAO1F,OAAOkN,KAAlB,CACA,IAAIwU,EAAMhc,EAAOqX,WACboK,EAAUzF,EAAIyF,QACdC,EAAU1F,EAAI0F,QAEdA,GAA4B,EAAjBA,EAAQ/yB,SACjBqR,EAAOgH,YACT0a,EAAQ1xB,SAASsK,EAAOqnB,eAExBD,EAAQpxB,YAAYgK,EAAOqnB,eAE7BD,EAAQ1hB,EAAO1F,OAAO8K,eAAiBpF,EAAOoM,SAAW,WAAa,eAAe9R,EAAOsnB,YAE1FH,GAA4B,EAAjBA,EAAQ9yB,SACjBqR,EAAOiH,MACTwa,EAAQzxB,SAASsK,EAAOqnB,eAExBF,EAAQnxB,YAAYgK,EAAOqnB,eAE7BF,EAAQzhB,EAAO1F,OAAO8K,eAAiBpF,EAAOoM,SAAW,WAAa,eAAe9R,EAAOsnB,cAGhGC,YAAa,SAAqBnvB,GAEhCA,EAAE4gB,iBADWjnB,KAEF2a,cAFE3a,KAEqBiO,OAAOkN,MAF5Bnb,KAGNqe,aAEToX,YAAa,SAAqBpvB,GAEhCA,EAAE4gB,iBADWjnB,KAEF4a,QAFE5a,KAEeiO,OAAOkN,MAFtBnb,KAGNke,aAETuE,KAAM,WACJ,IAII2S,EACAC,EALA1hB,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAO+c,YACrB/c,EAAOynB,QAAUznB,EAAO0nB,UAI1B1nB,EAAOynB,SACTN,EAAU7yB,EAAE0L,EAAOynB,QAEjB/hB,EAAO1F,OAAOiW,mBACc,iBAAlBjW,EAAOynB,QACG,EAAjBN,EAAQ9yB,QACkC,IAA1CqR,EAAOC,IAAIjI,KAAKsC,EAAOynB,QAAQpzB,SAElC8yB,EAAUzhB,EAAOC,IAAIjI,KAAKsC,EAAOynB,UAGjCznB,EAAO0nB,SACTN,EAAU9yB,EAAE0L,EAAO0nB,QAEjBhiB,EAAO1F,OAAOiW,mBACc,iBAAlBjW,EAAO0nB,QACG,EAAjBN,EAAQ/yB,QACkC,IAA1CqR,EAAOC,IAAIjI,KAAKsC,EAAO0nB,QAAQrzB,SAElC+yB,EAAU1hB,EAAOC,IAAIjI,KAAKsC,EAAO0nB,UAIjCP,GAA4B,EAAjBA,EAAQ9yB,QACrB8yB,EAAQxvB,GAAG,QAAS+N,EAAOqX,WAAWyK,aAEpCJ,GAA4B,EAAjBA,EAAQ/yB,QACrB+yB,EAAQzvB,GAAG,QAAS+N,EAAOqX,WAAWwK,aAGxClpB,GAAMqC,OAAOgF,EAAOqX,WAAY,CAC9BoK,QAASA,EACTM,OAAQN,GAAWA,EAAQ,GAC3BC,QAASA,EACTM,OAAQN,GAAWA,EAAQ,OAG/B7H,QAAS,WACP,IAAI7Z,EAAS3T,KACT2vB,EAAMhc,EAAOqX,WACboK,EAAUzF,EAAIyF,QACdC,EAAU1F,EAAI0F,QACdD,GAAWA,EAAQ9yB,SACrB8yB,EAAQ9tB,IAAI,QAASqM,EAAOqX,WAAWyK,aACvCL,EAAQnxB,YAAY0P,EAAO1F,OAAO+c,WAAWsK,gBAE3CD,GAAWA,EAAQ/yB,SACrB+yB,EAAQ/tB,IAAI,QAASqM,EAAOqX,WAAWwK,aACvCH,EAAQpxB,YAAY0P,EAAO1F,OAAO+c,WAAWsK,kBAgF/CM,EAAa,CACfriB,OAAQ,WAEN,IAAII,EAAS3T,KACTsU,EAAMX,EAAOW,IACbrG,EAAS0F,EAAO1F,OAAO4nB,WAC3B,GAAK5nB,EAAO/I,IAAOyO,EAAOkiB,WAAW3wB,IAAOyO,EAAOkiB,WAAWjiB,KAAwC,IAAjCD,EAAOkiB,WAAWjiB,IAAItR,OAA3F,CACA,IAGIwzB,EAHAhhB,EAAenB,EAAOe,SAAWf,EAAO1F,OAAOyG,QAAQC,QAAUhB,EAAOe,QAAQG,OAAOvS,OAASqR,EAAOkB,OAAOvS,OAC9GsR,EAAMD,EAAOkiB,WAAWjiB,IAGxBmiB,EAAQpiB,EAAO1F,OAAOkN,KAAOhF,KAAKE,MAAMvB,EAAsC,EAAtBnB,EAAOsK,cAAqBtK,EAAO1F,OAAOiK,gBAAkBvE,EAAOoB,SAASzS,OAcxI,GAbIqR,EAAO1F,OAAOkN,OAChB2a,EAAU3f,KAAKE,MAAM1C,EAAO8F,YAAc9F,EAAOsK,cAAgBtK,EAAO1F,OAAOiK,iBACjEpD,EAAe,EAA2B,EAAtBnB,EAAOsK,eACvC6X,GAAYhhB,EAAsC,EAAtBnB,EAAOsK,cAEvB8X,EAAQ,EAAlBD,IAAuBA,GAAWC,GAClCD,EAAU,GAAsC,YAAjCniB,EAAO1F,OAAO+nB,iBAAgCF,EAAUC,EAAQD,IAEnFA,OADqC,IAArBniB,EAAOmF,UACbnF,EAAOmF,UAEPnF,EAAO8F,aAAe,EAGd,YAAhBxL,EAAO2X,MAAsBjS,EAAOkiB,WAAWI,SAA8C,EAAnCtiB,EAAOkiB,WAAWI,QAAQ3zB,OAAY,CAClG,IACI4zB,EACAC,EACAC,EAHAH,EAAUtiB,EAAOkiB,WAAWI,QAoBhC,GAhBIhoB,EAAOooB,iBACT1iB,EAAOkiB,WAAWS,WAAaL,EAAQ1rB,GAAG,GAAGoJ,EAAOI,eAAiB,aAAe,gBAAe,GACnGH,EAAIlK,IAAIiK,EAAOI,eAAiB,QAAU,SAAYJ,EAAOkiB,WAAWS,YAAcroB,EAAOsoB,mBAAqB,GAAM,MACxF,EAA5BtoB,EAAOsoB,yBAAmDxvB,IAAzB4M,EAAOmI,gBAC1CnI,EAAOkiB,WAAWW,oBAAuBV,EAAUniB,EAAOmI,cACtDnI,EAAOkiB,WAAWW,mBAAsBvoB,EAAOsoB,mBAAqB,EACtE5iB,EAAOkiB,WAAWW,mBAAqBvoB,EAAOsoB,mBAAqB,EAC1D5iB,EAAOkiB,WAAWW,mBAAqB,IAChD7iB,EAAOkiB,WAAWW,mBAAqB,IAG3CN,EAAaJ,EAAUniB,EAAOkiB,WAAWW,mBAEzCJ,IADAD,EAAYD,GAAc/f,KAAKoM,IAAI0T,EAAQ3zB,OAAQ2L,EAAOsoB,oBAAsB,IACxDL,GAAc,GAExCD,EAAQhyB,YAAcgK,EAAwB,kBAAI,IAAOA,EAAwB,kBAAI,SAAYA,EAAwB,kBAAI,cAAiBA,EAAwB,kBAAI,SAAYA,EAAwB,kBAAI,cAAiBA,EAAwB,kBAAI,SAC9O,EAAb2F,EAAItR,OACN2zB,EAAQpsB,KAAK,SAAUO,EAAOqsB,GAC5B,IAAIC,EAAUn0B,EAAEk0B,GACZE,EAAcD,EAAQtsB,QACtBusB,IAAgBb,GAClBY,EAAQ/yB,SAASsK,EAAO2oB,mBAEtB3oB,EAAOooB,iBACUH,GAAfS,GAA6BA,GAAeR,GAC9CO,EAAQ/yB,SAAWsK,EAAwB,kBAAI,SAE7C0oB,IAAgBT,GAClBQ,EACGtrB,OACAzH,SAAWsK,EAAwB,kBAAI,SACvC7C,OACAzH,SAAWsK,EAAwB,kBAAI,cAExC0oB,IAAgBR,GAClBO,EACG1rB,OACArH,SAAWsK,EAAwB,kBAAI,SACvCjD,OACArH,SAAWsK,EAAwB,kBAAI,sBAOhD,GAFcgoB,EAAQ1rB,GAAGurB,GACjBnyB,SAASsK,EAAO2oB,mBACpB3oB,EAAOooB,eAAgB,CAGzB,IAFA,IAAIQ,EAAwBZ,EAAQ1rB,GAAG2rB,GACnCY,EAAuBb,EAAQ1rB,GAAG4rB,GAC7B9zB,EAAI6zB,EAAY7zB,GAAK8zB,EAAW9zB,GAAK,EAC5C4zB,EAAQ1rB,GAAGlI,GAAGsB,SAAWsK,EAAwB,kBAAI,SAEvD4oB,EACGzrB,OACAzH,SAAWsK,EAAwB,kBAAI,SACvC7C,OACAzH,SAAWsK,EAAwB,kBAAI,cAC1C6oB,EACG9rB,OACArH,SAAWsK,EAAwB,kBAAI,SACvCjD,OACArH,SAAWsK,EAAwB,kBAAI,cAG9C,GAAIA,EAAOooB,eAAgB,CACzB,IAAIU,EAAuB5gB,KAAKoM,IAAI0T,EAAQ3zB,OAAQ2L,EAAOsoB,mBAAqB,GAC5ES,GAAmBrjB,EAAOkiB,WAAWS,WAAaS,EAAyBpjB,EAAOkiB,WAAqB,YAAK,EAAMO,EAAWziB,EAAOkiB,WAAWS,WAC/IhG,EAAahc,EAAM,QAAU,OACjC2hB,EAAQvsB,IAAIiK,EAAOI,eAAiBuc,EAAa,MAAQ0G,EAAgB,OAO7E,GAJoB,aAAhB/oB,EAAO2X,OACThS,EAAIjI,KAAM,IAAOsC,EAAmB,cAAInE,KAAKmE,EAAOgpB,sBAAsBnB,EAAU,IACpFliB,EAAIjI,KAAM,IAAOsC,EAAiB,YAAInE,KAAKmE,EAAOipB,oBAAoBnB,KAEpD,gBAAhB9nB,EAAO2X,KAAwB,CACjC,IAAIuR,EAEFA,EADElpB,EAAOmpB,oBACczjB,EAAOI,eAAiB,WAAa,aAErCJ,EAAOI,eAAiB,aAAe,WAEhE,IAAIsjB,GAASvB,EAAU,GAAKC,EACxBuB,EAAS,EACTC,EAAS,EACgB,eAAzBJ,EACFG,EAASD,EAETE,EAASF,EAEXzjB,EAAIjI,KAAM,IAAOsC,EAA2B,sBAAI5I,UAAW,6BAA+BiyB,EAAS,YAAcC,EAAS,KAAM/xB,WAAWmO,EAAO1F,OAAOoL,OAEvI,WAAhBpL,EAAO2X,MAAqB3X,EAAOupB,cACrC5jB,EAAIhR,KAAKqL,EAAOupB,aAAa7jB,EAAQmiB,EAAU,EAAGC,IAClDpiB,EAAO/B,KAAK,mBAAoB+B,EAAQC,EAAI,KAE5CD,EAAO/B,KAAK,mBAAoB+B,EAAQC,EAAI,IAE9CA,EAAID,EAAO1F,OAAO8K,eAAiBpF,EAAOoM,SAAW,WAAa,eAAe9R,EAAOsnB,aAE1FkC,OAAQ,WAEN,IAAI9jB,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAO4nB,WAC3B,GAAK5nB,EAAO/I,IAAOyO,EAAOkiB,WAAW3wB,IAAOyO,EAAOkiB,WAAWjiB,KAAwC,IAAjCD,EAAOkiB,WAAWjiB,IAAItR,OAA3F,CACA,IAAIwS,EAAenB,EAAOe,SAAWf,EAAO1F,OAAOyG,QAAQC,QAAUhB,EAAOe,QAAQG,OAAOvS,OAASqR,EAAOkB,OAAOvS,OAE9GsR,EAAMD,EAAOkiB,WAAWjiB,IACxB8jB,EAAiB,GACrB,GAAoB,YAAhBzpB,EAAO2X,KAAoB,CAE7B,IADA,IAAI+R,EAAkBhkB,EAAO1F,OAAOkN,KAAOhF,KAAKE,MAAMvB,EAAsC,EAAtBnB,EAAOsK,cAAqBtK,EAAO1F,OAAOiK,gBAAkBvE,EAAOoB,SAASzS,OACzID,EAAI,EAAGA,EAAIs1B,EAAiBt1B,GAAK,EACpC4L,EAAO2pB,aACTF,GAAkBzpB,EAAO2pB,aAAarvB,KAAKoL,EAAQtR,EAAG4L,EAAO4pB,aAE7DH,GAAkB,IAAOzpB,EAAoB,cAAI,WAAeA,EAAkB,YAAI,OAAWA,EAAoB,cAAI,IAG7H2F,EAAIhR,KAAK80B,GACT/jB,EAAOkiB,WAAWI,QAAUriB,EAAIjI,KAAM,IAAOsC,EAAkB,aAE7C,aAAhBA,EAAO2X,OAEP8R,EADEzpB,EAAO6pB,eACQ7pB,EAAO6pB,eAAevvB,KAAKoL,EAAQ1F,EAAO8pB,aAAc9pB,EAAO+pB,YAE/D,gBAAoB/pB,EAAmB,aAAI,4BAEtCA,EAAiB,WAAI,YAE7C2F,EAAIhR,KAAK80B,IAES,gBAAhBzpB,EAAO2X,OAEP8R,EADEzpB,EAAOgqB,kBACQhqB,EAAOgqB,kBAAkB1vB,KAAKoL,EAAQ1F,EAAOiqB,sBAE7C,gBAAoBjqB,EAA2B,qBAAI,YAEtE2F,EAAIhR,KAAK80B,IAES,WAAhBzpB,EAAO2X,MACTjS,EAAO/B,KAAK,mBAAoB+B,EAAOkiB,WAAWjiB,IAAI,MAG1D6O,KAAM,WACJ,IAAI9O,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAO4nB,WAC3B,GAAK5nB,EAAO/I,GAAZ,CAEA,IAAI0O,EAAMrR,EAAE0L,EAAO/I,IACA,IAAf0O,EAAItR,SAGNqR,EAAO1F,OAAOiW,mBACU,iBAAdjW,EAAO/I,IACD,EAAb0O,EAAItR,QACkC,IAAtCqR,EAAOC,IAAIjI,KAAKsC,EAAO/I,IAAI5C,SAE9BsR,EAAMD,EAAOC,IAAIjI,KAAKsC,EAAO/I,KAGX,YAAhB+I,EAAO2X,MAAsB3X,EAAOkqB,WACtCvkB,EAAIjQ,SAASsK,EAAOmqB,gBAGtBxkB,EAAIjQ,SAASsK,EAAOoqB,cAAgBpqB,EAAO2X,MAEvB,YAAhB3X,EAAO2X,MAAsB3X,EAAOooB,iBACtCziB,EAAIjQ,SAAU,GAAMsK,EAAoB,cAAKA,EAAW,KAAI,YAC5D0F,EAAOkiB,WAAWW,mBAAqB,EACnCvoB,EAAOsoB,mBAAqB,IAC9BtoB,EAAOsoB,mBAAqB,IAGZ,gBAAhBtoB,EAAO2X,MAA0B3X,EAAOmpB,qBAC1CxjB,EAAIjQ,SAASsK,EAAOqqB,0BAGlBrqB,EAAOkqB,WACTvkB,EAAIhO,GAAG,QAAU,IAAOqI,EAAkB,YAAI,SAAiB5H,GAC7DA,EAAE4gB,iBACF,IAAI7c,EAAQ7H,EAAEvC,MAAMoK,QAAUuJ,EAAO1F,OAAOiK,eACxCvE,EAAO1F,OAAOkN,OAAQ/Q,GAASuJ,EAAOsK,cAC1CtK,EAAO0J,QAAQjT,KAInBkC,GAAMqC,OAAOgF,EAAOkiB,WAAY,CAC9BjiB,IAAKA,EACL1O,GAAI0O,EAAI,QAGZ4Z,QAAS,WACP,IAAI7Z,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAO4nB,WAC3B,GAAK5nB,EAAO/I,IAAOyO,EAAOkiB,WAAW3wB,IAAOyO,EAAOkiB,WAAWjiB,KAAwC,IAAjCD,EAAOkiB,WAAWjiB,IAAItR,OAA3F,CACA,IAAIsR,EAAMD,EAAOkiB,WAAWjiB,IAE5BA,EAAI3P,YAAYgK,EAAOsqB,aACvB3kB,EAAI3P,YAAYgK,EAAOoqB,cAAgBpqB,EAAO2X,MAC1CjS,EAAOkiB,WAAWI,SAAWtiB,EAAOkiB,WAAWI,QAAQhyB,YAAYgK,EAAO2oB,mBAC1E3oB,EAAOkqB,WACTvkB,EAAItM,IAAI,QAAU,IAAO2G,EAAkB,gBA0G7CuqB,EAAY,CACd/b,aAAc,WACZ,IAAI9I,EAAS3T,KACb,GAAK2T,EAAO1F,OAAOwqB,UAAUvzB,IAAOyO,EAAO8kB,UAAUvzB,GAArD,CACA,IAAIuzB,EAAY9kB,EAAO8kB,UACnBnkB,EAAMX,EAAOY,aACbgG,EAAW5G,EAAO4G,SAClBme,EAAWD,EAAUC,SACrBC,EAAYF,EAAUE,UACtBC,EAAUH,EAAUG,QACpBhlB,EAAM6kB,EAAU7kB,IAChB3F,EAAS0F,EAAO1F,OAAOwqB,UAEvBI,EAAUH,EACVI,GAAUH,EAAYD,GAAYne,EAClCjG,EAEW,GADbwkB,GAAUA,IAERD,EAAUH,EAAWI,EACrBA,EAAS,GACqBH,GAApBG,EAASJ,IACnBG,EAAUF,EAAYG,GAEfA,EAAS,GAClBD,EAAUH,EAAWI,EACrBA,EAAS,GACoBH,EAApBG,EAASJ,IAClBG,EAAUF,EAAYG,GAEpBnlB,EAAOI,gBACL1E,GAAQU,aACV6oB,EAAQvzB,UAAW,eAAiByzB,EAAS,aAE7CF,EAAQvzB,UAAW,cAAgByzB,EAAS,OAE9CF,EAAQ,GAAG33B,MAAMwS,MAAQolB,EAAU,OAE/BxpB,GAAQU,aACV6oB,EAAQvzB,UAAW,oBAAsByzB,EAAS,UAElDF,EAAQvzB,UAAW,cAAgByzB,EAAS,OAE9CF,EAAQ,GAAG33B,MAAMyS,OAASmlB,EAAU,MAElC5qB,EAAO8qB,OACT72B,aAAayR,EAAO8kB,UAAU5D,SAC9BjhB,EAAI,GAAG3S,MAAM+3B,QAAU,EACvBrlB,EAAO8kB,UAAU5D,QAAU5yB,WAAW,WACpC2R,EAAI,GAAG3S,MAAM+3B,QAAU,EACvBplB,EAAIpO,WAAW,MACd,QAGPgU,cAAe,SAAuB/T,GACvBzF,KACDiO,OAAOwqB,UAAUvzB,IADhBlF,KAC8By4B,UAAUvzB,IADxClF,KAENy4B,UAAUG,QAAQpzB,WAAWC,IAEtC+N,WAAY,WACV,IAAIG,EAAS3T,KACb,GAAK2T,EAAO1F,OAAOwqB,UAAUvzB,IAAOyO,EAAO8kB,UAAUvzB,GAArD,CAEA,IAAIuzB,EAAY9kB,EAAO8kB,UACnBG,EAAUH,EAAUG,QACpBhlB,EAAM6kB,EAAU7kB,IAEpBglB,EAAQ,GAAG33B,MAAMwS,MAAQ,GACzBmlB,EAAQ,GAAG33B,MAAMyS,OAAS,GAC1B,IAIIglB,EAJAC,EAAYhlB,EAAOI,eAAiBH,EAAI,GAAGjL,YAAciL,EAAI,GAAG9K,aAEhEmwB,EAAUtlB,EAAOO,KAAOP,EAAOkC,YAC/BqjB,EAAcD,GAAWN,EAAYhlB,EAAOO,MAG9CwkB,EADuC,SAArC/kB,EAAO1F,OAAOwqB,UAAUC,SACfC,EAAYM,EAEZhlB,SAASN,EAAO1F,OAAOwqB,UAAUC,SAAU,IAGpD/kB,EAAOI,eACT6kB,EAAQ,GAAG33B,MAAMwS,MAAQilB,EAAW,KAEpCE,EAAQ,GAAG33B,MAAMyS,OAASglB,EAAW,KAIrC9kB,EAAI,GAAG3S,MAAMk4B,QADA,GAAXF,EACqB,OAEA,GAErBtlB,EAAO1F,OAAOwqB,UAAUM,OAC1BnlB,EAAI,GAAG3S,MAAM+3B,QAAU,GAEzB1sB,GAAMqC,OAAO8pB,EAAW,CACtBE,UAAWA,EACXM,QAASA,EACTC,YAAaA,EACbR,SAAUA,IAEZD,EAAU7kB,IAAID,EAAO1F,OAAO8K,eAAiBpF,EAAOoM,SAAW,WAAa,eAAepM,EAAO1F,OAAOwqB,UAAUlD,aAErH6D,gBAAiB,SAAyB/yB,GACxC,IAaIgzB,EAbA1lB,EAAS3T,KACTy4B,EAAY9kB,EAAO8kB,UACnBnkB,EAAMX,EAAOY,aACbX,EAAM6kB,EAAU7kB,IAChB8kB,EAAWD,EAAUC,SACrBC,EAAYF,EAAUE,UAS1BU,IANI1lB,EAAOI,eACsB,eAAX1N,EAAEuf,MAAoC,cAAXvf,EAAEuf,KAAwBvf,EAAE8f,cAAc,GAAGC,MAAQ/f,EAAE+f,OAAS/f,EAAEizB,QAElF,eAAXjzB,EAAEuf,MAAoC,cAAXvf,EAAEuf,KAAwBvf,EAAE8f,cAAc,GAAGG,MAAQjgB,EAAEigB,OAASjgB,EAAEkzB,SAG9E3lB,EAAI7K,SAAS4K,EAAOI,eAAiB,OAAS,OAAU2kB,EAAW,IAAOC,EAAYD,GAC3HW,EAAgBljB,KAAKK,IAAIL,KAAKoM,IAAI8W,EAAe,GAAI,GACjD/kB,IACF+kB,EAAgB,EAAIA,GAGtB,IAAInR,EAAWvU,EAAOyG,gBAAmBzG,EAAO+G,eAAiB/G,EAAOyG,gBAAkBif,EAE1F1lB,EAAO6G,eAAe0N,GACtBvU,EAAO8I,aAAayL,GACpBvU,EAAOiI,oBACPjI,EAAOoH,uBAETye,YAAa,SAAqBnzB,GAChC,IAAIsN,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAOwqB,UACvBA,EAAY9kB,EAAO8kB,UACnBrkB,EAAaT,EAAOS,WACpBR,EAAM6kB,EAAU7kB,IAChBglB,EAAUH,EAAUG,QACxBjlB,EAAO8kB,UAAU1S,WAAY,EAC7B1f,EAAE4gB,iBACF5gB,EAAEwhB,kBAEFzT,EAAW5O,WAAW,KACtBozB,EAAQpzB,WAAW,KACnBizB,EAAUW,gBAAgB/yB,GAE1BnE,aAAayR,EAAO8kB,UAAUgB,aAE9B7lB,EAAIpO,WAAW,GACXyI,EAAO8qB,MACTnlB,EAAIlK,IAAI,UAAW,GAErBiK,EAAO/B,KAAK,qBAAsBvL,IAEpCqzB,WAAY,SAAoBrzB,GAC9B,IACIoyB,EADSz4B,KACUy4B,UACnBrkB,EAFSpU,KAEWoU,WACpBR,EAAM6kB,EAAU7kB,IAChBglB,EAAUH,EAAUG,QAJX54B,KAMDy4B,UAAU1S,YAClB1f,EAAE4gB,eAAkB5gB,EAAE4gB,iBACnB5gB,EAAEosB,aAAc,EACvBgG,EAAUW,gBAAgB/yB,GAC1B+N,EAAW5O,WAAW,GACtBoO,EAAIpO,WAAW,GACfozB,EAAQpzB,WAAW,GAZNxF,KAaN4R,KAAK,oBAAqBvL,KAEnCszB,UAAW,SAAmBtzB,GAC5B,IAAIsN,EAAS3T,KAETiO,EAAS0F,EAAO1F,OAAOwqB,UAEvB7kB,EADYD,EAAO8kB,UACH7kB,IAEfD,EAAO8kB,UAAU1S,YACtBpS,EAAO8kB,UAAU1S,WAAY,EACzB9X,EAAO8qB,OACT72B,aAAayR,EAAO8kB,UAAUgB,aAC9B9lB,EAAO8kB,UAAUgB,YAAcntB,GAAMI,SAAS,WAC5CkH,EAAIlK,IAAI,UAAW,GACnBkK,EAAIpO,WAAW,MACd,MAELmO,EAAO/B,KAAK,mBAAoBvL,GAC5B4H,EAAO2rB,eACTjmB,EAAOkL,mBAGXgb,gBAAiB,WACf,IAAIlmB,EAAS3T,KACb,GAAK2T,EAAO1F,OAAOwqB,UAAUvzB,GAA7B,CACA,IAAIuzB,EAAY9kB,EAAO8kB,UACnB3L,EAAmBnZ,EAAOmZ,iBAC1BC,EAAqBpZ,EAAOoZ,mBAC5B9e,EAAS0F,EAAO1F,OAEhB3H,EADMmyB,EAAU7kB,IACH,GACbkmB,KAAiBzqB,GAAQc,kBAAmBlC,EAAO4W,mBAAmB,CAAE+E,SAAS,EAAOzjB,SAAS,GACjGgK,KAAkBd,GAAQc,kBAAmBlC,EAAO4W,mBAAmB,CAAE+E,SAAS,EAAMzjB,SAAS,GAChGkJ,GAAQC,OAKXhJ,EAAOlG,iBAAiB0sB,EAAiBnD,MAAOhW,EAAO8kB,UAAUe,YAAaM,GAC9ExzB,EAAOlG,iBAAiB0sB,EAAiBjD,KAAMlW,EAAO8kB,UAAUiB,WAAYI,GAC5ExzB,EAAOlG,iBAAiB0sB,EAAiBhD,IAAKnW,EAAO8kB,UAAUkB,UAAWxpB,KAN1E7J,EAAOlG,iBAAiB2sB,EAAmBpD,MAAOhW,EAAO8kB,UAAUe,YAAaM,GAChF75B,EAAIG,iBAAiB2sB,EAAmBlD,KAAMlW,EAAO8kB,UAAUiB,WAAYI,GAC3E75B,EAAIG,iBAAiB2sB,EAAmBjD,IAAKnW,EAAO8kB,UAAUkB,UAAWxpB,MAO7E4pB,iBAAkB,WAChB,IAAIpmB,EAAS3T,KACb,GAAK2T,EAAO1F,OAAOwqB,UAAUvzB,GAA7B,CACA,IAAIuzB,EAAY9kB,EAAO8kB,UACnB3L,EAAmBnZ,EAAOmZ,iBAC1BC,EAAqBpZ,EAAOoZ,mBAC5B9e,EAAS0F,EAAO1F,OAEhB3H,EADMmyB,EAAU7kB,IACH,GACbkmB,KAAiBzqB,GAAQc,kBAAmBlC,EAAO4W,mBAAmB,CAAE+E,SAAS,EAAOzjB,SAAS,GACjGgK,KAAkBd,GAAQc,kBAAmBlC,EAAO4W,mBAAmB,CAAE+E,SAAS,EAAMzjB,SAAS,GAChGkJ,GAAQC,OAKXhJ,EAAOjG,oBAAoBysB,EAAiBnD,MAAOhW,EAAO8kB,UAAUe,YAAaM,GACjFxzB,EAAOjG,oBAAoBysB,EAAiBjD,KAAMlW,EAAO8kB,UAAUiB,WAAYI,GAC/ExzB,EAAOjG,oBAAoBysB,EAAiBhD,IAAKnW,EAAO8kB,UAAUkB,UAAWxpB,KAN7E7J,EAAOjG,oBAAoB0sB,EAAmBpD,MAAOhW,EAAO8kB,UAAUe,YAAaM,GACnF75B,EAAII,oBAAoB0sB,EAAmBlD,KAAMlW,EAAO8kB,UAAUiB,WAAYI,GAC9E75B,EAAII,oBAAoB0sB,EAAmBjD,IAAKnW,EAAO8kB,UAAUkB,UAAWxpB,MAOhFsS,KAAM,WACJ,IAAI9O,EAAS3T,KACb,GAAK2T,EAAO1F,OAAOwqB,UAAUvzB,GAA7B,CACA,IAAIuzB,EAAY9kB,EAAO8kB,UACnBuB,EAAYrmB,EAAOC,IACnB3F,EAAS0F,EAAO1F,OAAOwqB,UAEvB7kB,EAAMrR,EAAE0L,EAAO/I,IACfyO,EAAO1F,OAAOiW,mBAA0C,iBAAdjW,EAAO/I,IAAgC,EAAb0O,EAAItR,QAAmD,IAArC03B,EAAUruB,KAAKsC,EAAO/I,IAAI5C,SAClHsR,EAAMomB,EAAUruB,KAAKsC,EAAO/I,KAG9B,IAAI0zB,EAAUhlB,EAAIjI,KAAM,IAAOgI,EAAO1F,OAAOwqB,UAAmB,WACzC,IAAnBG,EAAQt2B,SACVs2B,EAAUr2B,EAAG,eAAmBoR,EAAO1F,OAAOwqB,UAAmB,UAAI,YACrE7kB,EAAInJ,OAAOmuB,IAGbtsB,GAAMqC,OAAO8pB,EAAW,CACtB7kB,IAAKA,EACL1O,GAAI0O,EAAI,GACRglB,QAASA,EACTqB,OAAQrB,EAAQ,KAGd3qB,EAAOisB,WACTzB,EAAUoB,oBAGdrM,QAAS,WACMxtB,KACNy4B,UAAUsB,qBAwEjBI,EAAW,CACbC,aAAc,SAAsBl1B,EAAIqV,GACtC,IACIjG,EADStU,KACIsU,IAEbV,EAAMrR,EAAE2C,GACRuvB,EAAYngB,GAAO,EAAI,EAEvB+lB,EAAIzmB,EAAIrP,KAAK,yBAA2B,IACxCoY,EAAI/I,EAAIrP,KAAK,0BACbqY,EAAIhJ,EAAIrP,KAAK,0BACb8yB,EAAQzjB,EAAIrP,KAAK,8BACjBy0B,EAAUplB,EAAIrP,KAAK,gCAwBvB,GAtBIoY,GAAKC,GACPD,EAAIA,GAAK,IACTC,EAAIA,GAAK,KAdE5c,KAeK+T,gBAChB4I,EAAI0d,EACJzd,EAAI,MAEJA,EAAIyd,EACJ1d,EAAI,KAIJA,EADsB,GAApB,EAAI7Z,QAAQ,KACTmR,SAAS0I,EAAG,IAAMpC,EAAWka,EAAa,IAE1C9X,EAAIpC,EAAWka,EAAa,KAGjC7X,EADsB,GAApB,EAAI9Z,QAAQ,KACTmR,SAAS2I,EAAG,IAAMrC,EAAY,IAE9BqC,EAAIrC,EAAY,KAGnB,MAAOye,EAA6C,CACtD,IAAIsB,EAAiBtB,GAAYA,EAAU,IAAM,EAAI7iB,KAAK8B,IAAIsC,IAC9D3G,EAAI,GAAG3S,MAAM+3B,QAAUsB,EAEzB,GAAI,MAAOjD,EACTzjB,EAAIvO,UAAW,eAAiBsX,EAAI,KAAOC,EAAI,cAC1C,CACL,IAAI2d,EAAelD,GAAUA,EAAQ,IAAM,EAAIlhB,KAAK8B,IAAIsC,IACxD3G,EAAIvO,UAAW,eAAiBsX,EAAI,KAAOC,EAAI,gBAAkB2d,EAAe,OAGpF9d,aAAc,WACZ,IAAI9I,EAAS3T,KACT4T,EAAMD,EAAOC,IACbiB,EAASlB,EAAOkB,OAChB0F,EAAW5G,EAAO4G,SAClBxF,EAAWpB,EAAOoB,SACtBnB,EAAI7S,SAAS,8EACV8I,KAAK,SAAUO,EAAOlF,GACrByO,EAAO6mB,SAASJ,aAAal1B,EAAIqV,KAErC1F,EAAOhL,KAAK,SAAU0T,EAAYgQ,GAChC,IAAIpT,EAAgBoT,EAAQhT,SACO,EAA/B5G,EAAO1F,OAAOiK,gBAAsD,SAAhCvE,EAAO1F,OAAOqI,gBACpD6D,GAAiBhE,KAAKE,KAAKkH,EAAa,GAAMhD,GAAYxF,EAASzS,OAAS,IAE9E6X,EAAgBhE,KAAKoM,IAAIpM,KAAKK,IAAI2D,GAAgB,GAAI,GACtD5X,EAAEgrB,GAAS5hB,KAAK,8EACb9B,KAAK,SAAUO,EAAOlF,GACrByO,EAAO6mB,SAASJ,aAAal1B,EAAIiV,QAIzCX,cAAe,SAAuB/T,QAClB,IAAbA,IAAsBA,EAAWzF,KAAKiO,OAAOoL,OAErCrZ,KACI4T,IACbjI,KAAK,8EACN9B,KAAK,SAAUO,EAAOqwB,GACrB,IAAIC,EAAcn4B,EAAEk4B,GAChBE,EAAmB1mB,SAASymB,EAAYn2B,KAAK,iCAAkC,KAAOkB,EACzE,IAAbA,IAAkBk1B,EAAmB,GACzCD,EAAYl1B,WAAWm1B,OA+C3BC,EAAO,CAETC,0BAA2B,SAAmCx0B,GAC5D,GAAIA,EAAE8f,cAAc7jB,OAAS,EAAK,OAAO,EACzC,IAAIw4B,EAAKz0B,EAAE8f,cAAc,GAAGC,MACxB2U,EAAK10B,EAAE8f,cAAc,GAAGG,MACxB0U,EAAK30B,EAAE8f,cAAc,GAAGC,MACxB6U,EAAK50B,EAAE8f,cAAc,GAAGG,MAE5B,OADenQ,KAAKqR,KAAMrR,KAAKsR,IAAMuT,EAAKF,EAAK,GAAQ3kB,KAAKsR,IAAMwT,EAAKF,EAAK,KAI9EG,eAAgB,SAAwB70B,GACtC,IAAIsN,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAOktB,KACvBA,EAAOxnB,EAAOwnB,KACdC,EAAUD,EAAKC,QAGnB,GAFAD,EAAKE,oBAAqB,EAC1BF,EAAKG,kBAAmB,GACnBjsB,GAAQmB,SAAU,CACrB,GAAe,eAAXnK,EAAEuf,MAAqC,eAAXvf,EAAEuf,MAAyBvf,EAAE8f,cAAc7jB,OAAS,EAClF,OAEF64B,EAAKE,oBAAqB,EAC1BD,EAAQG,WAAaX,EAAKC,0BAA0Bx0B,GAEjD+0B,EAAQnK,UAAamK,EAAQnK,SAAS3uB,SACzC84B,EAAQnK,SAAW1uB,EAAE8D,EAAEC,QAAQoF,QAAQ,iBACP,IAA5B0vB,EAAQnK,SAAS3uB,SAAgB84B,EAAQnK,SAAWtd,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,cAChF2hB,EAAQI,SAAWJ,EAAQnK,SAAStlB,KAAK,oBACzCyvB,EAAQK,aAAeL,EAAQI,SAAShwB,OAAQ,IAAOyC,EAAqB,gBAC5EmtB,EAAQM,SAAWN,EAAQK,aAAal3B,KAAK,qBAAuB0J,EAAOytB,SACvC,IAAhCN,EAAQK,aAAan5B,SAK3B84B,EAAQI,SAASh2B,WAAW,GAC5BmO,EAAOwnB,KAAKQ,WAAY,GALpBP,EAAQI,cAAWz0B,GAOzB60B,gBAAiB,SAAyBv1B,GACxC,IACI4H,EADSjO,KACOiO,OAAOktB,KACvBA,EAFSn7B,KAEKm7B,KACdC,EAAUD,EAAKC,QACnB,IAAK/rB,GAAQmB,SAAU,CACrB,GAAe,cAAXnK,EAAEuf,MAAoC,cAAXvf,EAAEuf,MAAwBvf,EAAE8f,cAAc7jB,OAAS,EAChF,OAEF64B,EAAKG,kBAAmB,EACxBF,EAAQS,UAAYjB,EAAKC,0BAA0Bx0B,GAEhD+0B,EAAQI,UAAwC,IAA5BJ,EAAQI,SAASl5B,SAExC64B,EAAK9D,MADHhoB,GAAQmB,SACGnK,EAAEgxB,MAAQ8D,EAAKZ,aAEda,EAAQS,UAAYT,EAAQG,WAAcJ,EAAKZ,aAE3DY,EAAK9D,MAAQ+D,EAAQM,WACvBP,EAAK9D,MAAS+D,EAAQM,SAAW,EAAMvlB,KAAKsR,IAAO0T,EAAK9D,MAAQ+D,EAAQM,SAAY,EAAI,KAEtFP,EAAK9D,MAAQppB,EAAO6tB,WACtBX,EAAK9D,MAASppB,EAAO6tB,SAAW,EAAM3lB,KAAKsR,IAAOxZ,EAAO6tB,SAAWX,EAAK9D,MAAS,EAAI,KAExF+D,EAAQI,SAASn2B,UAAW,4BAA+B81B,EAAU,MAAI,OAE3EY,aAAc,SAAsB11B,GAClC,IACI4H,EADSjO,KACOiO,OAAOktB,KACvBA,EAFSn7B,KAEKm7B,KACdC,EAAUD,EAAKC,QACnB,IAAK/rB,GAAQmB,SAAU,CACrB,IAAK2qB,EAAKE,qBAAuBF,EAAKG,iBACpC,OAEF,GAAe,aAAXj1B,EAAEuf,MAAmC,aAAXvf,EAAEuf,MAAuBvf,EAAE21B,eAAe15B,OAAS,IAAMwe,EAAOG,QAC5F,OAEFka,EAAKE,oBAAqB,EAC1BF,EAAKG,kBAAmB,EAErBF,EAAQI,UAAwC,IAA5BJ,EAAQI,SAASl5B,SAC1C64B,EAAK9D,MAAQlhB,KAAKK,IAAIL,KAAKoM,IAAI4Y,EAAK9D,MAAO+D,EAAQM,UAAWztB,EAAO6tB,UACrEV,EAAQI,SAASh2B,WAhBJxF,KAgBsBiO,OAAOoL,OAAOhU,UAAW,4BAA+B81B,EAAU,MAAI,KACzGA,EAAKZ,aAAeY,EAAK9D,MACzB8D,EAAKQ,WAAY,EACE,IAAfR,EAAK9D,QAAe+D,EAAQnK,cAAWlqB,KAE7Cwe,aAAc,SAAsBlf,GAClC,IACI80B,EADSn7B,KACKm7B,KACdC,EAAUD,EAAKC,QACfvP,EAAQsP,EAAKtP,MACZuP,EAAQI,UAAwC,IAA5BJ,EAAQI,SAASl5B,SACtCupB,EAAM9F,YACNjF,EAAOG,SAAW5a,EAAE4gB,iBACxB4E,EAAM9F,WAAY,EAClB8F,EAAMoQ,aAAatf,EAAe,eAAXtW,EAAEuf,KAAwBvf,EAAE8f,cAAc,GAAGC,MAAQ/f,EAAE+f,MAC9EyF,EAAMoQ,aAAarf,EAAe,eAAXvW,EAAEuf,KAAwBvf,EAAE8f,cAAc,GAAGG,MAAQjgB,EAAEigB,SAEhFc,YAAa,SAAqB/gB,GAChC,IAAIsN,EAAS3T,KACTm7B,EAAOxnB,EAAOwnB,KACdC,EAAUD,EAAKC,QACfvP,EAAQsP,EAAKtP,MACb/C,EAAWqS,EAAKrS,SACpB,GAAKsS,EAAQI,UAAwC,IAA5BJ,EAAQI,SAASl5B,SAC1CqR,EAAOsS,YAAa,EACf4F,EAAM9F,WAAcqV,EAAQnK,UAAjC,CAEKpF,EAAM7F,UACT6F,EAAMpY,MAAQ2nB,EAAQI,SAAS,GAAG7yB,YAClCkjB,EAAMnY,OAAS0nB,EAAQI,SAAS,GAAG1yB,aACnC+iB,EAAMtF,OAASja,GAAMO,aAAauuB,EAAQK,aAAa,GAAI,MAAQ,EACnE5P,EAAMrF,OAASla,GAAMO,aAAauuB,EAAQK,aAAa,GAAI,MAAQ,EACnEL,EAAQc,WAAad,EAAQnK,SAAS,GAAGtoB,YACzCyyB,EAAQe,YAAcf,EAAQnK,SAAS,GAAGnoB,aAC1CsyB,EAAQK,aAAaj2B,WAAW,GAC5BmO,EAAOW,MACTuX,EAAMtF,QAAUsF,EAAMtF,OACtBsF,EAAMrF,QAAUqF,EAAMrF,SAI1B,IAAI4V,EAAcvQ,EAAMpY,MAAQ0nB,EAAK9D,MACjCgF,EAAexQ,EAAMnY,OAASynB,EAAK9D,MAEvC,KAAI+E,EAAchB,EAAQc,YAAcG,EAAejB,EAAQe,aAA/D,CAUA,GARAtQ,EAAMyQ,KAAOnmB,KAAKoM,IAAM6Y,EAAQc,WAAa,EAAME,EAAc,EAAK,GACtEvQ,EAAM0Q,MAAQ1Q,EAAMyQ,KACpBzQ,EAAM2Q,KAAOrmB,KAAKoM,IAAM6Y,EAAQe,YAAc,EAAME,EAAe,EAAK,GACxExQ,EAAM4Q,MAAQ5Q,EAAM2Q,KAEpB3Q,EAAM6Q,eAAe/f,EAAe,cAAXtW,EAAEuf,KAAuBvf,EAAE8f,cAAc,GAAGC,MAAQ/f,EAAE+f,MAC/EyF,EAAM6Q,eAAe9f,EAAe,cAAXvW,EAAEuf,KAAuBvf,EAAE8f,cAAc,GAAGG,MAAQjgB,EAAEigB,OAE1EuF,EAAM7F,UAAYmV,EAAKQ,UAAW,CACrC,GACEhoB,EAAOI,iBAEJoC,KAAKC,MAAMyV,EAAMyQ,QAAUnmB,KAAKC,MAAMyV,EAAMtF,SAAWsF,EAAM6Q,eAAe/f,EAAIkP,EAAMoQ,aAAatf,GAChGxG,KAAKC,MAAMyV,EAAM0Q,QAAUpmB,KAAKC,MAAMyV,EAAMtF,SAAWsF,EAAM6Q,eAAe/f,EAAIkP,EAAMoQ,aAAatf,GAIzG,YADAkP,EAAM9F,WAAY,GAElB,IACCpS,EAAOI,iBAELoC,KAAKC,MAAMyV,EAAM2Q,QAAUrmB,KAAKC,MAAMyV,EAAMrF,SAAWqF,EAAM6Q,eAAe9f,EAAIiP,EAAMoQ,aAAarf,GAChGzG,KAAKC,MAAMyV,EAAM4Q,QAAUtmB,KAAKC,MAAMyV,EAAMrF,SAAWqF,EAAM6Q,eAAe9f,EAAIiP,EAAMoQ,aAAarf,GAIzG,YADAiP,EAAM9F,WAAY,GAItB1f,EAAE4gB,iBACF5gB,EAAEwhB,kBAEFgE,EAAM7F,SAAU,EAChB6F,EAAM3F,SAAY2F,EAAM6Q,eAAe/f,EAAIkP,EAAMoQ,aAAatf,EAAKkP,EAAMtF,OACzEsF,EAAMxF,SAAYwF,EAAM6Q,eAAe9f,EAAIiP,EAAMoQ,aAAarf,EAAKiP,EAAMrF,OAErEqF,EAAM3F,SAAW2F,EAAMyQ,OACzBzQ,EAAM3F,SAAY2F,EAAMyQ,KAAO,EAAMnmB,KAAKsR,IAAOoE,EAAMyQ,KAAOzQ,EAAM3F,SAAY,EAAI,KAElF2F,EAAM3F,SAAW2F,EAAM0Q,OACzB1Q,EAAM3F,SAAY2F,EAAM0Q,KAAO,EAAMpmB,KAAKsR,IAAOoE,EAAM3F,SAAW2F,EAAM0Q,KAAQ,EAAI,KAGlF1Q,EAAMxF,SAAWwF,EAAM2Q,OACzB3Q,EAAMxF,SAAYwF,EAAM2Q,KAAO,EAAMrmB,KAAKsR,IAAOoE,EAAM2Q,KAAO3Q,EAAMxF,SAAY,EAAI,KAElFwF,EAAMxF,SAAWwF,EAAM4Q,OACzB5Q,EAAMxF,SAAYwF,EAAM4Q,KAAO,EAAMtmB,KAAKsR,IAAOoE,EAAMxF,SAAWwF,EAAM4Q,KAAQ,EAAI,KAIjF3T,EAAS6T,gBAAiB7T,EAAS6T,cAAgB9Q,EAAM6Q,eAAe/f,GACxEmM,EAAS8T,gBAAiB9T,EAAS8T,cAAgB/Q,EAAM6Q,eAAe9f,GACxEkM,EAAS+T,WAAY/T,EAAS+T,SAAW96B,KAAK6K,OACnDkc,EAASnM,GAAKkP,EAAM6Q,eAAe/f,EAAImM,EAAS6T,gBAAkB56B,KAAK6K,MAAQkc,EAAS+T,UAAY,EACpG/T,EAASlM,GAAKiP,EAAM6Q,eAAe9f,EAAIkM,EAAS8T,gBAAkB76B,KAAK6K,MAAQkc,EAAS+T,UAAY,EAChG1mB,KAAK8B,IAAI4T,EAAM6Q,eAAe/f,EAAImM,EAAS6T,eAAiB,IAAK7T,EAASnM,EAAI,GAC9ExG,KAAK8B,IAAI4T,EAAM6Q,eAAe9f,EAAIkM,EAAS8T,eAAiB,IAAK9T,EAASlM,EAAI,GAClFkM,EAAS6T,cAAgB9Q,EAAM6Q,eAAe/f,EAC9CmM,EAAS8T,cAAgB/Q,EAAM6Q,eAAe9f,EAC9CkM,EAAS+T,SAAW96B,KAAK6K,MAEzBwuB,EAAQK,aAAap2B,UAAW,eAAkBwmB,EAAc,SAAI,OAAUA,EAAc,SAAI,YAElGzD,WAAY,WACV,IACI+S,EADSn7B,KACKm7B,KACdC,EAAUD,EAAKC,QACfvP,EAAQsP,EAAKtP,MACb/C,EAAWqS,EAAKrS,SACpB,GAAKsS,EAAQI,UAAwC,IAA5BJ,EAAQI,SAASl5B,OAA1C,CACA,IAAKupB,EAAM9F,YAAc8F,EAAM7F,QAG7B,OAFA6F,EAAM9F,WAAY,OAClB8F,EAAM7F,SAAU,GAGlB6F,EAAM9F,WAAY,EAClB8F,EAAM7F,SAAU,EAChB,IAAI8W,EAAoB,IACpBC,EAAoB,IACpBC,EAAoBlU,EAASnM,EAAImgB,EACjCG,EAAepR,EAAM3F,SAAW8W,EAChCE,EAAoBpU,EAASlM,EAAImgB,EACjCI,EAAetR,EAAMxF,SAAW6W,EAGjB,IAAfpU,EAASnM,IAAWmgB,EAAoB3mB,KAAK8B,KAAKglB,EAAepR,EAAM3F,UAAY4C,EAASnM,IAC7E,IAAfmM,EAASlM,IAAWmgB,EAAoB5mB,KAAK8B,KAAKklB,EAAetR,EAAMxF,UAAYyC,EAASlM,IAChG,IAAImM,EAAmB5S,KAAKK,IAAIsmB,EAAmBC,GAEnDlR,EAAM3F,SAAW+W,EACjBpR,EAAMxF,SAAW8W,EAGjB,IAAIf,EAAcvQ,EAAMpY,MAAQ0nB,EAAK9D,MACjCgF,EAAexQ,EAAMnY,OAASynB,EAAK9D,MACvCxL,EAAMyQ,KAAOnmB,KAAKoM,IAAM6Y,EAAQc,WAAa,EAAME,EAAc,EAAK,GACtEvQ,EAAM0Q,MAAQ1Q,EAAMyQ,KACpBzQ,EAAM2Q,KAAOrmB,KAAKoM,IAAM6Y,EAAQe,YAAc,EAAME,EAAe,EAAK,GACxExQ,EAAM4Q,MAAQ5Q,EAAM2Q,KACpB3Q,EAAM3F,SAAW/P,KAAKK,IAAIL,KAAKoM,IAAIsJ,EAAM3F,SAAU2F,EAAM0Q,MAAO1Q,EAAMyQ,MACtEzQ,EAAMxF,SAAWlQ,KAAKK,IAAIL,KAAKoM,IAAIsJ,EAAMxF,SAAUwF,EAAM4Q,MAAO5Q,EAAM2Q,MAEtEpB,EAAQK,aAAaj2B,WAAWujB,GAAkB1jB,UAAW,eAAkBwmB,EAAc,SAAI,OAAUA,EAAc,SAAI,WAE/HuR,gBAAiB,WACf,IACIjC,EADSn7B,KACKm7B,KACdC,EAAUD,EAAKC,QACfA,EAAQnK,UAHCjxB,KAGkB8b,gBAHlB9b,KAG2CyZ,cACtD2hB,EAAQI,SAASn2B,UAAU,+BAC3B+1B,EAAQK,aAAap2B,UAAU,sBAE/B81B,EAAK9D,MAAQ,EACb8D,EAAKZ,aAAe,EAEpBa,EAAQnK,cAAWlqB,EACnBq0B,EAAQI,cAAWz0B,EACnBq0B,EAAQK,kBAAe10B,IAI3BzC,OAAQ,SAAgB+B,GACtB,IACI80B,EADSn7B,KACKm7B,KAEdA,EAAK9D,OAAwB,IAAf8D,EAAK9D,MAErB8D,EAAKkC,MAGLlC,EAAKmC,GAAGj3B,IAGZi3B,GAAI,SAAcj3B,GAChB,IAgBIk3B,EACAC,EAGAlW,EACAC,EACAkW,EACAC,EACAC,EACAC,EACAxB,EACAC,EACAwB,EACAC,EACAC,EACAC,EACA9B,EACAC,EAjCAxoB,EAAS3T,KAETm7B,EAAOxnB,EAAOwnB,KACdltB,EAAS0F,EAAO1F,OAAOktB,KACvBC,EAAUD,EAAKC,QACfvP,EAAQsP,EAAKtP,OAEZuP,EAAQnK,WACXmK,EAAQnK,SAAWtd,EAAOyI,aAAe7Z,EAAEoR,EAAOyI,cAAgBzI,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,aAC1F2hB,EAAQI,SAAWJ,EAAQnK,SAAStlB,KAAK,oBACzCyvB,EAAQK,aAAeL,EAAQI,SAAShwB,OAAQ,IAAOyC,EAAqB,iBAEzEmtB,EAAQI,UAAwC,IAA5BJ,EAAQI,SAASl5B,UAE1C84B,EAAQnK,SAASttB,SAAU,GAAMsK,EAAuB,uBAqBpB,IAAzB4d,EAAMoQ,aAAatf,GAAqBtW,GACjDk3B,EAAoB,aAAXl3B,EAAEuf,KAAsBvf,EAAE21B,eAAe,GAAG5V,MAAQ/f,EAAE+f,MAC/DoX,EAAoB,aAAXn3B,EAAEuf,KAAsBvf,EAAE21B,eAAe,GAAG1V,MAAQjgB,EAAEigB,QAE/DiX,EAAS1R,EAAMoQ,aAAatf,EAC5B6gB,EAAS3R,EAAMoQ,aAAarf,GAG9Bue,EAAK9D,MAAQ+D,EAAQK,aAAal3B,KAAK,qBAAuB0J,EAAOytB,SACrEP,EAAKZ,aAAea,EAAQK,aAAal3B,KAAK,qBAAuB0J,EAAOytB,SACxEr1B,GACF61B,EAAad,EAAQnK,SAAS,GAAGtoB,YACjCwzB,EAAcf,EAAQnK,SAAS,GAAGnoB,aAGlCwe,EAFU8T,EAAQnK,SAASloB,SAASU,KAEhByyB,EAAa,EAAMqB,EACvChW,EAFU6T,EAAQnK,SAASloB,SAASS,IAEhB2yB,EAAc,EAAMqB,EAExCG,EAAavC,EAAQI,SAAS,GAAG7yB,YACjCi1B,EAAcxC,EAAQI,SAAS,GAAG1yB,aAClCszB,EAAcuB,EAAaxC,EAAK9D,MAChCgF,EAAeuB,EAAczC,EAAK9D,MAIlC0G,IAFAF,EAAgB1nB,KAAKoM,IAAM2Z,EAAa,EAAME,EAAc,EAAK,IAGjE4B,IAFAF,EAAgB3nB,KAAKoM,IAAM4Z,EAAc,EAAME,EAAe,EAAK,KAInEoB,EAAanW,EAAQ6T,EAAK9D,OAGTwG,IACfJ,EAAaI,GAEEE,EAAbN,IACFA,EAAaM,IANfL,EAAanW,EAAQ4T,EAAK9D,OASTyG,IACfJ,EAAaI,GAEEE,EAAbN,IACFA,EAAaM,IAIfN,EADAD,EAAa,EAGfrC,EAAQK,aAAaj2B,WAAW,KAAKH,UAAW,eAAiBo4B,EAAa,OAASC,EAAa,SACpGtC,EAAQI,SAASh2B,WAAW,KAAKH,UAAW,4BAA+B81B,EAAU,MAAI,OAE3FkC,IAAK,WACH,IAAI1pB,EAAS3T,KAETm7B,EAAOxnB,EAAOwnB,KACdltB,EAAS0F,EAAO1F,OAAOktB,KACvBC,EAAUD,EAAKC,QAEdA,EAAQnK,WACXmK,EAAQnK,SAAWtd,EAAOyI,aAAe7Z,EAAEoR,EAAOyI,cAAgBzI,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,aAC1F2hB,EAAQI,SAAWJ,EAAQnK,SAAStlB,KAAK,oBACzCyvB,EAAQK,aAAeL,EAAQI,SAAShwB,OAAQ,IAAOyC,EAAqB,iBAEzEmtB,EAAQI,UAAwC,IAA5BJ,EAAQI,SAASl5B,SAE1C64B,EAAK9D,MAAQ,EACb8D,EAAKZ,aAAe,EACpBa,EAAQK,aAAaj2B,WAAW,KAAKH,UAAU,sBAC/C+1B,EAAQI,SAASh2B,WAAW,KAAKH,UAAU,+BAC3C+1B,EAAQnK,SAAShtB,YAAa,GAAMgK,EAAuB,kBAC3DmtB,EAAQnK,cAAWlqB,IAGrB2rB,OAAQ,WACN,IAAI/e,EAAS3T,KACTm7B,EAAOxnB,EAAOwnB,KAClB,IAAIA,EAAKxmB,QAAT,CACAwmB,EAAKxmB,SAAU,EAEf,IAAIxE,IAA+C,eAA7BwD,EAAO0R,YAAYsE,QAA0Bta,GAAQc,kBAAmBwD,EAAO1F,OAAO4W,mBAAmB,CAAE+E,SAAS,EAAMzjB,SAAS,GAGrJkJ,GAAQmB,UACVmD,EAAOS,WAAWxO,GAAG,eAAgB,gBAAiBu1B,EAAKD,eAAgB/qB,GAC3EwD,EAAOS,WAAWxO,GAAG,gBAAiB,gBAAiBu1B,EAAKS,gBAAiBzrB,GAC7EwD,EAAOS,WAAWxO,GAAG,aAAc,gBAAiBu1B,EAAKY,aAAc5rB,IACjC,eAA7BwD,EAAO0R,YAAYsE,QAC5BhW,EAAOS,WAAWxO,GAAG+N,EAAO0R,YAAYsE,MAAO,gBAAiBwR,EAAKD,eAAgB/qB,GACrFwD,EAAOS,WAAWxO,GAAG+N,EAAO0R,YAAYwE,KAAM,gBAAiBsR,EAAKS,gBAAiBzrB,GACrFwD,EAAOS,WAAWxO,GAAG+N,EAAO0R,YAAYyE,IAAK,gBAAiBqR,EAAKY,aAAc5rB,IAInFwD,EAAOS,WAAWxO,GAAG+N,EAAO0R,YAAYwE,KAAO,IAAOlW,EAAO1F,OAAOktB,KAAmB,eAAIA,EAAK/T,eAElGuL,QAAS,WACP,IAAIhf,EAAS3T,KACTm7B,EAAOxnB,EAAOwnB,KAClB,GAAKA,EAAKxmB,QAAV,CAEAhB,EAAOwnB,KAAKxmB,SAAU,EAEtB,IAAIxE,IAA+C,eAA7BwD,EAAO0R,YAAYsE,QAA0Bta,GAAQc,kBAAmBwD,EAAO1F,OAAO4W,mBAAmB,CAAE+E,SAAS,EAAMzjB,SAAS,GAGrJkJ,GAAQmB,UACVmD,EAAOS,WAAW9M,IAAI,eAAgB,gBAAiB6zB,EAAKD,eAAgB/qB,GAC5EwD,EAAOS,WAAW9M,IAAI,gBAAiB,gBAAiB6zB,EAAKS,gBAAiBzrB,GAC9EwD,EAAOS,WAAW9M,IAAI,aAAc,gBAAiB6zB,EAAKY,aAAc5rB,IAClC,eAA7BwD,EAAO0R,YAAYsE,QAC5BhW,EAAOS,WAAW9M,IAAIqM,EAAO0R,YAAYsE,MAAO,gBAAiBwR,EAAKD,eAAgB/qB,GACtFwD,EAAOS,WAAW9M,IAAIqM,EAAO0R,YAAYwE,KAAM,gBAAiBsR,EAAKS,gBAAiBzrB,GACtFwD,EAAOS,WAAW9M,IAAIqM,EAAO0R,YAAYyE,IAAK,gBAAiBqR,EAAKY,aAAc5rB,IAIpFwD,EAAOS,WAAW9M,IAAIqM,EAAO0R,YAAYwE,KAAO,IAAOlW,EAAO1F,OAAOktB,KAAmB,eAAIA,EAAK/T,gBAkHjG6W,EAAO,CACTC,YAAa,SAAqB9zB,EAAO+zB,QACd,IAApBA,IAA6BA,GAAkB,GAEpD,IAAIxqB,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAOyiB,KAC3B,QAAqB,IAAVtmB,GACkB,IAAzBuJ,EAAOkB,OAAOvS,OAAlB,CACA,IAEI2uB,EAFYtd,EAAOe,SAAWf,EAAO1F,OAAOyG,QAAQC,QAGpDhB,EAAOS,WAAWrT,SAAU,IAAO4S,EAAO1F,OAAiB,WAAI,6BAAgC7D,EAAQ,MACvGuJ,EAAOkB,OAAOtK,GAAGH,GAEjBg0B,EAAUnN,EAAStlB,KAAM,IAAOsC,EAAmB,aAAI,SAAYA,EAAkB,YAAI,UAAaA,EAAmB,aAAI,MAC7HgjB,EAAS9sB,SAAS8J,EAAOowB,eAAkBpN,EAAS9sB,SAAS8J,EAAOqwB,cAAiBrN,EAAS9sB,SAAS8J,EAAOswB,gBAChHH,EAAUA,EAAQp6B,IAAIitB,EAAS,KAEV,IAAnBmN,EAAQ97B,QAEZ87B,EAAQv0B,KAAK,SAAU20B,EAAYhT,GACjC,IAAIgQ,EAAWj5B,EAAEipB,GACjBgQ,EAAS73B,SAASsK,EAAOswB,cAEzB,IAAIE,EAAajD,EAASj3B,KAAK,mBAC3BknB,EAAM+P,EAASj3B,KAAK,YACpBmnB,EAAS8P,EAASj3B,KAAK,eACvBonB,EAAQ6P,EAASj3B,KAAK,cAE1BoP,EAAO4X,UAAUiQ,EAAS,GAAK/P,GAAOgT,EAAa/S,EAAQC,GAAO,EAAO,WACvE,GAAI,MAAOhY,GAA8CA,KAAWA,GAAWA,EAAO1F,UAAW0F,EAAOmK,UAAxG,CAqBA,GApBI2gB,GACFjD,EAAS9xB,IAAI,mBAAqB,QAAW+0B,EAAa,MAC1DjD,EAAS12B,WAAW,qBAEhB4mB,IACF8P,EAASj3B,KAAK,SAAUmnB,GACxB8P,EAAS12B,WAAW,gBAElB6mB,IACF6P,EAASj3B,KAAK,QAASonB,GACvB6P,EAAS12B,WAAW,eAElB2mB,IACF+P,EAASj3B,KAAK,MAAOknB,GACrB+P,EAAS12B,WAAW,cAIxB02B,EAAS73B,SAASsK,EAAOqwB,aAAar6B,YAAYgK,EAAOswB,cACzDtN,EAAStlB,KAAM,IAAOsC,EAAqB,gBAAI/J,SAC3CyP,EAAO1F,OAAOkN,MAAQgjB,EAAiB,CACzC,IAAIO,EAAqBzN,EAAS1sB,KAAK,2BACvC,GAAI0sB,EAAS9sB,SAASwP,EAAO1F,OAAOmN,qBAAsB,CACxD,IAAIujB,EAAgBhrB,EAAOS,WAAWrT,SAAU,6BAAgC29B,EAAqB,WAAe/qB,EAAO1F,OAA0B,oBAAI,KACzJ0F,EAAO+c,KAAKwN,YAAYS,EAAcv0B,SAAS,OAC1C,CACL,IAAIw0B,EAAkBjrB,EAAOS,WAAWrT,SAAU,IAAO4S,EAAO1F,OAA0B,oBAAI,6BAAgCywB,EAAqB,MACnJ/qB,EAAO+c,KAAKwN,YAAYU,EAAgBx0B,SAAS,IAGrDuJ,EAAO/B,KAAK,iBAAkBqf,EAAS,GAAIuK,EAAS,OAGtD7nB,EAAO/B,KAAK,gBAAiBqf,EAAS,GAAIuK,EAAS,QAGvD7K,KAAM,WACJ,IAAIhd,EAAS3T,KACToU,EAAaT,EAAOS,WACpBqY,EAAe9Y,EAAO1F,OACtB4G,EAASlB,EAAOkB,OAChB4E,EAAc9F,EAAO8F,YACrBhF,EAAYd,EAAOe,SAAW+X,EAAa/X,QAAQC,QACnD1G,EAASwe,EAAaiE,KAEtBpa,EAAgBmW,EAAanW,cAKjC,SAASuoB,EAAWz0B,GAClB,GAAIqK,GACF,GAAIL,EAAWrT,SAAU,IAAO0rB,EAAuB,WAAI,6BAAgCriB,EAAQ,MAAQ9H,OACzG,OAAO,OAEJ,GAAIuS,EAAOzK,GAAU,OAAO,EACnC,OAAO,EAET,SAASmT,EAAWgQ,GAClB,OAAI9Y,EACKlS,EAAEgrB,GAAShpB,KAAK,2BAElBhC,EAAEgrB,GAASnjB,QAIpB,GApBsB,SAAlBkM,IACFA,EAAgB,GAkBb3C,EAAO+c,KAAKoO,qBAAsBnrB,EAAO+c,KAAKoO,oBAAqB,GACpEnrB,EAAO1F,OAAOiL,sBAChB9E,EAAWrT,SAAU,IAAO0rB,EAA8B,mBAAI5iB,KAAK,SAAUk1B,EAASxR,GACpF,IAAInjB,EAAQqK,EAAYlS,EAAEgrB,GAAShpB,KAAK,2BAA6BhC,EAAEgrB,GAASnjB,QAChFuJ,EAAO+c,KAAKwN,YAAY9zB,UAErB,GAAoB,EAAhBkM,EACT,IAAK,IAAIjU,EAAIoX,EAAapX,EAAIoX,EAAcnD,EAAejU,GAAK,EAC1Dw8B,EAAWx8B,IAAMsR,EAAO+c,KAAKwN,YAAY77B,QAG/CsR,EAAO+c,KAAKwN,YAAYzkB,GAE1B,GAAIxL,EAAO+wB,aACT,GAAoB,EAAhB1oB,GAAsBrI,EAAOgxB,oBAAkD,EAA5BhxB,EAAOgxB,mBAAyB,CAMrF,IALA,IAAIC,EAASjxB,EAAOgxB,mBAChBhS,EAAM3W,EACN6oB,EAAWhpB,KAAKoM,IAAI9I,EAAcwT,EAAM9W,KAAKK,IAAI0oB,EAAQjS,GAAMpY,EAAOvS,QACtE88B,EAAWjpB,KAAKK,IAAIiD,EAActD,KAAKK,IAAIyW,EAAKiS,GAAS,GAEpD7mB,EAAMoB,EAAcnD,EAAe+B,EAAM8mB,EAAU9mB,GAAO,EAC7DwmB,EAAWxmB,IAAQ1E,EAAO+c,KAAKwN,YAAY7lB,GAGjD,IAAK,IAAIE,EAAM6mB,EAAU7mB,EAAMkB,EAAalB,GAAO,EAC7CsmB,EAAWtmB,IAAQ5E,EAAO+c,KAAKwN,YAAY3lB,OAE5C,CACL,IAAI+C,EAAYlH,EAAWrT,SAAU,IAAO0rB,EAA2B,gBAChD,EAAnBnR,EAAUhZ,QAAcqR,EAAO+c,KAAKwN,YAAY3gB,EAAWjC,IAE/D,IAAIE,EAAYpH,EAAWrT,SAAU,IAAO0rB,EAA2B,gBAChD,EAAnBjR,EAAUlZ,QAAcqR,EAAO+c,KAAKwN,YAAY3gB,EAAW/B,OAiFnE6jB,EAAa,CACfC,aAAc,SAAsB3iB,EAAGC,GACrC,IACMuiB,EACAC,EACAG,EAqBFC,EACAC,EAzBAC,EAIK,SAAUC,EAAOphB,GAGtB,IAFA6gB,GAAY,EACZD,EAAWQ,EAAMr9B,OACY,EAAtB68B,EAAWC,GAEZO,EADJJ,EAAQJ,EAAWC,GAAY,IACX7gB,EAClB6gB,EAAWG,EAEXJ,EAAWI,EAGf,OAAOJ,GAuBX,OApBAn/B,KAAK2c,EAAIA,EACT3c,KAAK4c,EAAIA,EACT5c,KAAKm2B,UAAYxZ,EAAEra,OAAS,EAO5BtC,KAAK4/B,YAAc,SAAqB5E,GACtC,OAAKA,GAGLyE,EAAKC,EAAa1/B,KAAK2c,EAAGqe,GAC1BwE,EAAKC,EAAK,GAIAzE,EAAKh7B,KAAK2c,EAAE6iB,KAAQx/B,KAAK4c,EAAE6iB,GAAMz/B,KAAK4c,EAAE4iB,KAASx/B,KAAK2c,EAAE8iB,GAAMz/B,KAAK2c,EAAE6iB,IAAQx/B,KAAK4c,EAAE4iB,IAR5E,GAUbx/B,MAGT6/B,uBAAwB,SAAgCC,GACtD,IAAInsB,EAAS3T,KACR2T,EAAOosB,WAAWC,SACrBrsB,EAAOosB,WAAWC,OAASrsB,EAAO1F,OAAOkN,KACrC,IAAIkkB,EAAWC,aAAa3rB,EAAOqB,WAAY8qB,EAAE9qB,YACjD,IAAIqqB,EAAWC,aAAa3rB,EAAOoB,SAAU+qB,EAAE/qB,YAGvD0H,aAAc,SAAsBwjB,EAAgBvjB,GAClD,IAEIwjB,EACAC,EAHAxsB,EAAS3T,KACTogC,EAAazsB,EAAOosB,WAAWM,QAGnC,SAASC,EAAuBR,GAK9B,IAAIhmB,EAAYnG,EAAOY,cAAgBZ,EAAOmG,UAAYnG,EAAOmG,UAC7B,UAAhCnG,EAAO1F,OAAO8xB,WAAWQ,KAC3B5sB,EAAOosB,WAAWF,uBAAuBC,GAGzCK,GAAuBxsB,EAAOosB,WAAWC,OAAOJ,aAAa9lB,IAG1DqmB,GAAuD,cAAhCxsB,EAAO1F,OAAO8xB,WAAWQ,KACnDL,GAAcJ,EAAEplB,eAAiBolB,EAAE1lB,iBAAmBzG,EAAO+G,eAAiB/G,EAAOyG,gBACrF+lB,GAAwBrmB,EAAYnG,EAAOyG,gBAAkB8lB,EAAcJ,EAAE1lB,gBAG3EzG,EAAO1F,OAAO8xB,WAAWS,UAC3BL,EAAsBL,EAAEplB,eAAiBylB,GAE3CL,EAAEtlB,eAAe2lB,GACjBL,EAAErjB,aAAa0jB,EAAqBxsB,GACpCmsB,EAAElkB,oBACFkkB,EAAE/kB,sBAEJ,GAAIlJ,MAAMC,QAAQsuB,GAChB,IAAK,IAAI/9B,EAAI,EAAGA,EAAI+9B,EAAW99B,OAAQD,GAAK,EACtC+9B,EAAW/9B,KAAOqa,GAAgB0jB,EAAW/9B,aAActC,GAC7DugC,EAAuBF,EAAW/9B,SAG7B+9B,aAAsBrgC,GAAU2c,IAAiB0jB,GAC1DE,EAAuBF,IAG3B5mB,cAAe,SAAuB/T,EAAUiX,GAC9C,IAEIra,EAFAsR,EAAS3T,KACTogC,EAAazsB,EAAOosB,WAAWM,QAEnC,SAASI,EAAwBX,GAC/BA,EAAEtmB,cAAc/T,EAAUkO,GACT,IAAblO,IACFq6B,EAAE/iB,kBACE+iB,EAAE7xB,OAAOiP,YACX5Q,GAAMI,SAAS,WACbozB,EAAE1mB,qBAGN0mB,EAAE1rB,WAAWjM,cAAc,WACpBi4B,IACDN,EAAE7xB,OAAOkN,MAAwC,UAAhCxH,EAAO1F,OAAO8xB,WAAWQ,IAC5CT,EAAE3hB,UAEJ2hB,EAAE33B,oBAIR,GAAI0J,MAAMC,QAAQsuB,GAChB,IAAK/9B,EAAI,EAAGA,EAAI+9B,EAAW99B,OAAQD,GAAK,EAClC+9B,EAAW/9B,KAAOqa,GAAgB0jB,EAAW/9B,aAActC,GAC7D0gC,EAAwBL,EAAW/9B,SAG9B+9B,aAAsBrgC,GAAU2c,IAAiB0jB,GAC1DK,EAAwBL,KA8D1BM,EAAO,CACTC,gBAAiB,SAAyB/sB,GAExC,OADAA,EAAIrP,KAAK,WAAY,KACdqP,GAETgtB,UAAW,SAAmBhtB,EAAKitB,GAEjC,OADAjtB,EAAIrP,KAAK,OAAQs8B,GACVjtB,GAETktB,WAAY,SAAoBltB,EAAKmtB,GAEnC,OADAntB,EAAIrP,KAAK,aAAcw8B,GAChBntB,GAETotB,UAAW,SAAmBptB,GAE5B,OADAA,EAAIrP,KAAK,iBAAiB,GACnBqP,GAETqtB,SAAU,SAAkBrtB,GAE1B,OADAA,EAAIrP,KAAK,iBAAiB,GACnBqP,GAETstB,WAAY,SAAoB76B,GAC9B,IAAIsN,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAOyyB,KAC3B,GAAkB,KAAdr6B,EAAEsrB,QAAN,CACA,IAAIwP,EAAY5+B,EAAE8D,EAAEC,QAChBqN,EAAOqX,YAAcrX,EAAOqX,WAAWoK,SAAW+L,EAAUz6B,GAAGiN,EAAOqX,WAAWoK,WAC7EzhB,EAAOiH,QAAUjH,EAAO1F,OAAOkN,MACnCxH,EAAOuK,YAELvK,EAAOiH,MACTjH,EAAO+sB,KAAKU,OAAOnzB,EAAOozB,kBAE1B1tB,EAAO+sB,KAAKU,OAAOnzB,EAAOqzB,mBAG1B3tB,EAAOqX,YAAcrX,EAAOqX,WAAWqK,SAAW8L,EAAUz6B,GAAGiN,EAAOqX,WAAWqK,WAC7E1hB,EAAOgH,cAAgBhH,EAAO1F,OAAOkN,MACzCxH,EAAO0K,YAEL1K,EAAOgH,YACThH,EAAO+sB,KAAKU,OAAOnzB,EAAOszB,mBAE1B5tB,EAAO+sB,KAAKU,OAAOnzB,EAAOuzB,mBAG1B7tB,EAAOkiB,YAAcsL,EAAUz6B,GAAI,IAAOiN,EAAO1F,OAAO4nB,WAAsB,cAChFsL,EAAU,GAAGM,UAGjBL,OAAQ,SAAgBM,GACtB,IACIC,EADS3hC,KACa0gC,KAAKkB,WACH,IAAxBD,EAAar/B,SACjBq/B,EAAa/+B,KAAK,IAClB++B,EAAa/+B,KAAK8+B,KAEpBG,iBAAkB,WAChB,IAAIluB,EAAS3T,KAEb,IAAI2T,EAAO1F,OAAOkN,KAAlB,CACA,IAAIwU,EAAMhc,EAAOqX,WACboK,EAAUzF,EAAIyF,QACdC,EAAU1F,EAAI0F,QAEdA,GAA4B,EAAjBA,EAAQ/yB,SACjBqR,EAAOgH,YACThH,EAAO+sB,KAAKM,UAAU3L,GAEtB1hB,EAAO+sB,KAAKO,SAAS5L,IAGrBD,GAA4B,EAAjBA,EAAQ9yB,SACjBqR,EAAOiH,MACTjH,EAAO+sB,KAAKM,UAAU5L,GAEtBzhB,EAAO+sB,KAAKO,SAAS7L,MAI3B0M,iBAAkB,WAChB,IAAInuB,EAAS3T,KACTiO,EAAS0F,EAAO1F,OAAOyyB,KACvB/sB,EAAOkiB,YAAcliB,EAAO1F,OAAO4nB,WAAWsC,WAAaxkB,EAAOkiB,WAAWI,SAAWtiB,EAAOkiB,WAAWI,QAAQ3zB,QACpHqR,EAAOkiB,WAAWI,QAAQpsB,KAAK,SAAU8sB,EAAaoL,GACpD,IAAIC,EAAYz/B,EAAEw/B,GAClBpuB,EAAO+sB,KAAKC,gBAAgBqB,GAC5BruB,EAAO+sB,KAAKE,UAAUoB,EAAW,UACjCruB,EAAO+sB,KAAKI,WAAWkB,EAAW/zB,EAAOg0B,wBAAwB30B,QAAQ,YAAa00B,EAAU53B,QAAU,OAIhHqY,KAAM,WACJ,IAAI9O,EAAS3T,KAEb2T,EAAOC,IAAInJ,OAAOkJ,EAAO+sB,KAAKkB,YAG9B,IACIxM,EACAC,EAFApnB,EAAS0F,EAAO1F,OAAOyyB,KAGvB/sB,EAAOqX,YAAcrX,EAAOqX,WAAWoK,UACzCA,EAAUzhB,EAAOqX,WAAWoK,SAE1BzhB,EAAOqX,YAAcrX,EAAOqX,WAAWqK,UACzCA,EAAU1hB,EAAOqX,WAAWqK,SAE1BD,IACFzhB,EAAO+sB,KAAKC,gBAAgBvL,GAC5BzhB,EAAO+sB,KAAKE,UAAUxL,EAAS,UAC/BzhB,EAAO+sB,KAAKI,WAAW1L,EAASnnB,EAAOqzB,kBACvClM,EAAQxvB,GAAG,UAAW+N,EAAO+sB,KAAKQ,aAEhC7L,IACF1hB,EAAO+sB,KAAKC,gBAAgBtL,GAC5B1hB,EAAO+sB,KAAKE,UAAUvL,EAAS,UAC/B1hB,EAAO+sB,KAAKI,WAAWzL,EAASpnB,EAAOuzB,kBACvCnM,EAAQzvB,GAAG,UAAW+N,EAAO+sB,KAAKQ,aAIhCvtB,EAAOkiB,YAAcliB,EAAO1F,OAAO4nB,WAAWsC,WAAaxkB,EAAOkiB,WAAWI,SAAWtiB,EAAOkiB,WAAWI,QAAQ3zB,QACpHqR,EAAOkiB,WAAWjiB,IAAIhO,GAAG,UAAY,IAAO+N,EAAO1F,OAAO4nB,WAAsB,YAAIliB,EAAO+sB,KAAKQ,aAGpG1T,QAAS,WACP,IAGI4H,EACAC,EAJA1hB,EAAS3T,KACT2T,EAAO+sB,KAAKkB,YAA8C,EAAhCjuB,EAAO+sB,KAAKkB,WAAWt/B,QAAcqR,EAAO+sB,KAAKkB,WAAW19B,SAItFyP,EAAOqX,YAAcrX,EAAOqX,WAAWoK,UACzCA,EAAUzhB,EAAOqX,WAAWoK,SAE1BzhB,EAAOqX,YAAcrX,EAAOqX,WAAWqK,UACzCA,EAAU1hB,EAAOqX,WAAWqK,SAE1BD,GACFA,EAAQ9tB,IAAI,UAAWqM,EAAO+sB,KAAKQ,YAEjC7L,GACFA,EAAQ/tB,IAAI,UAAWqM,EAAO+sB,KAAKQ,YAIjCvtB,EAAOkiB,YAAcliB,EAAO1F,OAAO4nB,WAAWsC,WAAaxkB,EAAOkiB,WAAWI,SAAWtiB,EAAOkiB,WAAWI,QAAQ3zB,QACpHqR,EAAOkiB,WAAWjiB,IAAItM,IAAI,UAAY,IAAOqM,EAAO1F,OAAO4nB,WAAsB,YAAIliB,EAAO+sB,KAAKQ,cA0DnGgB,EAAU,CACZzf,KAAM,WACJ,IAAI9O,EAAS3T,KACb,GAAK2T,EAAO1F,OAAOvM,QAAnB,CACA,IAAKJ,EAAII,UAAYJ,EAAII,QAAQygC,UAG/B,OAFAxuB,EAAO1F,OAAOvM,QAAQiT,SAAU,OAChChB,EAAO1F,OAAOm0B,eAAeztB,SAAU,GAGzC,IAAIjT,EAAUiS,EAAOjS,QACrBA,EAAQgc,aAAc,EACtBhc,EAAQ2gC,MAAQH,EAAQI,iBACnB5gC,EAAQ2gC,MAAMp9B,KAAQvD,EAAQ2gC,MAAM59B,SACzC/C,EAAQ6gC,cAAc,EAAG7gC,EAAQ2gC,MAAM59B,MAAOkP,EAAO1F,OAAOiX,oBACvDvR,EAAO1F,OAAOvM,QAAQ8gC,cACzBlhC,EAAIlB,iBAAiB,WAAYuT,EAAOjS,QAAQ+gC,uBAGpDjV,QAAS,WACMxtB,KACDiO,OAAOvM,QAAQ8gC,cACzBlhC,EAAIjB,oBAAoB,WAFbL,KAEgC0B,QAAQ+gC,qBAGvDA,mBAAoB,WACLziC,KACN0B,QAAQ2gC,MAAQH,EAAQI,gBADlBtiC,KAEN0B,QAAQ6gC,cAFFviC,KAEuBiO,OAAOoL,MAF9BrZ,KAE4C0B,QAAQ2gC,MAAM59B,OAAO,IAEhF69B,cAAe,WACb,IAAII,EAAYphC,EAAIF,SAASuhC,SAAS5wB,MAAM,GAAG5O,MAAM,KAAK6E,OAAO,SAAU46B,GAAQ,MAAgB,KAATA,IACtF7M,EAAQ2M,EAAUpgC,OAGtB,MAAO,CAAE2C,IAFCy9B,EAAU3M,EAAQ,GAETtxB,MADPi+B,EAAU3M,EAAQ,KAGhC8M,WAAY,SAAoB59B,EAAKmF,GAEnC,GADapK,KACD0B,QAAQgc,aADP1d,KAC8BiO,OAAOvM,QAAQiT,QAA1D,CACA,IAAIiC,EAFS5W,KAEM6U,OAAOtK,GAAGH,GACzB3F,EAAQy9B,EAAQY,QAAQlsB,EAAMrS,KAAK,iBAClCjD,EAAIF,SAASuhC,SAASI,SAAS99B,KAClCR,EAAQQ,EAAM,IAAMR,GAEtB,IAAIu+B,EAAe1hC,EAAII,QAAQuhC,MAC3BD,GAAgBA,EAAav+B,QAAUA,IAR9BzE,KAWFiO,OAAOvM,QAAQ8gC,aACxBlhC,EAAII,QAAQ8gC,aAAa,CAAE/9B,MAAOA,GAAS,KAAMA,GAEjDnD,EAAII,QAAQygC,UAAU,CAAE19B,MAAOA,GAAS,KAAMA,MAGlDq+B,QAAS,SAAiBh5B,GACxB,OAAOA,EAAK8D,WACTN,QAAQ,OAAQ,KAChBA,QAAQ,WAAY,IACpBA,QAAQ,OAAQ,KAChBA,QAAQ,MAAO,IACfA,QAAQ,MAAO,KAEpBi1B,cAAe,SAAuBlpB,EAAO5U,EAAOuY,GAClD,IAAIrJ,EAAS3T,KACb,GAAIyE,EACF,IAAK,IAAIpC,EAAI,EAAGC,EAASqR,EAAOkB,OAAOvS,OAAQD,EAAIC,EAAQD,GAAK,EAAG,CACjE,IAAIuU,EAAQjD,EAAOkB,OAAOtK,GAAGlI,GAE7B,GADmB6/B,EAAQY,QAAQlsB,EAAMrS,KAAK,mBACzBE,IAAUmS,EAAMzS,SAASwP,EAAO1F,OAAOmN,qBAAsB,CAChF,IAAIhR,EAAQwM,EAAMxM,QAClBuJ,EAAO0J,QAAQjT,EAAOiP,EAAO2D,SAIjCrJ,EAAO0J,QAAQ,EAAGhE,EAAO2D,KAgD3BkmB,EAAiB,CACnBC,YAAa,WACX,IAAIxvB,EAAS3T,KACTojC,EAAUnjC,EAAImB,SAASC,KAAKiM,QAAQ,IAAK,IAE7C,GAAI81B,IADkBzvB,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,aAAalV,KAAK,aAC/B,CAC/B,IAAIyZ,EAAWrK,EAAOS,WAAWrT,SAAU,IAAO4S,EAAO1F,OAAiB,WAAI,eAAkBm1B,EAAU,MAAQh5B,QAClH,QAAwB,IAAb4T,EAA4B,OACvCrK,EAAO0J,QAAQW,KAGnBqlB,QAAS,WACP,IAAI1vB,EAAS3T,KACb,GAAK2T,EAAOyuB,eAAe1kB,aAAgB/J,EAAO1F,OAAOm0B,eAAeztB,QACxE,GAAIhB,EAAO1F,OAAOm0B,eAAeI,cAAgBlhC,EAAII,SAAWJ,EAAII,QAAQ8gC,aAC1ElhC,EAAII,QAAQ8gC,aAAa,KAAM,KAAQ,IAAO7uB,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,aAAalV,KAAK,cAAkB,QACrG,CACL,IAAIqS,EAAQjD,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,aAChCpY,EAAOuV,EAAMrS,KAAK,cAAgBqS,EAAMrS,KAAK,gBACjDtE,EAAImB,SAASC,KAAOA,GAAQ,KAGhCohB,KAAM,WACJ,IAAI9O,EAAS3T,KACb,MAAK2T,EAAO1F,OAAOm0B,eAAeztB,SAAYhB,EAAO1F,OAAOvM,SAAWiS,EAAO1F,OAAOvM,QAAQiT,SAA7F,CACAhB,EAAOyuB,eAAe1kB,aAAc,EACpC,IAAIrc,EAAOpB,EAAImB,SAASC,KAAKiM,QAAQ,IAAK,IAC1C,GAAIjM,EAEF,IADA,IACSgB,EAAI,EAAGC,EAASqR,EAAOkB,OAAOvS,OAAQD,EAAIC,EAAQD,GAAK,EAAG,CACjE,IAAIuU,EAAQjD,EAAOkB,OAAOtK,GAAGlI,GAE7B,IADgBuU,EAAMrS,KAAK,cAAgBqS,EAAMrS,KAAK,mBACpClD,IAASuV,EAAMzS,SAASwP,EAAO1F,OAAOmN,qBAAsB,CAC5E,IAAIhR,EAAQwM,EAAMxM,QAClBuJ,EAAO0J,QAAQjT,EANP,EAMqBuJ,EAAO1F,OAAOiX,oBAAoB,IAIjEvR,EAAO1F,OAAOm0B,eAAekB,YAC/B/gC,EAAEjB,GAAKsE,GAAG,aAAc+N,EAAOyuB,eAAee,eAGlD3V,QAAS,WACMxtB,KACFiO,OAAOm0B,eAAekB,YAC/B/gC,EAAEjB,GAAKgG,IAAI,aAFAtH,KAEqBoiC,eAAee,eAiDjDI,EAAW,CACbC,IAAK,WACH,IAAI7vB,EAAS3T,KACTyjC,EAAiB9vB,EAAOkB,OAAOtK,GAAGoJ,EAAO8F,aACzC9M,EAAQgH,EAAO1F,OAAO6mB,SAASnoB,MAC/B82B,EAAel/B,KAAK,0BACtBoI,EAAQ82B,EAAel/B,KAAK,yBAA2BoP,EAAO1F,OAAO6mB,SAASnoB,OAEhFgH,EAAOmhB,SAASD,QAAUvoB,GAAMI,SAAS,WACnCiH,EAAO1F,OAAO6mB,SAAS4O,iBACrB/vB,EAAO1F,OAAOkN,MAChBxH,EAAOwK,UACPxK,EAAO0K,UAAU1K,EAAO1F,OAAOoL,OAAO,GAAM,GAC5C1F,EAAO/B,KAAK,aACF+B,EAAOgH,YAGPhH,EAAO1F,OAAO6mB,SAAS6O,gBAIjChwB,EAAOmhB,SAASE,QAHhBrhB,EAAO0J,QAAQ1J,EAAOkB,OAAOvS,OAAS,EAAGqR,EAAO1F,OAAOoL,OAAO,GAAM,GACpE1F,EAAO/B,KAAK,cAJZ+B,EAAO0K,UAAU1K,EAAO1F,OAAOoL,OAAO,GAAM,GAC5C1F,EAAO/B,KAAK,aAOL+B,EAAO1F,OAAOkN,MACvBxH,EAAOwK,UACPxK,EAAOuK,UAAUvK,EAAO1F,OAAOoL,OAAO,GAAM,GAC5C1F,EAAO/B,KAAK,aACF+B,EAAOiH,MAGPjH,EAAO1F,OAAO6mB,SAAS6O,gBAIjChwB,EAAOmhB,SAASE,QAHhBrhB,EAAO0J,QAAQ,EAAG1J,EAAO1F,OAAOoL,OAAO,GAAM,GAC7C1F,EAAO/B,KAAK,cAJZ+B,EAAOuK,UAAUvK,EAAO1F,OAAOoL,OAAO,GAAM,GAC5C1F,EAAO/B,KAAK,cAObjF,IAELgd,MAAO,WACL,IAAIhW,EAAS3T,KACb,YAAuC,IAA5B2T,EAAOmhB,SAASD,WACvBlhB,EAAOmhB,SAAS8O,UACpBjwB,EAAOmhB,SAAS8O,SAAU,EAC1BjwB,EAAO/B,KAAK,iBACZ+B,EAAOmhB,SAAS0O,OACT,KAETxO,KAAM,WACJ,IAAIrhB,EAAS3T,KACb,QAAK2T,EAAOmhB,SAAS8O,eACkB,IAA5BjwB,EAAOmhB,SAASD,UAEvBlhB,EAAOmhB,SAASD,UAClB3yB,aAAayR,EAAOmhB,SAASD,SAC7BlhB,EAAOmhB,SAASD,aAAU9tB,GAE5B4M,EAAOmhB,SAAS8O,SAAU,EAC1BjwB,EAAO/B,KAAK,iBACL,KAETiyB,MAAO,SAAexqB,GACpB,IAAI1F,EAAS3T,KACR2T,EAAOmhB,SAAS8O,UACjBjwB,EAAOmhB,SAASgP,SAChBnwB,EAAOmhB,SAASD,SAAW3yB,aAAayR,EAAOmhB,SAASD,SAC5DlhB,EAAOmhB,SAASgP,QAAS,EACX,IAAVzqB,GAAgB1F,EAAO1F,OAAO6mB,SAASiP,mBAIzCpwB,EAAOS,WAAW,GAAGhU,iBAAiB,gBAAiBuT,EAAOmhB,SAASsI,iBACvEzpB,EAAOS,WAAW,GAAGhU,iBAAiB,sBAAuBuT,EAAOmhB,SAASsI,mBAJ7EzpB,EAAOmhB,SAASgP,QAAS,EACzBnwB,EAAOmhB,SAAS0O,WAiFlBQ,EAAO,CACTvnB,aAAc,WAGZ,IAFA,IAAI9I,EAAS3T,KACT6U,EAASlB,EAAOkB,OACXxS,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAAG,CACzC,IAAI4uB,EAAWtd,EAAOkB,OAAOtK,GAAGlI,GAE5B4hC,GADShT,EAAS,GAAGvX,kBAEpB/F,EAAO1F,OAAOsO,mBAAoB0nB,GAAMtwB,EAAOmG,WACpD,IAAIoqB,EAAK,EACJvwB,EAAOI,iBACVmwB,EAAKD,EACLA,EAAK,GAEP,IAAIE,EAAexwB,EAAO1F,OAAOm2B,WAAWC,UACxCluB,KAAKK,IAAI,EAAIL,KAAK8B,IAAIgZ,EAAS,GAAG1W,UAAW,GAC7C,EAAIpE,KAAKoM,IAAIpM,KAAKK,IAAIya,EAAS,GAAG1W,UAAW,GAAI,GACrD0W,EACGvnB,IAAI,CACHsvB,QAASmL,IAEV9+B,UAAW,eAAiB4+B,EAAK,OAASC,EAAK,cAGtD1qB,cAAe,SAAuB/T,GACpC,IAAIkO,EAAS3T,KACT6U,EAASlB,EAAOkB,OAChBT,EAAaT,EAAOS,WAExB,GADAS,EAAOrP,WAAWC,GACdkO,EAAO1F,OAAOsO,kBAAiC,IAAb9W,EAAgB,CACpD,IAAI6+B,GAAiB,EACrBzvB,EAAO1M,cAAc,WACnB,IAAIm8B,GACC3wB,IAAUA,EAAOmK,UAAtB,CACAwmB,GAAiB,EACjB3wB,EAAOyJ,WAAY,EAEnB,IADA,IAAImnB,EAAgB,CAAC,sBAAuB,iBACnCliC,EAAI,EAAGA,EAAIkiC,EAAcjiC,OAAQD,GAAK,EAC7C+R,EAAWzM,QAAQ48B,EAAcliC,UAoDvCmiC,EAAO,CACT/nB,aAAc,WACZ,IAYIgoB,EAZA9wB,EAAS3T,KACT4T,EAAMD,EAAOC,IACbQ,EAAaT,EAAOS,WACpBS,EAASlB,EAAOkB,OAChB6vB,EAAc/wB,EAAOF,MACrBkxB,EAAehxB,EAAOD,OACtBY,EAAMX,EAAOY,aACbF,EAAaV,EAAOO,KACpBjG,EAAS0F,EAAO1F,OAAO22B,WACvB7wB,EAAeJ,EAAOI,eACtBU,EAAYd,EAAOe,SAAWf,EAAO1F,OAAOyG,QAAQC,QACpDkwB,EAAgB,EAEhB52B,EAAO62B,SACL/wB,GAE2B,KAD7B0wB,EAAgBrwB,EAAWzI,KAAK,wBACdrJ,SAChBmiC,EAAgBliC,EAAE,0CAClB6R,EAAW3J,OAAOg6B,IAEpBA,EAAc/6B,IAAI,CAAEgK,OAASgxB,EAAc,QAGd,KAD7BD,EAAgB7wB,EAAIjI,KAAK,wBACPrJ,SAChBmiC,EAAgBliC,EAAE,0CAClBqR,EAAInJ,OAAOg6B,KAIjB,IAAK,IAAIpiC,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAAG,CACzC,IAAI4uB,EAAWpc,EAAOtK,GAAGlI,GACrBkb,EAAalb,EACboS,IACF8I,EAAatJ,SAASgd,EAAS1sB,KAAK,2BAA4B,KAElE,IAAIwgC,EAA0B,GAAbxnB,EACbynB,EAAQ7uB,KAAKC,MAAM2uB,EAAa,KAChCzwB,IACFywB,GAAcA,EACdC,EAAQ7uB,KAAKC,OAAO2uB,EAAa,MAEnC,IAAIxqB,EAAWpE,KAAKK,IAAIL,KAAKoM,IAAI0O,EAAS,GAAG1W,SAAU,IAAK,GACxD0pB,EAAK,EACLC,EAAK,EACLe,EAAK,EACL1nB,EAAa,GAAM,GACrB0mB,EAAc,GAARe,EAAY3wB,EAClB4wB,EAAK,IACK1nB,EAAa,GAAK,GAAM,GAClC0mB,EAAK,EACLgB,EAAc,GAARD,EAAY3wB,IACRkJ,EAAa,GAAK,GAAM,GAClC0mB,EAAK5vB,EAAsB,EAAR2wB,EAAY3wB,EAC/B4wB,EAAK5wB,IACKkJ,EAAa,GAAK,GAAM,IAClC0mB,GAAM5vB,EACN4wB,EAAM,EAAI5wB,EAA4B,EAAbA,EAAiB2wB,GAExC1wB,IACF2vB,GAAMA,GAGHlwB,IACHmwB,EAAKD,EACLA,EAAK,GAGP,IAAI5+B,EAAY,YAAc0O,EAAe,GAAKgxB,GAAc,iBAAmBhxB,EAAegxB,EAAa,GAAK,oBAAsBd,EAAK,OAASC,EAAK,OAASe,EAAK,MAM3K,GALI1qB,GAAY,IAAiB,EAAZA,IACnBsqB,EAA8B,GAAbtnB,EAA+B,GAAXhD,EACjCjG,IAAOuwB,EAA+B,IAAbtnB,EAA+B,GAAXhD,IAEnD0W,EAAS5rB,UAAUA,GACf4I,EAAOi3B,aAAc,CAEvB,IAAIC,EAAepxB,EAAekd,EAAStlB,KAAK,6BAA+BslB,EAAStlB,KAAK,4BACzFy5B,EAAcrxB,EAAekd,EAAStlB,KAAK,8BAAgCslB,EAAStlB,KAAK,+BACjE,IAAxBw5B,EAAa7iC,SACf6iC,EAAe5iC,EAAG,oCAAuCwR,EAAe,OAAS,OAAS,YAC1Fkd,EAASxmB,OAAO06B,IAES,IAAvBC,EAAY9iC,SACd8iC,EAAc7iC,EAAG,oCAAuCwR,EAAe,QAAU,UAAY,YAC7Fkd,EAASxmB,OAAO26B,IAEdD,EAAa7iC,SAAU6iC,EAAa,GAAGlkC,MAAM+3B,QAAU7iB,KAAKK,KAAK+D,EAAU,IAC3E6qB,EAAY9iC,SAAU8iC,EAAY,GAAGnkC,MAAM+3B,QAAU7iB,KAAKK,IAAI+D,EAAU,KAUhF,GAPAnG,EAAW1K,IAAI,CACb27B,2BAA6B,YAAehxB,EAAa,EAAK,KAC9DixB,wBAA0B,YAAejxB,EAAa,EAAK,KAC3DkxB,uBAAyB,YAAelxB,EAAa,EAAK,KAC1DmxB,mBAAqB,YAAenxB,EAAa,EAAK,OAGpDpG,EAAO62B,OACT,GAAI/wB,EACF0wB,EAAcp/B,UAAW,qBAAwBq/B,EAAc,EAAKz2B,EAAOw3B,cAAgB,QAAWf,EAAc,EAAK,0CAA6Cz2B,EAAkB,YAAI,SACvL,CACL,IAAIy3B,EAAcvvB,KAAK8B,IAAI4sB,GAA6D,GAA3C1uB,KAAKC,MAAMD,KAAK8B,IAAI4sB,GAAiB,IAC9E3E,EAAa,KACd/pB,KAAKwvB,IAAmB,EAAdD,EAAkBvvB,KAAKwR,GAAM,KAAO,EAC5CxR,KAAKyvB,IAAmB,EAAdF,EAAkBvvB,KAAKwR,GAAM,KAAO,GAE/Cke,EAAS53B,EAAO63B,YAChBC,EAAS93B,EAAO63B,YAAc5F,EAC9Bn3B,EAASkF,EAAOw3B,aACpBhB,EAAcp/B,UAAW,WAAawgC,EAAS,QAAUE,EAAS,uBAA0BpB,EAAe,EAAK57B,GAAU,QAAW47B,EAAe,EAAIoB,EAAU,uBAGtK,IAAIC,EAAWv1B,EAAQG,UAAYH,EAAQK,aAAiBuD,EAAa,EAAK,EAC9ED,EACG/O,UAAW,qBAAuB2gC,EAAU,gBAAkBryB,EAAOI,eAAiB,EAAI8wB,GAAiB,iBAAmBlxB,EAAOI,gBAAkB8wB,EAAgB,GAAK,SAEjLrrB,cAAe,SAAuB/T,GACpC,IACImO,EADS5T,KACI4T,IADJ5T,KAEO6U,OAEjBrP,WAAWC,GACXkG,KAAK,gHACLnG,WAAWC,GANDzF,KAOFiO,OAAO22B,WAAWE,SAPhB9kC,KAOkC+T,gBAC7CH,EAAIjI,KAAK,uBAAuBnG,WAAWC,KAwD7CwgC,EAAO,CACTxpB,aAAc,WAIZ,IAHA,IAAI9I,EAAS3T,KACT6U,EAASlB,EAAOkB,OAChBP,EAAMX,EAAOY,aACRlS,EAAI,EAAGA,EAAIwS,EAAOvS,OAAQD,GAAK,EAAG,CACzC,IAAI4uB,EAAWpc,EAAOtK,GAAGlI,GACrBkY,EAAW0W,EAAS,GAAG1W,SACvB5G,EAAO1F,OAAOi4B,WAAWC,gBAC3B5rB,EAAWpE,KAAKK,IAAIL,KAAKoM,IAAI0O,EAAS,GAAG1W,SAAU,IAAK,IAE1D,IAEI6rB,GADU,IAAM7rB,EAEhB8rB,EAAU,EACVpC,GAJShT,EAAS,GAAGvX,kBAKrBwqB,EAAK,EAYT,GAXKvwB,EAAOI,eAKDO,IACT8xB,GAAWA,IALXlC,EAAKD,EAELoC,GAAWD,EACXA,EAFAnC,EAAK,GAOPhT,EAAS,GAAGhwB,MAAMqlC,QAAUnwB,KAAK8B,IAAI9B,KAAK6uB,MAAMzqB,IAAa1F,EAAOvS,OAEhEqR,EAAO1F,OAAOi4B,WAAWhB,aAAc,CAEzC,IAAIC,EAAexxB,EAAOI,eAAiBkd,EAAStlB,KAAK,6BAA+BslB,EAAStlB,KAAK,4BAClGy5B,EAAczxB,EAAOI,eAAiBkd,EAAStlB,KAAK,8BAAgCslB,EAAStlB,KAAK,+BAC1E,IAAxBw5B,EAAa7iC,SACf6iC,EAAe5iC,EAAG,oCAAuCoR,EAAOI,eAAiB,OAAS,OAAS,YACnGkd,EAASxmB,OAAO06B,IAES,IAAvBC,EAAY9iC,SACd8iC,EAAc7iC,EAAG,oCAAuCoR,EAAOI,eAAiB,QAAU,UAAY,YACtGkd,EAASxmB,OAAO26B,IAEdD,EAAa7iC,SAAU6iC,EAAa,GAAGlkC,MAAM+3B,QAAU7iB,KAAKK,KAAK+D,EAAU,IAC3E6qB,EAAY9iC,SAAU8iC,EAAY,GAAGnkC,MAAM+3B,QAAU7iB,KAAKK,IAAI+D,EAAU,IAE9E0W,EACG5rB,UAAW,eAAiB4+B,EAAK,OAASC,EAAK,oBAAsBmC,EAAU,gBAAkBD,EAAU,UAGlH5sB,cAAe,SAAuB/T,GACpC,IAAIkO,EAAS3T,KACT6U,EAASlB,EAAOkB,OAChB4E,EAAc9F,EAAO8F,YACrBrF,EAAaT,EAAOS,WAKxB,GAJAS,EACGrP,WAAWC,GACXkG,KAAK,gHACLnG,WAAWC,GACVkO,EAAO1F,OAAOsO,kBAAiC,IAAb9W,EAAgB,CACpD,IAAI6+B,GAAiB,EAErBzvB,EAAOtK,GAAGkP,GAAatR,cAAc,WACnC,IAAIm8B,GACC3wB,IAAUA,EAAOmK,UAAtB,CAEAwmB,GAAiB,EACjB3wB,EAAOyJ,WAAY,EAEnB,IADA,IAAImnB,EAAgB,CAAC,sBAAuB,iBACnCliC,EAAI,EAAGA,EAAIkiC,EAAcjiC,OAAQD,GAAK,EAC7C+R,EAAWzM,QAAQ48B,EAAcliC,UAsDvCkkC,EAAY,CACd9pB,aAAc,WAcZ,IAbA,IAAI9I,EAAS3T,KACT0kC,EAAc/wB,EAAOF,MACrBkxB,EAAehxB,EAAOD,OACtBmB,EAASlB,EAAOkB,OAChBT,EAAaT,EAAOS,WACpBa,EAAkBtB,EAAOsB,gBACzBhH,EAAS0F,EAAO1F,OAAOu4B,gBACvBzyB,EAAeJ,EAAOI,eACtB1O,EAAYsO,EAAOmG,UACnB2sB,EAAS1yB,EAA6B2wB,EAAc,EAA3Br/B,EAA8Cs/B,EAAe,EAA5Bt/B,EAC1DqhC,EAAS3yB,EAAe9F,EAAOy4B,QAAUz4B,EAAOy4B,OAChD5sB,EAAY7L,EAAO04B,MAEdtkC,EAAI,EAAGC,EAASuS,EAAOvS,OAAQD,EAAIC,EAAQD,GAAK,EAAG,CAC1D,IAAI4uB,EAAWpc,EAAOtK,GAAGlI,GACrBuT,EAAYX,EAAgB5S,GAE5BukC,GAAqBH,EADPxV,EAAS,GAAGvX,kBACmB9D,EAAY,GAAMA,EAAa3H,EAAO44B,SAEnFT,EAAUryB,EAAe2yB,EAASE,EAAmB,EACrDP,EAAUtyB,EAAe,EAAI2yB,EAASE,EAEtCE,GAAchtB,EAAY3D,KAAK8B,IAAI2uB,GAEnClJ,EAAa3pB,EAAe,EAAI9F,EAAO84B,QAAU,EACjDtJ,EAAa1pB,EAAe9F,EAAO84B,QAAU,EAAqB,EAGlE5wB,KAAK8B,IAAIwlB,GAAc,OAASA,EAAa,GAC7CtnB,KAAK8B,IAAIylB,GAAc,OAASA,EAAa,GAC7CvnB,KAAK8B,IAAI6uB,GAAc,OAASA,EAAa,GAC7C3wB,KAAK8B,IAAImuB,GAAW,OAASA,EAAU,GACvCjwB,KAAK8B,IAAIouB,GAAW,OAASA,EAAU,GAE3C,IAAIW,EAAiB,eAAiBvJ,EAAa,MAAQC,EAAa,MAAQoJ,EAAa,gBAAkBT,EAAU,gBAAkBD,EAAU,OAIrJ,GAFAnV,EAAS5rB,UAAU2hC,GACnB/V,EAAS,GAAGhwB,MAAMqlC,OAAmD,EAAzCnwB,KAAK8B,IAAI9B,KAAK6uB,MAAM4B,IAC5C34B,EAAOi3B,aAAc,CAEvB,IAAI+B,EAAkBlzB,EAAekd,EAAStlB,KAAK,6BAA+BslB,EAAStlB,KAAK,4BAC5Fu7B,EAAiBnzB,EAAekd,EAAStlB,KAAK,8BAAgCslB,EAAStlB,KAAK,+BACjE,IAA3Bs7B,EAAgB3kC,SAClB2kC,EAAkB1kC,EAAG,oCAAuCwR,EAAe,OAAS,OAAS,YAC7Fkd,EAASxmB,OAAOw8B,IAEY,IAA1BC,EAAe5kC,SACjB4kC,EAAiB3kC,EAAG,oCAAuCwR,EAAe,QAAU,UAAY,YAChGkd,EAASxmB,OAAOy8B,IAEdD,EAAgB3kC,SAAU2kC,EAAgB,GAAGhmC,MAAM+3B,QAA6B,EAAnB4N,EAAuBA,EAAmB,GACvGM,EAAe5kC,SAAU4kC,EAAe,GAAGjmC,MAAM+3B,QAAgC,GAApB4N,GAAyBA,EAAmB,KAK7Gv3B,GAAQK,eAAiBL,GAAQQ,yBAC1BuE,EAAW,GAAGnT,MACpBkmC,kBAAoBV,EAAS,WAGpCjtB,cAAe,SAAuB/T,GACvBzF,KACN6U,OACJrP,WAAWC,GACXkG,KAAK,gHACLnG,WAAWC,KAgDd2hC,EAAS,CACX3kB,KAAM,WACJ,IAAI9O,EAAS3T,KAETqnC,EADM1zB,EAAO1F,OACMq5B,OACnBt2B,EAAc2C,EAAOjF,YACrB24B,EAAa1zB,kBAAkB3C,GACjC2C,EAAO2zB,OAAO3zB,OAAS0zB,EAAa1zB,OACpCrH,GAAMqC,OAAOgF,EAAO2zB,OAAO3zB,OAAO2W,eAAgB,CAChDrR,qBAAqB,EACrBqD,qBAAqB,IAEvBhQ,GAAMqC,OAAOgF,EAAO2zB,OAAO3zB,OAAO1F,OAAQ,CACxCgL,qBAAqB,EACrBqD,qBAAqB,KAEdhQ,GAAMkC,SAAS64B,EAAa1zB,UACrCA,EAAO2zB,OAAO3zB,OAAS,IAAI3C,EAAY1E,GAAMqC,OAAO,GAAI04B,EAAa1zB,OAAQ,CAC3EuF,uBAAuB,EACvBD,qBAAqB,EACrBqD,qBAAqB,KAEvB3I,EAAO2zB,OAAOC,eAAgB,GAEhC5zB,EAAO2zB,OAAO3zB,OAAOC,IAAIjQ,SAASgQ,EAAO1F,OAAOq5B,OAAOE,sBACvD7zB,EAAO2zB,OAAO3zB,OAAO/N,GAAG,MAAO+N,EAAO2zB,OAAOG,eAE/CA,aAAc,WACZ,IAAI9zB,EAAS3T,KACT0nC,EAAe/zB,EAAO2zB,OAAO3zB,OACjC,GAAK+zB,EAAL,CACA,IAAIrrB,EAAeqrB,EAAarrB,aAC5BD,EAAesrB,EAAatrB,aAChC,KAAIA,GAAgB7Z,EAAE6Z,GAAcjY,SAASwP,EAAO1F,OAAOq5B,OAAOK,wBAC9D,MAAOtrB,GAAX,CACA,IAAI2C,EAMJ,GAJEA,EADE0oB,EAAaz5B,OAAOkN,KACPlH,SAAS1R,EAAEmlC,EAAatrB,cAAc7X,KAAK,2BAA4B,IAEvE8X,EAEb1I,EAAO1F,OAAOkN,KAAM,CACtB,IAAIysB,EAAej0B,EAAO8F,YACtB9F,EAAOkB,OAAOtK,GAAGq9B,GAAczjC,SAASwP,EAAO1F,OAAOmN,uBACxDzH,EAAOwK,UAEPxK,EAAOyK,YAAczK,EAAOS,WAAW,GAAGjL,WAC1Cy+B,EAAej0B,EAAO8F,aAExB,IAAI+E,EAAY7K,EAAOkB,OAAOtK,GAAGq9B,GAAct8B,QAAS,6BAAgC0T,EAAe,MAAQzU,GAAG,GAAGH,QACjH4E,EAAY2E,EAAOkB,OAAOtK,GAAGq9B,GAAc18B,QAAS,6BAAgC8T,EAAe,MAAQzU,GAAG,GAAGH,QAC7E4U,OAAf,IAAdR,EAA4CxP,OACzB,IAAdA,EAA4CwP,EACnDxP,EAAY44B,EAAeA,EAAeppB,EAA4BxP,EACzDwP,EAExB7K,EAAO0J,QAAQ2B,MAEjBzL,OAAQ,SAAgBs0B,GACtB,IAAIl0B,EAAS3T,KACT0nC,EAAe/zB,EAAO2zB,OAAO3zB,OACjC,GAAK+zB,EAAL,CAEA,IAAIpxB,EAAsD,SAAtCoxB,EAAaz5B,OAAOqI,cACpCoxB,EAAa3oB,uBACb2oB,EAAaz5B,OAAOqI,cAExB,GAAI3C,EAAOsH,YAAcysB,EAAazsB,UAAW,CAC/C,IACI6sB,EADAC,EAAqBL,EAAajuB,YAEtC,GAAIiuB,EAAaz5B,OAAOkN,KAAM,CACxBusB,EAAa7yB,OAAOtK,GAAGw9B,GAAoB5jC,SAASujC,EAAaz5B,OAAOmN,uBAC1EssB,EAAavpB,UAEbupB,EAAatpB,YAAcspB,EAAatzB,WAAW,GAAGjL,WACtD4+B,EAAqBL,EAAajuB,aAGpC,IAAIuuB,EAAkBN,EAAa7yB,OAAOtK,GAAGw9B,GAAoBz8B,QAAS,6BAAiCqI,EAAgB,UAAI,MAAQpJ,GAAG,GAAGH,QACzI69B,EAAkBP,EAAa7yB,OAAOtK,GAAGw9B,GAAoB78B,QAAS,6BAAiCyI,EAAgB,UAAI,MAAQpJ,GAAG,GAAGH,QAC/F09B,OAAf,IAApBE,EAAoDC,OAC3B,IAApBA,EAAoDD,EAC3DC,EAAkBF,GAAuBA,EAAqBC,EAAoCD,EAClGE,EAAkBF,EAAqBA,EAAqBC,EAAoCC,EACjFD,OAExBF,EAAiBn0B,EAAOsH,UAEtBysB,EAAaztB,qBAAqBnX,QAAQglC,GAAkB,IAC1DJ,EAAaz5B,OAAO+J,eAEpB8vB,EADmBC,EAAjBD,EACeA,EAAiB3xB,KAAKC,MAAME,EAAgB,GAAK,EAEjDwxB,EAAiB3xB,KAAKC,MAAME,EAAgB,GAAK,EAE1CyxB,EAAjBD,IACTA,EAAiBA,EAAiBxxB,EAAgB,GAEpDoxB,EAAarqB,QAAQyqB,EAAgBD,EAAU,OAAI9gC,IAKvD,IAAImhC,EAAmB,EACnBC,EAAmBx0B,EAAO1F,OAAOq5B,OAAOK,sBAO5C,GALkC,EAA9Bh0B,EAAO1F,OAAOqI,gBAAsB3C,EAAO1F,OAAO+J,iBACpDkwB,EAAmBv0B,EAAO1F,OAAOqI,eAGnCoxB,EAAa7yB,OAAO5Q,YAAYkkC,GAC5BT,EAAaz5B,OAAOkN,KACtB,IAAK,IAAI9Y,EAAI,EAAGA,EAAI6lC,EAAkB7lC,GAAK,EACzCqlC,EAAatzB,WAAWrT,SAAU,8BAAiC4S,EAAOsH,UAAY5Y,GAAK,MAAQsB,SAASwkC,QAG9G,IAAK,IAAI9vB,EAAM,EAAGA,EAAM6vB,EAAkB7vB,GAAO,EAC/CqvB,EAAa7yB,OAAOtK,GAAGoJ,EAAOsH,UAAY5C,GAAK1U,SAASwkC,MAyE5D/2B,EAAa,CACfyc,EACAC,EACAE,EACAE,EACAsB,EACA6B,EACAuB,EAtoGiB,CACjB5f,KAAM,aACN/E,OAAQ,CACNqmB,WAAY,CACV3f,SAAS,EACT4f,gBAAgB,EAChBI,QAAQ,EACRD,aAAa,EACbE,YAAa,EACbM,aAAc,cAGlBtiB,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnB2gB,WAAY,CACV3f,SAAS,EACT+d,OAAQG,EAAWH,OAAOhgB,KAAKiB,GAC/Bgf,QAASE,EAAWF,QAAQjgB,KAAKiB,GACjC8d,OAAQoB,EAAWpB,OAAO/e,KAAKiB,GAC/BwgB,iBAAkBtB,EAAWsB,iBAAiBzhB,KAAKiB,GACnD0gB,iBAAkBxB,EAAWwB,iBAAiB3hB,KAAKiB,GACnDmf,eAAgBxmB,GAAMM,UAI5BhH,GAAI,CACF6c,KAAM,WACSziB,KACFiO,OAAOqmB,WAAW3f,SADhB3U,KACkCs0B,WAAW5B,UAE5DlF,QAAS,WACMxtB,KACFs0B,WAAW3f,SADT3U,KAC2Bs0B,WAAW3B,aAyGtC,CACjB3f,KAAM,aACN/E,OAAQ,CACN+c,WAAY,CACV0K,OAAQ,KACRC,OAAQ,KAERyS,aAAa,EACb9S,cAAe,yBACfiD,YAAa,uBACbhD,UAAW,uBAGf3iB,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnBqX,WAAY,CACVvI,KAAM0S,EAAW1S,KAAK/P,KAAKiB,GAC3BJ,OAAQ4hB,EAAW5hB,OAAOb,KAAKiB,GAC/B6Z,QAAS2H,EAAW3H,QAAQ9a,KAAKiB,GACjC8hB,YAAaN,EAAWM,YAAY/iB,KAAKiB,GACzC6hB,YAAaL,EAAWK,YAAY9iB,KAAKiB,OAI/C/N,GAAI,CACF6c,KAAM,WACSziB,KACNgrB,WAAWvI,OADLziB,KAENgrB,WAAWzX,UAEpB80B,OAAQ,WACOroC,KACNgrB,WAAWzX,UAEpB+0B,SAAU,WACKtoC,KACNgrB,WAAWzX,UAEpBia,QAAS,WACMxtB,KACNgrB,WAAWwC,WAEpBiU,MAAO,SAAep7B,GACpB,IASMkiC,EATF50B,EAAS3T,KACT2vB,EAAMhc,EAAOqX,WACboK,EAAUzF,EAAIyF,QACdC,EAAU1F,EAAI0F,SAEhB1hB,EAAO1F,OAAO+c,WAAWod,aACrB7lC,EAAE8D,EAAEC,QAAQI,GAAG2uB,IACf9yB,EAAE8D,EAAEC,QAAQI,GAAG0uB,KAGfA,EACFmT,EAAWnT,EAAQjxB,SAASwP,EAAO1F,OAAO+c,WAAWuN,aAC5ClD,IACTkT,EAAWlT,EAAQlxB,SAASwP,EAAO1F,OAAO+c,WAAWuN,eAEtC,IAAbgQ,EACF50B,EAAO/B,KAAK,iBAAkB+B,GAE9BA,EAAO/B,KAAK,iBAAkB+B,GAE5ByhB,GACFA,EAAQ/wB,YAAYsP,EAAO1F,OAAO+c,WAAWuN,aAE3ClD,GACFA,EAAQhxB,YAAYsP,EAAO1F,OAAO+c,WAAWuN,iBAmPpC,CACjBvlB,KAAM,aACN/E,OAAQ,CACN4nB,WAAY,CACV3wB,GAAI,KACJsjC,cAAe,OACfrQ,WAAW,EACXiQ,aAAa,EACbxQ,aAAc,KACdK,kBAAmB,KACnBH,eAAgB,KAChBN,aAAc,KACdJ,qBAAqB,EACrBxR,KAAM,UACNyQ,gBAAgB,EAChBE,mBAAoB,EACpBU,sBAAuB,SAAUwR,GAAU,OAAOA,GAClDvR,oBAAqB,SAAUuR,GAAU,OAAOA,GAChD5Q,YAAa,2BACbjB,kBAAmB,kCACnByB,cAAe,qBACfN,aAAc,4BACdC,WAAY,0BACZO,YAAa,2BACbL,qBAAsB,qCACtBI,yBAA0B,yCAC1BF,eAAgB,8BAChB7C,UAAW,2BAGf3iB,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnBkiB,WAAY,CACVpT,KAAMmT,EAAWnT,KAAK/P,KAAKiB,GAC3B8jB,OAAQ7B,EAAW6B,OAAO/kB,KAAKiB,GAC/BJ,OAAQqiB,EAAWriB,OAAOb,KAAKiB,GAC/B6Z,QAASoI,EAAWpI,QAAQ9a,KAAKiB,GACjC6iB,mBAAoB,MAI1B5wB,GAAI,CACF6c,KAAM,WACSziB,KACN61B,WAAWpT,OADLziB,KAEN61B,WAAW4B,SAFLz3B,KAGN61B,WAAWtiB,UAEpBm1B,kBAAmB,WACJ1oC,KACFiO,OAAOkN,KADLnb,KAEJ61B,WAAWtiB,cACmB,IAH1BvT,KAGY8Y,WAHZ9Y,KAIJ61B,WAAWtiB,UAGtBo1B,gBAAiB,WACF3oC,KACDiO,OAAOkN,MADNnb,KAEJ61B,WAAWtiB,UAGtBq1B,mBAAoB,WACL5oC,KACFiO,OAAOkN,OADLnb,KAEJ61B,WAAW4B,SAFPz3B,KAGJ61B,WAAWtiB,WAGtBs1B,qBAAsB,WACP7oC,KACDiO,OAAOkN,OADNnb,KAEJ61B,WAAW4B,SAFPz3B,KAGJ61B,WAAWtiB,WAGtBia,QAAS,WACMxtB,KACN61B,WAAWrI,WAEpBiU,MAAO,SAAep7B,GACpB,IAAIsN,EAAS3T,KAEX2T,EAAO1F,OAAO4nB,WAAW3wB,IACtByO,EAAO1F,OAAO4nB,WAAWuS,aACM,EAA/Bz0B,EAAOkiB,WAAWjiB,IAAItR,SACrBC,EAAE8D,EAAEC,QAAQnC,SAASwP,EAAO1F,OAAO4nB,WAAWgC,gBAGjC,IADFlkB,EAAOkiB,WAAWjiB,IAAIzP,SAASwP,EAAO1F,OAAO4nB,WAAW0C,aAErE5kB,EAAO/B,KAAK,iBAAkB+B,GAE9BA,EAAO/B,KAAK,iBAAkB+B,GAEhCA,EAAOkiB,WAAWjiB,IAAIvP,YAAYsP,EAAO1F,OAAO4nB,WAAW0C,iBAgRjD,CAChBvlB,KAAM,YACN/E,OAAQ,CACNwqB,UAAW,CACTvzB,GAAI,KACJwzB,SAAU,OACVK,MAAM,EACNmB,WAAW,EACXN,eAAe,EACfrE,UAAW,wBACXuT,UAAW,0BAGfl2B,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnB8kB,UAAW,CACThW,KAAM+V,EAAU/V,KAAK/P,KAAKiB,GAC1B6Z,QAASgL,EAAUhL,QAAQ9a,KAAKiB,GAChCH,WAAYglB,EAAUhlB,WAAWd,KAAKiB,GACtC8I,aAAc+b,EAAU/b,aAAa/J,KAAKiB,GAC1C6F,cAAegf,EAAUhf,cAAc9G,KAAKiB,GAC5CkmB,gBAAiBrB,EAAUqB,gBAAgBnnB,KAAKiB,GAChDomB,iBAAkBvB,EAAUuB,iBAAiBrnB,KAAKiB,GAClDylB,gBAAiBZ,EAAUY,gBAAgB1mB,KAAKiB,GAChD6lB,YAAahB,EAAUgB,YAAY9mB,KAAKiB,GACxC+lB,WAAYlB,EAAUkB,WAAWhnB,KAAKiB,GACtCgmB,UAAWnB,EAAUmB,UAAUjnB,KAAKiB,GACpCoS,WAAW,EACX8O,QAAS,KACT4E,YAAa,SAInB7zB,GAAI,CACF6c,KAAM,WACSziB,KACNy4B,UAAUhW,OADJziB,KAENy4B,UAAUjlB,aAFJxT,KAGNy4B,UAAUhc,gBAEnBlJ,OAAQ,WACOvT,KACNy4B,UAAUjlB,cAEnB2a,OAAQ,WACOnuB,KACNy4B,UAAUjlB,cAEnBqb,eAAgB,WACD7uB,KACNy4B,UAAUjlB,cAEnBiJ,aAAc,WACCzc,KACNy4B,UAAUhc,gBAEnBjD,cAAe,SAAuB/T,GACvBzF,KACNy4B,UAAUjf,cAAc/T,IAEjC+nB,QAAS,WACMxtB,KACNy4B,UAAUjL,aAyFN,CACfxa,KAAM,WACN/E,OAAQ,CACNusB,SAAU,CACR7lB,SAAS,IAGb/B,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnBw6B,SAAU,CACRJ,aAAcD,EAASC,aAAa1nB,KAH3B1S,MAITyc,aAAc0d,EAAS1d,aAAa/J,KAJ3B1S,MAKTwZ,cAAe2gB,EAAS3gB,cAAc9G,KAL7B1S,UASf4F,GAAI,CACF0rB,WAAY,WACGtxB,KACDiO,OAAOusB,SAAS7lB,UADf3U,KAENiO,OAAOgL,qBAAsB,EAFvBjZ,KAGNsqB,eAAerR,qBAAsB,IAE9CwJ,KAAM,WACSziB,KACDiO,OAAOusB,SAAS7lB,SADf3U,KAENw6B,SAAS/d,gBAElBA,aAAc,WACCzc,KACDiO,OAAOusB,SAAS7lB,SADf3U,KAENw6B,SAAS/d,gBAElBjD,cAAe,SAAuB/T,GACvBzF,KACDiO,OAAOusB,SAAS7lB,SADf3U,KAENw6B,SAAShhB,cAAc/T,MAwavB,CACXuN,KAAM,OACN/E,OAAQ,CACNktB,KAAM,CACJxmB,SAAS,EACT+mB,SAAU,EACVI,SAAU,EACVx3B,QAAQ,EACRykC,eAAgB,wBAChBC,iBAAkB,wBAGtBp2B,OAAQ,WACN,IAAIe,EAAS3T,KACTm7B,EAAO,CACTxmB,SAAS,EACT0iB,MAAO,EACPkD,aAAc,EACdoB,WAAW,EACXP,QAAS,CACPnK,cAAUlqB,EACVm1B,gBAAYn1B,EACZo1B,iBAAap1B,EACby0B,cAAUz0B,EACV00B,kBAAc10B,EACd20B,SAAU,GAEZ7P,MAAO,CACL9F,eAAWhf,EACXif,aAASjf,EACTmf,cAAUnf,EACVsf,cAAUtf,EACVu1B,UAAMv1B,EACNy1B,UAAMz1B,EACNw1B,UAAMx1B,EACN01B,UAAM11B,EACN0M,WAAO1M,EACP2M,YAAQ3M,EACRwf,YAAQxf,EACRyf,YAAQzf,EACRk1B,aAAc,GACdS,eAAgB,IAElB5T,SAAU,CACRnM,OAAG5V,EACH6V,OAAG7V,EACH41B,mBAAe51B,EACf61B,mBAAe71B,EACf81B,cAAU91B,IAId,+HAAiI5D,MAAM,KAAK+I,QAAQ,SAAUC,GAC5JgvB,EAAKhvB,GAAcyuB,EAAKzuB,GAAYuG,KAAKiB,KAE3CrH,GAAMqC,OAAOgF,EAAQ,CACnBwnB,KAAMA,IAGR,IAAI9D,EAAQ,EACZrrB,OAAOsE,eAAeqD,EAAOwnB,KAAM,QAAS,CAC1C5qB,IAAK,WACH,OAAO8mB,GAETxkB,IAAK,SAAapO,GAChB,GAAI4yB,IAAU5yB,EAAO,CACnB,IAAI+mB,EAAU7X,EAAOwnB,KAAKC,QAAQI,SAAW7nB,EAAOwnB,KAAKC,QAAQI,SAAS,QAAKz0B,EAC3EwmB,EAAU5Z,EAAOwnB,KAAKC,QAAQnK,SAAWtd,EAAOwnB,KAAKC,QAAQnK,SAAS,QAAKlqB,EAC/E4M,EAAO/B,KAAK,aAAcnN,EAAO+mB,EAAS+B,GAE5C8J,EAAQ5yB,MAIdmB,GAAI,CACF6c,KAAM,WACSziB,KACFiO,OAAOktB,KAAKxmB,SADV3U,KAEJm7B,KAAKzI,UAGhBlF,QAAS,WACMxtB,KACNm7B,KAAKxI,WAEdsW,WAAY,SAAoB5iC,GACjBrG,KACDm7B,KAAKxmB,SADJ3U,KAENm7B,KAAK5V,aAAalf,IAE3B6iC,SAAU,SAAkB7iC,GACbrG,KACDm7B,KAAKxmB,SADJ3U,KAENm7B,KAAK/S,WAAW/hB,IAEzB8iC,UAAW,SAAmB9iC,GACfrG,KACFiO,OAAOktB,KAAKxmB,SADV3U,KAC4Bm7B,KAAKxmB,SADjC3U,KACmDiO,OAAOktB,KAAK72B,QAD/DtE,KAEJm7B,KAAK72B,OAAO+B,IAGvB8B,cAAe,WACAnI,KACFm7B,KAAKxmB,SADH3U,KACqBiO,OAAOktB,KAAKxmB,SADjC3U,KAEJm7B,KAAKiC,qBA4IP,CACXpqB,KAAM,OACN/E,OAAQ,CACNyiB,KAAM,CACJ/b,SAAS,EACTqqB,cAAc,EACdC,mBAAoB,EACpBmK,uBAAuB,EAEvB/K,aAAc,cACdE,aAAc,sBACdD,YAAa,qBACb+K,eAAgB,0BAGpBz2B,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnB0wB,KAAM,CACJoO,oBAAoB,EACpBnO,KAAMsN,EAAKtN,KAAKje,KAJP1S,MAKTk+B,YAAaD,EAAKC,YAAYxrB,KALrB1S,UASf4F,GAAI,CACF0rB,WAAY,WACGtxB,KACFiO,OAAOyiB,KAAK/b,SADV3U,KAC4BiO,OAAOsW,gBADnCvkB,KAEJiO,OAAOsW,eAAgB,IAGlC9B,KAAM,WACSziB,KACFiO,OAAOyiB,KAAK/b,UADV3U,KAC6BiO,OAAOkN,MAAuC,IAD3Enb,KACmDiO,OAAOwP,cAD1Dzd,KAEJ0wB,KAAKC,QAGhB2Y,OAAQ,WACOtpC,KACFiO,OAAOoU,WADLriB,KACyBiO,OAAOiV,gBADhCljB,KAEJ0wB,KAAKC,QAGhBxC,OAAQ,WACOnuB,KACFiO,OAAOyiB,KAAK/b,SADV3U,KAEJ0wB,KAAKC,QAGhB4Y,kBAAmB,WACJvpC,KACFiO,OAAOyiB,KAAK/b,SADV3U,KAEJ0wB,KAAKC,QAGhB5T,gBAAiB,WACf,IAAIpJ,EAAS3T,KACT2T,EAAO1F,OAAOyiB,KAAK/b,UACjBhB,EAAO1F,OAAOyiB,KAAK0Y,wBAA2Bz1B,EAAO1F,OAAOyiB,KAAK0Y,wBAA0Bz1B,EAAO+c,KAAKoO,qBACzGnrB,EAAO+c,KAAKC,QAIlBxoB,cAAe,WACAnI,KACFiO,OAAOyiB,KAAK/b,UADV3U,KAC6BiO,OAAOyiB,KAAK0Y,uBADzCppC,KAEJ0wB,KAAKC,UAqID,CACjB3d,KAAM,aACN/E,OAAQ,CACN8xB,WAAY,CACVM,aAASt5B,EACTy5B,SAAS,EACTD,GAAI,UAGR3tB,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnBosB,WAAY,CACVM,QAAS1sB,EAAO1F,OAAO8xB,WAAWM,QAClCR,uBAAwBR,EAAWQ,uBAAuBntB,KAAKiB,GAC/D8I,aAAc4iB,EAAW5iB,aAAa/J,KAAKiB,GAC3C6F,cAAe6lB,EAAW7lB,cAAc9G,KAAKiB,OAInD/N,GAAI,CACF2N,OAAQ,WACOvT,KACD+/B,WAAWM,SADVrgC,KAEF+/B,WAAWC,SAFThgC,KAGJ+/B,WAAWC,YAASj5B,SAHhB/G,KAIG+/B,WAAWC,SAG7B7R,OAAQ,WACOnuB,KACD+/B,WAAWM,SADVrgC,KAEF+/B,WAAWC,SAFThgC,KAGJ+/B,WAAWC,YAASj5B,SAHhB/G,KAIG+/B,WAAWC,SAG7BnR,eAAgB,WACD7uB,KACD+/B,WAAWM,SADVrgC,KAEF+/B,WAAWC,SAFThgC,KAGJ+/B,WAAWC,YAASj5B,SAHhB/G,KAIG+/B,WAAWC,SAG7BvjB,aAAc,SAAsB3C,EAAW4C,GAChC1c,KACD+/B,WAAWM,SADVrgC,KAEN+/B,WAAWtjB,aAAa3C,EAAW4C,IAE5ClD,cAAe,SAAuB/T,EAAUiX,GACjC1c,KACD+/B,WAAWM,SADVrgC,KAEN+/B,WAAWvmB,cAAc/T,EAAUiX,MA2JrC,CACT1J,KAAM,OACN/E,OAAQ,CACNyyB,KAAM,CACJ/rB,SAAS,EACT60B,kBAAmB,sBACnBhI,iBAAkB,iBAClBF,iBAAkB,aAClBC,kBAAmB,0BACnBF,iBAAkB,yBAClBY,wBAAyB,0BAG7BrvB,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnB+sB,KAAM,CACJkB,WAAYr/B,EAAG,gBAAoBoR,EAAO1F,OAAOyyB,KAAsB,kBAAI,yDAG/E10B,OAAOC,KAAKy0B,GAAMx0B,QAAQ,SAAUC,GAClCwH,EAAO+sB,KAAKv0B,GAAcu0B,EAAKv0B,GAAYuG,KAAKiB,MAGpD/N,GAAI,CACF6c,KAAM,WACSziB,KACDiO,OAAOyyB,KAAK/rB,UADX3U,KAEN0gC,KAAKje,OAFCziB,KAGN0gC,KAAKmB,qBAEdwG,OAAQ,WACOroC,KACDiO,OAAOyyB,KAAK/rB,SADX3U,KAEN0gC,KAAKmB,oBAEdyG,SAAU,WACKtoC,KACDiO,OAAOyyB,KAAK/rB,SADX3U,KAEN0gC,KAAKmB,oBAEd4H,iBAAkB,WACHzpC,KACDiO,OAAOyyB,KAAK/rB,SADX3U,KAEN0gC,KAAKoB,oBAEdtU,QAAS,WACMxtB,KACDiO,OAAOyyB,KAAK/rB,SADX3U,KAEN0gC,KAAKlT,aAoFF,CACdxa,KAAM,UACN/E,OAAQ,CACNvM,QAAS,CACPiT,SAAS,EACT6tB,cAAc,EACdv9B,IAAK,WAGT2N,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnBjS,QAAS,CACP+gB,KAAMyf,EAAQzf,KAAK/P,KAAKiB,GACxBkvB,WAAYX,EAAQW,WAAWnwB,KAAKiB,GACpC8uB,mBAAoBP,EAAQO,mBAAmB/vB,KAAKiB,GACpD4uB,cAAeL,EAAQK,cAAc7vB,KAAKiB,GAC1C6Z,QAAS0U,EAAQ1U,QAAQ9a,KAAKiB,OAIpC/N,GAAI,CACF6c,KAAM,WACSziB,KACFiO,OAAOvM,QAAQiT,SADb3U,KAEJ0B,QAAQ+gB,QAGnB+K,QAAS,WACMxtB,KACFiO,OAAOvM,QAAQiT,SADb3U,KAEJ0B,QAAQ8rB,WAGnBrlB,cAAe,WACAnI,KACF0B,QAAQgc,aADN1d,KAEJ0B,QAAQmhC,WAFJ7iC,KAEsBiO,OAAOvM,QAAQuD,IAFrCjF,KAEiDyZ,gBAuD7C,CACrBzG,KAAM,kBACN/E,OAAQ,CACNm0B,eAAgB,CACdztB,SAAS,EACT6tB,cAAc,EACdc,YAAY,IAGhB1wB,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnByuB,eAAgB,CACd1kB,aAAa,EACb+E,KAAMygB,EAAezgB,KAAK/P,KAAKiB,GAC/B6Z,QAAS0V,EAAe1V,QAAQ9a,KAAKiB,GACrC0vB,QAASH,EAAeG,QAAQ3wB,KAAKiB,GACrCwvB,YAAaD,EAAeC,YAAYzwB,KAAKiB,OAInD/N,GAAI,CACF6c,KAAM,WACSziB,KACFiO,OAAOm0B,eAAeztB,SADpB3U,KAEJoiC,eAAe3f,QAG1B+K,QAAS,WACMxtB,KACFiO,OAAOm0B,eAAeztB,SADpB3U,KAEJoiC,eAAe5U,WAG1BrlB,cAAe,WACAnI,KACFoiC,eAAe1kB,aADb1d,KAEJoiC,eAAeiB,aAoFb,CACfrwB,KAAM,WACN/E,OAAQ,CACN6mB,SAAU,CACRngB,SAAS,EACThI,MAAO,IACPo3B,mBAAmB,EACnB2F,sBAAsB,EACtB/F,iBAAiB,EACjBD,kBAAkB,IAGtB9wB,OAAQ,WACN,IAAIe,EAAS3T,KACbsM,GAAMqC,OAAOgF,EAAQ,CACnBmhB,SAAU,CACR8O,SAAS,EACTE,QAAQ,EACRN,IAAKD,EAASC,IAAI9wB,KAAKiB,GACvBgW,MAAO4Z,EAAS5Z,MAAMjX,KAAKiB,GAC3BqhB,KAAMuO,EAASvO,KAAKtiB,KAAKiB,GACzBkwB,MAAON,EAASM,MAAMnxB,KAAKiB,GAC3BypB,gBAAiB,SAAyB/2B,GACnCsN,IAAUA,EAAOmK,WAAcnK,EAAOS,YACvC/N,EAAEC,SAAWtG,OACjB2T,EAAOS,WAAW,GAAG/T,oBAAoB,gBAAiBsT,EAAOmhB,SAASsI,iBAC1EzpB,EAAOS,WAAW,GAAG/T,oBAAoB,sBAAuBsT,EAAOmhB,SAASsI,iBAChFzpB,EAAOmhB,SAASgP,QAAS,EACpBnwB,EAAOmhB,SAAS8O,QAGnBjwB,EAAOmhB,SAAS0O,MAFhB7vB,EAAOmhB,SAASE,aAQ1BpvB,GAAI,CACF6c,KAAM,WACSziB,KACFiO,OAAO6mB,SAASngB,SADd3U,KAEJ80B,SAASnL,SAGpBggB,sBAAuB,SAA+BtwB,EAAOiE,GAC9Ctd,KACF80B,SAAS8O,UACdtmB,IAFOtd,KAEaiO,OAAO6mB,SAAS4U,qBAF7B1pC,KAGF80B,SAAS+O,MAAMxqB,GAHbrZ,KAKF80B,SAASE,SAItB4U,gBAAiB,WACF5pC,KACF80B,SAAS8O,UADP5jC,KAEAiO,OAAO6mB,SAAS4U,qBAFhB1pC,KAGF80B,SAASE,OAHPh1B,KAKF80B,SAAS+O,UAItBrW,QAAS,WACMxtB,KACF80B,SAAS8O,SADP5jC,KAEJ80B,SAASE,UAmDP,CACfhiB,KAAM,cACN/E,OAAQ,CACNm2B,WAAY,CACVC,WAAW,IAGfzxB,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnBokC,WAAY,CACV3nB,aAAcunB,EAAKvnB,aAAa/J,KAHvB1S,MAITwZ,cAAewqB,EAAKxqB,cAAc9G,KAJzB1S,UAQf4F,GAAI,CACF0rB,WAAY,WACV,IAAI3d,EAAS3T,KACb,GAA6B,SAAzB2T,EAAO1F,OAAOkK,OAAlB,CACAxE,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,QACjE,IAAIsjB,EAAkB,CACpBjb,cAAe,EACfJ,gBAAiB,EACjBgC,eAAgB,EAChBe,qBAAqB,EACrBzD,aAAc,EACd+G,kBAAkB,GAEpBjQ,GAAMqC,OAAOgF,EAAO1F,OAAQsjB,GAC5BjlB,GAAMqC,OAAOgF,EAAO2W,eAAgBiH,KAEtC9U,aAAc,WAEiB,SADhBzc,KACFiO,OAAOkK,QADLnY,KAENokC,WAAW3nB,gBAEpBjD,cAAe,SAAuB/T,GAEP,SADhBzF,KACFiO,OAAOkK,QADLnY,KAENokC,WAAW5qB,cAAc/T,MAwIrB,CACfuN,KAAM,cACN/E,OAAQ,CACN22B,WAAY,CACVM,cAAc,EACdJ,QAAQ,EACRW,aAAc,GACdK,YAAa,MAGjBlzB,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnB4kC,WAAY,CACVnoB,aAAc+nB,EAAK/nB,aAAa/J,KAHvB1S,MAITwZ,cAAegrB,EAAKhrB,cAAc9G,KAJzB1S,UAQf4F,GAAI,CACF0rB,WAAY,WACV,IAAI3d,EAAS3T,KACb,GAA6B,SAAzB2T,EAAO1F,OAAOkK,OAAlB,CACAxE,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,QACjE0F,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,MACjE,IAAIsjB,EAAkB,CACpBjb,cAAe,EACfJ,gBAAiB,EACjBgC,eAAgB,EAChBe,qBAAqB,EACrBmL,gBAAiB,EACjB5O,aAAc,EACdwC,gBAAgB,EAChBuE,kBAAkB,GAEpBjQ,GAAMqC,OAAOgF,EAAO1F,OAAQsjB,GAC5BjlB,GAAMqC,OAAOgF,EAAO2W,eAAgBiH,KAEtC9U,aAAc,WAEiB,SADhBzc,KACFiO,OAAOkK,QADLnY,KAEN4kC,WAAWnoB,gBAEpBjD,cAAe,SAAuB/T,GAEP,SADhBzF,KACFiO,OAAOkK,QADLnY,KAEN4kC,WAAWprB,cAAc/T,MA+ErB,CACfuN,KAAM,cACN/E,OAAQ,CACNi4B,WAAY,CACVhB,cAAc,EACdiB,eAAe,IAGnBvzB,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnBkmC,WAAY,CACVzpB,aAAcwpB,EAAKxpB,aAAa/J,KAHvB1S,MAITwZ,cAAeysB,EAAKzsB,cAAc9G,KAJzB1S,UAQf4F,GAAI,CACF0rB,WAAY,WACV,IAAI3d,EAAS3T,KACb,GAA6B,SAAzB2T,EAAO1F,OAAOkK,OAAlB,CACAxE,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,QACjE0F,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,MACjE,IAAIsjB,EAAkB,CACpBjb,cAAe,EACfJ,gBAAiB,EACjBgC,eAAgB,EAChBe,qBAAqB,EACrBzD,aAAc,EACd+G,kBAAkB,GAEpBjQ,GAAMqC,OAAOgF,EAAO1F,OAAQsjB,GAC5BjlB,GAAMqC,OAAOgF,EAAO2W,eAAgBiH,KAEtC9U,aAAc,WAEiB,SADhBzc,KACFiO,OAAOkK,QADLnY,KAENkmC,WAAWzpB,gBAEpBjD,cAAe,SAAuB/T,GAEP,SADhBzF,KACFiO,OAAOkK,QADLnY,KAENkmC,WAAW1sB,cAAc/T,MA6EhB,CACpBuN,KAAM,mBACN/E,OAAQ,CACNu4B,gBAAiB,CACfE,OAAQ,GACRK,QAAS,EACTJ,MAAO,IACPE,SAAU,EACV3B,cAAc,IAGlBtyB,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnBwmC,gBAAiB,CACf/pB,aAAc8pB,EAAU9pB,aAAa/J,KAH5B1S,MAITwZ,cAAe+sB,EAAU/sB,cAAc9G,KAJ9B1S,UAQf4F,GAAI,CACF0rB,WAAY,WACV,IAAI3d,EAAS3T,KACgB,cAAzB2T,EAAO1F,OAAOkK,SAElBxE,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,aACjE0F,EAAOuX,WAAWjoB,KAAO0Q,EAAO1F,OAA6B,uBAAI,MAEjE0F,EAAO1F,OAAOgL,qBAAsB,EACpCtF,EAAO2W,eAAerR,qBAAsB,IAE9CwD,aAAc,WAEiB,cADhBzc,KACFiO,OAAOkK,QADLnY,KAENwmC,gBAAgB/pB,gBAEzBjD,cAAe,SAAuB/T,GAEP,cADhBzF,KACFiO,OAAOkK,QADLnY,KAENwmC,gBAAgBhtB,cAAc/T,MA+H5B,CACbuN,KAAM,SACN/E,OAAQ,CACNq5B,OAAQ,CACN3zB,OAAQ,KACRg0B,sBAAuB,4BACvBH,qBAAsB,4BAG1B50B,OAAQ,WAENtG,GAAMqC,OADO3O,KACQ,CACnBsnC,OAAQ,CACN3zB,OAAQ,KACR8O,KAAM2kB,EAAO3kB,KAAK/P,KAJT1S,MAKTuT,OAAQ6zB,EAAO7zB,OAAOb,KALb1S,MAMTynC,aAAcL,EAAOK,aAAa/0B,KANzB1S,UAUf4F,GAAI,CACF0rB,WAAY,WACV,IAEIgW,EAFStnC,KACIiO,OACAq5B,OACZA,GAAWA,EAAO3zB,SAHV3T,KAINsnC,OAAO7kB,OAJDziB,KAKNsnC,OAAO/zB,QAAO,KAEvBs2B,YAAa,WACE7pC,KACDsnC,OAAO3zB,QADN3T,KAENsnC,OAAO/zB,UAEhBA,OAAQ,WACOvT,KACDsnC,OAAO3zB,QADN3T,KAENsnC,OAAO/zB,UAEhB4a,OAAQ,WACOnuB,KACDsnC,OAAO3zB,QADN3T,KAENsnC,OAAO/zB,UAEhBsb,eAAgB,WACD7uB,KACDsnC,OAAO3zB,QADN3T,KAENsnC,OAAO/zB,UAEhBiG,cAAe,SAAuB/T,GACpC,IACIiiC,EADS1nC,KACasnC,OAAO3zB,OAC5B+zB,GACLA,EAAaluB,cAAc/T,IAE7BqkC,cAAe,WACb,IACIpC,EADS1nC,KACasnC,OAAO3zB,OAC5B+zB,GAFQ1nC,KAGFsnC,OAAOC,eAAiBG,GACjCA,EAAala,cA0CrB,YAP0B,IAAfztB,EAAO+S,MAChB/S,EAAO+S,IAAM/S,EAAO0D,MAAMqP,IAC1B/S,EAAOgT,cAAgBhT,EAAO0D,MAAMsP,eAGtChT,EAAO+S,IAAI1B,GAEJrR","file":"swiper.min.js","sourcesContent":["/**\n * Swiper 4.5.0\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n * http://www.idangero.us/swiper/\n *\n * Copyright 2014-2019 Vladimir Kharlampidi\n *\n * Released under the MIT License\n *\n * Released on: February 22, 2019\n */\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = global || self, global.Swiper = factory());\n}(this, function () { 'use strict';\n\n /**\n * SSR Window 1.0.1\n * Better handling for window object in SSR environment\n * https://github.com/nolimits4web/ssr-window\n *\n * Copyright 2018, Vladimir Kharlampidi\n *\n * Licensed under MIT\n *\n * Released on: July 18, 2018\n */\n var doc = (typeof document === 'undefined') ? {\n body: {},\n addEventListener: function addEventListener() {},\n removeEventListener: function removeEventListener() {},\n activeElement: {\n blur: function blur() {},\n nodeName: '',\n },\n querySelector: function querySelector() {\n return null;\n },\n querySelectorAll: function querySelectorAll() {\n return [];\n },\n getElementById: function getElementById() {\n return null;\n },\n createEvent: function createEvent() {\n return {\n initEvent: function initEvent() {},\n };\n },\n createElement: function createElement() {\n return {\n children: [],\n childNodes: [],\n style: {},\n setAttribute: function setAttribute() {},\n getElementsByTagName: function getElementsByTagName() {\n return [];\n },\n };\n },\n location: { hash: '' },\n } : document; // eslint-disable-line\n\n var win = (typeof window === 'undefined') ? {\n document: doc,\n navigator: {\n userAgent: '',\n },\n location: {},\n history: {},\n CustomEvent: function CustomEvent() {\n return this;\n },\n addEventListener: function addEventListener() {},\n removeEventListener: function removeEventListener() {},\n getComputedStyle: function getComputedStyle() {\n return {\n getPropertyValue: function getPropertyValue() {\n return '';\n },\n };\n },\n Image: function Image() {},\n Date: function Date() {},\n screen: {},\n setTimeout: function setTimeout() {},\n clearTimeout: function clearTimeout() {},\n } : window; // eslint-disable-line\n\n /**\n * Dom7 2.1.3\n * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API\n * http://framework7.io/docs/dom.html\n *\n * Copyright 2019, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n *\n * Licensed under MIT\n *\n * Released on: February 11, 2019\n */\n\n var Dom7 = function Dom7(arr) {\n var self = this;\n // Create array-like object\n for (var i = 0; i < arr.length; i += 1) {\n self[i] = arr[i];\n }\n self.length = arr.length;\n // Return collection with methods\n return this;\n };\n\n function $(selector, context) {\n var arr = [];\n var i = 0;\n if (selector && !context) {\n if (selector instanceof Dom7) {\n return selector;\n }\n }\n if (selector) {\n // String\n if (typeof selector === 'string') {\n var els;\n var tempParent;\n var html = selector.trim();\n if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {\n var toCreate = 'div';\n if (html.indexOf(':~]/)) {\n // Pure ID selector\n els = [doc.getElementById(selector.trim().split('#')[1])];\n } else {\n // Other selectors\n els = (context || doc).querySelectorAll(selector.trim());\n }\n for (i = 0; i < els.length; i += 1) {\n if (els[i]) { arr.push(els[i]); }\n }\n }\n } else if (selector.nodeType || selector === win || selector === doc) {\n // Node/element\n arr.push(selector);\n } else if (selector.length > 0 && selector[0].nodeType) {\n // Array of elements or instance of Dom\n for (i = 0; i < selector.length; i += 1) {\n arr.push(selector[i]);\n }\n }\n }\n return new Dom7(arr);\n }\n\n $.fn = Dom7.prototype;\n $.Class = Dom7;\n $.Dom7 = Dom7;\n\n function unique(arr) {\n var uniqueArray = [];\n for (var i = 0; i < arr.length; i += 1) {\n if (uniqueArray.indexOf(arr[i]) === -1) { uniqueArray.push(arr[i]); }\n }\n return uniqueArray;\n }\n\n // Classes and attributes\n function addClass(className) {\n if (typeof className === 'undefined') {\n return this;\n }\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i += 1) {\n for (var j = 0; j < this.length; j += 1) {\n if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.add(classes[i]); }\n }\n }\n return this;\n }\n function removeClass(className) {\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i += 1) {\n for (var j = 0; j < this.length; j += 1) {\n if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.remove(classes[i]); }\n }\n }\n return this;\n }\n function hasClass(className) {\n if (!this[0]) { return false; }\n return this[0].classList.contains(className);\n }\n function toggleClass(className) {\n var classes = className.split(' ');\n for (var i = 0; i < classes.length; i += 1) {\n for (var j = 0; j < this.length; j += 1) {\n if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.toggle(classes[i]); }\n }\n }\n return this;\n }\n function attr(attrs, value) {\n var arguments$1 = arguments;\n\n if (arguments.length === 1 && typeof attrs === 'string') {\n // Get attr\n if (this[0]) { return this[0].getAttribute(attrs); }\n return undefined;\n }\n\n // Set attrs\n for (var i = 0; i < this.length; i += 1) {\n if (arguments$1.length === 2) {\n // String\n this[i].setAttribute(attrs, value);\n } else {\n // Object\n // eslint-disable-next-line\n for (var attrName in attrs) {\n this[i][attrName] = attrs[attrName];\n this[i].setAttribute(attrName, attrs[attrName]);\n }\n }\n }\n return this;\n }\n // eslint-disable-next-line\n function removeAttr(attr) {\n for (var i = 0; i < this.length; i += 1) {\n this[i].removeAttribute(attr);\n }\n return this;\n }\n function data(key, value) {\n var el;\n if (typeof value === 'undefined') {\n el = this[0];\n // Get value\n if (el) {\n if (el.dom7ElementDataStorage && (key in el.dom7ElementDataStorage)) {\n return el.dom7ElementDataStorage[key];\n }\n\n var dataKey = el.getAttribute((\"data-\" + key));\n if (dataKey) {\n return dataKey;\n }\n return undefined;\n }\n return undefined;\n }\n\n // Set value\n for (var i = 0; i < this.length; i += 1) {\n el = this[i];\n if (!el.dom7ElementDataStorage) { el.dom7ElementDataStorage = {}; }\n el.dom7ElementDataStorage[key] = value;\n }\n return this;\n }\n // Transforms\n // eslint-disable-next-line\n function transform(transform) {\n for (var i = 0; i < this.length; i += 1) {\n var elStyle = this[i].style;\n elStyle.webkitTransform = transform;\n elStyle.transform = transform;\n }\n return this;\n }\n function transition(duration) {\n if (typeof duration !== 'string') {\n duration = duration + \"ms\"; // eslint-disable-line\n }\n for (var i = 0; i < this.length; i += 1) {\n var elStyle = this[i].style;\n elStyle.webkitTransitionDuration = duration;\n elStyle.transitionDuration = duration;\n }\n return this;\n }\n // Events\n function on() {\n var assign;\n\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n var eventType = args[0];\n var targetSelector = args[1];\n var listener = args[2];\n var capture = args[3];\n if (typeof args[1] === 'function') {\n (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]);\n targetSelector = undefined;\n }\n if (!capture) { capture = false; }\n\n function handleLiveEvent(e) {\n var target = e.target;\n if (!target) { return; }\n var eventData = e.target.dom7EventData || [];\n if (eventData.indexOf(e) < 0) {\n eventData.unshift(e);\n }\n if ($(target).is(targetSelector)) { listener.apply(target, eventData); }\n else {\n var parents = $(target).parents(); // eslint-disable-line\n for (var k = 0; k < parents.length; k += 1) {\n if ($(parents[k]).is(targetSelector)) { listener.apply(parents[k], eventData); }\n }\n }\n }\n function handleEvent(e) {\n var eventData = e && e.target ? e.target.dom7EventData || [] : [];\n if (eventData.indexOf(e) < 0) {\n eventData.unshift(e);\n }\n listener.apply(this, eventData);\n }\n var events = eventType.split(' ');\n var j;\n for (var i = 0; i < this.length; i += 1) {\n var el = this[i];\n if (!targetSelector) {\n for (j = 0; j < events.length; j += 1) {\n var event = events[j];\n if (!el.dom7Listeners) { el.dom7Listeners = {}; }\n if (!el.dom7Listeners[event]) { el.dom7Listeners[event] = []; }\n el.dom7Listeners[event].push({\n listener: listener,\n proxyListener: handleEvent,\n });\n el.addEventListener(event, handleEvent, capture);\n }\n } else {\n // Live events\n for (j = 0; j < events.length; j += 1) {\n var event$1 = events[j];\n if (!el.dom7LiveListeners) { el.dom7LiveListeners = {}; }\n if (!el.dom7LiveListeners[event$1]) { el.dom7LiveListeners[event$1] = []; }\n el.dom7LiveListeners[event$1].push({\n listener: listener,\n proxyListener: handleLiveEvent,\n });\n el.addEventListener(event$1, handleLiveEvent, capture);\n }\n }\n }\n return this;\n }\n function off() {\n var assign;\n\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n var eventType = args[0];\n var targetSelector = args[1];\n var listener = args[2];\n var capture = args[3];\n if (typeof args[1] === 'function') {\n (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]);\n targetSelector = undefined;\n }\n if (!capture) { capture = false; }\n\n var events = eventType.split(' ');\n for (var i = 0; i < events.length; i += 1) {\n var event = events[i];\n for (var j = 0; j < this.length; j += 1) {\n var el = this[j];\n var handlers = (void 0);\n if (!targetSelector && el.dom7Listeners) {\n handlers = el.dom7Listeners[event];\n } else if (targetSelector && el.dom7LiveListeners) {\n handlers = el.dom7LiveListeners[event];\n }\n if (handlers && handlers.length) {\n for (var k = handlers.length - 1; k >= 0; k -= 1) {\n var handler = handlers[k];\n if (listener && handler.listener === listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n } else if (!listener) {\n el.removeEventListener(event, handler.proxyListener, capture);\n handlers.splice(k, 1);\n }\n }\n }\n }\n }\n return this;\n }\n function trigger() {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n var events = args[0].split(' ');\n var eventData = args[1];\n for (var i = 0; i < events.length; i += 1) {\n var event = events[i];\n for (var j = 0; j < this.length; j += 1) {\n var el = this[j];\n var evt = (void 0);\n try {\n evt = new win.CustomEvent(event, {\n detail: eventData,\n bubbles: true,\n cancelable: true,\n });\n } catch (e) {\n evt = doc.createEvent('Event');\n evt.initEvent(event, true, true);\n evt.detail = eventData;\n }\n // eslint-disable-next-line\n el.dom7EventData = args.filter(function (data, dataIndex) { return dataIndex > 0; });\n el.dispatchEvent(evt);\n el.dom7EventData = [];\n delete el.dom7EventData;\n }\n }\n return this;\n }\n function transitionEnd(callback) {\n var events = ['webkitTransitionEnd', 'transitionend'];\n var dom = this;\n var i;\n function fireCallBack(e) {\n /* jshint validthis:true */\n if (e.target !== this) { return; }\n callback.call(this, e);\n for (i = 0; i < events.length; i += 1) {\n dom.off(events[i], fireCallBack);\n }\n }\n if (callback) {\n for (i = 0; i < events.length; i += 1) {\n dom.on(events[i], fireCallBack);\n }\n }\n return this;\n }\n function outerWidth(includeMargins) {\n if (this.length > 0) {\n if (includeMargins) {\n // eslint-disable-next-line\n var styles = this.styles();\n return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left'));\n }\n return this[0].offsetWidth;\n }\n return null;\n }\n function outerHeight(includeMargins) {\n if (this.length > 0) {\n if (includeMargins) {\n // eslint-disable-next-line\n var styles = this.styles();\n return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom'));\n }\n return this[0].offsetHeight;\n }\n return null;\n }\n function offset() {\n if (this.length > 0) {\n var el = this[0];\n var box = el.getBoundingClientRect();\n var body = doc.body;\n var clientTop = el.clientTop || body.clientTop || 0;\n var clientLeft = el.clientLeft || body.clientLeft || 0;\n var scrollTop = el === win ? win.scrollY : el.scrollTop;\n var scrollLeft = el === win ? win.scrollX : el.scrollLeft;\n return {\n top: (box.top + scrollTop) - clientTop,\n left: (box.left + scrollLeft) - clientLeft,\n };\n }\n\n return null;\n }\n function styles() {\n if (this[0]) { return win.getComputedStyle(this[0], null); }\n return {};\n }\n function css(props, value) {\n var i;\n if (arguments.length === 1) {\n if (typeof props === 'string') {\n if (this[0]) { return win.getComputedStyle(this[0], null).getPropertyValue(props); }\n } else {\n for (i = 0; i < this.length; i += 1) {\n // eslint-disable-next-line\n for (var prop in props) {\n this[i].style[prop] = props[prop];\n }\n }\n return this;\n }\n }\n if (arguments.length === 2 && typeof props === 'string') {\n for (i = 0; i < this.length; i += 1) {\n this[i].style[props] = value;\n }\n return this;\n }\n return this;\n }\n // Iterate over the collection passing elements to `callback`\n function each(callback) {\n // Don't bother continuing without a callback\n if (!callback) { return this; }\n // Iterate over the current collection\n for (var i = 0; i < this.length; i += 1) {\n // If the callback returns false\n if (callback.call(this[i], i, this[i]) === false) {\n // End the loop early\n return this;\n }\n }\n // Return `this` to allow chained DOM operations\n return this;\n }\n // eslint-disable-next-line\n function html(html) {\n if (typeof html === 'undefined') {\n return this[0] ? this[0].innerHTML : undefined;\n }\n\n for (var i = 0; i < this.length; i += 1) {\n this[i].innerHTML = html;\n }\n return this;\n }\n // eslint-disable-next-line\n function text(text) {\n if (typeof text === 'undefined') {\n if (this[0]) {\n return this[0].textContent.trim();\n }\n return null;\n }\n\n for (var i = 0; i < this.length; i += 1) {\n this[i].textContent = text;\n }\n return this;\n }\n function is(selector) {\n var el = this[0];\n var compareWith;\n var i;\n if (!el || typeof selector === 'undefined') { return false; }\n if (typeof selector === 'string') {\n if (el.matches) { return el.matches(selector); }\n else if (el.webkitMatchesSelector) { return el.webkitMatchesSelector(selector); }\n else if (el.msMatchesSelector) { return el.msMatchesSelector(selector); }\n\n compareWith = $(selector);\n for (i = 0; i < compareWith.length; i += 1) {\n if (compareWith[i] === el) { return true; }\n }\n return false;\n } else if (selector === doc) { return el === doc; }\n else if (selector === win) { return el === win; }\n\n if (selector.nodeType || selector instanceof Dom7) {\n compareWith = selector.nodeType ? [selector] : selector;\n for (i = 0; i < compareWith.length; i += 1) {\n if (compareWith[i] === el) { return true; }\n }\n return false;\n }\n return false;\n }\n function index() {\n var child = this[0];\n var i;\n if (child) {\n i = 0;\n // eslint-disable-next-line\n while ((child = child.previousSibling) !== null) {\n if (child.nodeType === 1) { i += 1; }\n }\n return i;\n }\n return undefined;\n }\n // eslint-disable-next-line\n function eq(index) {\n if (typeof index === 'undefined') { return this; }\n var length = this.length;\n var returnIndex;\n if (index > length - 1) {\n return new Dom7([]);\n }\n if (index < 0) {\n returnIndex = length + index;\n if (returnIndex < 0) { return new Dom7([]); }\n return new Dom7([this[returnIndex]]);\n }\n return new Dom7([this[index]]);\n }\n function append() {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n var newChild;\n\n for (var k = 0; k < args.length; k += 1) {\n newChild = args[k];\n for (var i = 0; i < this.length; i += 1) {\n if (typeof newChild === 'string') {\n var tempDiv = doc.createElement('div');\n tempDiv.innerHTML = newChild;\n while (tempDiv.firstChild) {\n this[i].appendChild(tempDiv.firstChild);\n }\n } else if (newChild instanceof Dom7) {\n for (var j = 0; j < newChild.length; j += 1) {\n this[i].appendChild(newChild[j]);\n }\n } else {\n this[i].appendChild(newChild);\n }\n }\n }\n\n return this;\n }\n function prepend(newChild) {\n var i;\n var j;\n for (i = 0; i < this.length; i += 1) {\n if (typeof newChild === 'string') {\n var tempDiv = doc.createElement('div');\n tempDiv.innerHTML = newChild;\n for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {\n this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);\n }\n } else if (newChild instanceof Dom7) {\n for (j = 0; j < newChild.length; j += 1) {\n this[i].insertBefore(newChild[j], this[i].childNodes[0]);\n }\n } else {\n this[i].insertBefore(newChild, this[i].childNodes[0]);\n }\n }\n return this;\n }\n function next(selector) {\n if (this.length > 0) {\n if (selector) {\n if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {\n return new Dom7([this[0].nextElementSibling]);\n }\n return new Dom7([]);\n }\n\n if (this[0].nextElementSibling) { return new Dom7([this[0].nextElementSibling]); }\n return new Dom7([]);\n }\n return new Dom7([]);\n }\n function nextAll(selector) {\n var nextEls = [];\n var el = this[0];\n if (!el) { return new Dom7([]); }\n while (el.nextElementSibling) {\n var next = el.nextElementSibling; // eslint-disable-line\n if (selector) {\n if ($(next).is(selector)) { nextEls.push(next); }\n } else { nextEls.push(next); }\n el = next;\n }\n return new Dom7(nextEls);\n }\n function prev(selector) {\n if (this.length > 0) {\n var el = this[0];\n if (selector) {\n if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {\n return new Dom7([el.previousElementSibling]);\n }\n return new Dom7([]);\n }\n\n if (el.previousElementSibling) { return new Dom7([el.previousElementSibling]); }\n return new Dom7([]);\n }\n return new Dom7([]);\n }\n function prevAll(selector) {\n var prevEls = [];\n var el = this[0];\n if (!el) { return new Dom7([]); }\n while (el.previousElementSibling) {\n var prev = el.previousElementSibling; // eslint-disable-line\n if (selector) {\n if ($(prev).is(selector)) { prevEls.push(prev); }\n } else { prevEls.push(prev); }\n el = prev;\n }\n return new Dom7(prevEls);\n }\n function parent(selector) {\n var parents = []; // eslint-disable-line\n for (var i = 0; i < this.length; i += 1) {\n if (this[i].parentNode !== null) {\n if (selector) {\n if ($(this[i].parentNode).is(selector)) { parents.push(this[i].parentNode); }\n } else {\n parents.push(this[i].parentNode);\n }\n }\n }\n return $(unique(parents));\n }\n function parents(selector) {\n var parents = []; // eslint-disable-line\n for (var i = 0; i < this.length; i += 1) {\n var parent = this[i].parentNode; // eslint-disable-line\n while (parent) {\n if (selector) {\n if ($(parent).is(selector)) { parents.push(parent); }\n } else {\n parents.push(parent);\n }\n parent = parent.parentNode;\n }\n }\n return $(unique(parents));\n }\n function closest(selector) {\n var closest = this; // eslint-disable-line\n if (typeof selector === 'undefined') {\n return new Dom7([]);\n }\n if (!closest.is(selector)) {\n closest = closest.parents(selector).eq(0);\n }\n return closest;\n }\n function find(selector) {\n var foundElements = [];\n for (var i = 0; i < this.length; i += 1) {\n var found = this[i].querySelectorAll(selector);\n for (var j = 0; j < found.length; j += 1) {\n foundElements.push(found[j]);\n }\n }\n return new Dom7(foundElements);\n }\n function children(selector) {\n var children = []; // eslint-disable-line\n for (var i = 0; i < this.length; i += 1) {\n var childNodes = this[i].childNodes;\n\n for (var j = 0; j < childNodes.length; j += 1) {\n if (!selector) {\n if (childNodes[j].nodeType === 1) { children.push(childNodes[j]); }\n } else if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) {\n children.push(childNodes[j]);\n }\n }\n }\n return new Dom7(unique(children));\n }\n function remove() {\n for (var i = 0; i < this.length; i += 1) {\n if (this[i].parentNode) { this[i].parentNode.removeChild(this[i]); }\n }\n return this;\n }\n function add() {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n var dom = this;\n var i;\n var j;\n for (i = 0; i < args.length; i += 1) {\n var toAdd = $(args[i]);\n for (j = 0; j < toAdd.length; j += 1) {\n dom[dom.length] = toAdd[j];\n dom.length += 1;\n }\n }\n return dom;\n }\n\n var Methods = {\n addClass: addClass,\n removeClass: removeClass,\n hasClass: hasClass,\n toggleClass: toggleClass,\n attr: attr,\n removeAttr: removeAttr,\n data: data,\n transform: transform,\n transition: transition,\n on: on,\n off: off,\n trigger: trigger,\n transitionEnd: transitionEnd,\n outerWidth: outerWidth,\n outerHeight: outerHeight,\n offset: offset,\n css: css,\n each: each,\n html: html,\n text: text,\n is: is,\n index: index,\n eq: eq,\n append: append,\n prepend: prepend,\n next: next,\n nextAll: nextAll,\n prev: prev,\n prevAll: prevAll,\n parent: parent,\n parents: parents,\n closest: closest,\n find: find,\n children: children,\n remove: remove,\n add: add,\n styles: styles,\n };\n\n Object.keys(Methods).forEach(function (methodName) {\n $.fn[methodName] = Methods[methodName];\n });\n\n var Utils = {\n deleteProps: function deleteProps(obj) {\n var object = obj;\n Object.keys(object).forEach(function (key) {\n try {\n object[key] = null;\n } catch (e) {\n // no getter for object\n }\n try {\n delete object[key];\n } catch (e) {\n // something got wrong\n }\n });\n },\n nextTick: function nextTick(callback, delay) {\n if ( delay === void 0 ) delay = 0;\n\n return setTimeout(callback, delay);\n },\n now: function now() {\n return Date.now();\n },\n getTranslate: function getTranslate(el, axis) {\n if ( axis === void 0 ) axis = 'x';\n\n var matrix;\n var curTransform;\n var transformMatrix;\n\n var curStyle = win.getComputedStyle(el, null);\n\n if (win.WebKitCSSMatrix) {\n curTransform = curStyle.transform || curStyle.webkitTransform;\n if (curTransform.split(',').length > 6) {\n curTransform = curTransform.split(', ').map(function (a) { return a.replace(',', '.'); }).join(', ');\n }\n // Some old versions of Webkit choke when 'none' is passed; pass\n // empty string instead in this case\n transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);\n } else {\n transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');\n matrix = transformMatrix.toString().split(',');\n }\n\n if (axis === 'x') {\n // Latest Chrome and webkits Fix\n if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m41; }\n // Crazy IE10 Matrix\n else if (matrix.length === 16) { curTransform = parseFloat(matrix[12]); }\n // Normal Browsers\n else { curTransform = parseFloat(matrix[4]); }\n }\n if (axis === 'y') {\n // Latest Chrome and webkits Fix\n if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m42; }\n // Crazy IE10 Matrix\n else if (matrix.length === 16) { curTransform = parseFloat(matrix[13]); }\n // Normal Browsers\n else { curTransform = parseFloat(matrix[5]); }\n }\n return curTransform || 0;\n },\n parseUrlQuery: function parseUrlQuery(url) {\n var query = {};\n var urlToParse = url || win.location.href;\n var i;\n var params;\n var param;\n var length;\n if (typeof urlToParse === 'string' && urlToParse.length) {\n urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\\S*\\?/, '') : '';\n params = urlToParse.split('&').filter(function (paramsPart) { return paramsPart !== ''; });\n length = params.length;\n\n for (i = 0; i < length; i += 1) {\n param = params[i].replace(/#\\S+/g, '').split('=');\n query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param[1]) || '';\n }\n }\n return query;\n },\n isObject: function isObject(o) {\n return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object;\n },\n extend: function extend() {\n var args = [], len$1 = arguments.length;\n while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];\n\n var to = Object(args[0]);\n for (var i = 1; i < args.length; i += 1) {\n var nextSource = args[i];\n if (nextSource !== undefined && nextSource !== null) {\n var keysArray = Object.keys(Object(nextSource));\n for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {\n var nextKey = keysArray[nextIndex];\n var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);\n if (desc !== undefined && desc.enumerable) {\n if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {\n Utils.extend(to[nextKey], nextSource[nextKey]);\n } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {\n to[nextKey] = {};\n Utils.extend(to[nextKey], nextSource[nextKey]);\n } else {\n to[nextKey] = nextSource[nextKey];\n }\n }\n }\n }\n }\n return to;\n },\n };\n\n var Support = (function Support() {\n var testDiv = doc.createElement('div');\n return {\n touch: (win.Modernizr && win.Modernizr.touch === true) || (function checkTouch() {\n return !!((win.navigator.maxTouchPoints > 0) || ('ontouchstart' in win) || (win.DocumentTouch && doc instanceof win.DocumentTouch));\n }()),\n\n pointerEvents: !!(win.navigator.pointerEnabled || win.PointerEvent || ('maxTouchPoints' in win.navigator && win.navigator.maxTouchPoints > 0)),\n prefixedPointerEvents: !!win.navigator.msPointerEnabled,\n\n transition: (function checkTransition() {\n var style = testDiv.style;\n return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style);\n }()),\n transforms3d: (win.Modernizr && win.Modernizr.csstransforms3d === true) || (function checkTransforms3d() {\n var style = testDiv.style;\n return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style);\n }()),\n\n flexbox: (function checkFlexbox() {\n var style = testDiv.style;\n var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');\n for (var i = 0; i < styles.length; i += 1) {\n if (styles[i] in style) { return true; }\n }\n return false;\n }()),\n\n observer: (function checkObserver() {\n return ('MutationObserver' in win || 'WebkitMutationObserver' in win);\n }()),\n\n passiveListener: (function checkPassiveListener() {\n var supportsPassive = false;\n try {\n var opts = Object.defineProperty({}, 'passive', {\n // eslint-disable-next-line\n get: function get() {\n supportsPassive = true;\n },\n });\n win.addEventListener('testPassiveListener', null, opts);\n } catch (e) {\n // No support\n }\n return supportsPassive;\n }()),\n\n gestures: (function checkGestures() {\n return 'ongesturestart' in win;\n }()),\n };\n }());\n\n var Browser = (function Browser() {\n function isSafari() {\n var ua = win.navigator.userAgent.toLowerCase();\n return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);\n }\n return {\n isIE: !!win.navigator.userAgent.match(/Trident/g) || !!win.navigator.userAgent.match(/MSIE/g),\n isEdge: !!win.navigator.userAgent.match(/Edge/g),\n isSafari: isSafari(),\n isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(win.navigator.userAgent),\n };\n }());\n\n var SwiperClass = function SwiperClass(params) {\n if ( params === void 0 ) params = {};\n\n var self = this;\n self.params = params;\n\n // Events\n self.eventsListeners = {};\n\n if (self.params && self.params.on) {\n Object.keys(self.params.on).forEach(function (eventName) {\n self.on(eventName, self.params.on[eventName]);\n });\n }\n };\n\n var staticAccessors = { components: { configurable: true } };\n\n SwiperClass.prototype.on = function on (events, handler, priority) {\n var self = this;\n if (typeof handler !== 'function') { return self; }\n var method = priority ? 'unshift' : 'push';\n events.split(' ').forEach(function (event) {\n if (!self.eventsListeners[event]) { self.eventsListeners[event] = []; }\n self.eventsListeners[event][method](handler);\n });\n return self;\n };\n\n SwiperClass.prototype.once = function once (events, handler, priority) {\n var self = this;\n if (typeof handler !== 'function') { return self; }\n function onceHandler() {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n handler.apply(self, args);\n self.off(events, onceHandler);\n if (onceHandler.f7proxy) {\n delete onceHandler.f7proxy;\n }\n }\n onceHandler.f7proxy = handler;\n return self.on(events, onceHandler, priority);\n };\n\n SwiperClass.prototype.off = function off (events, handler) {\n var self = this;\n if (!self.eventsListeners) { return self; }\n events.split(' ').forEach(function (event) {\n if (typeof handler === 'undefined') {\n self.eventsListeners[event] = [];\n } else if (self.eventsListeners[event] && self.eventsListeners[event].length) {\n self.eventsListeners[event].forEach(function (eventHandler, index) {\n if (eventHandler === handler || (eventHandler.f7proxy && eventHandler.f7proxy === handler)) {\n self.eventsListeners[event].splice(index, 1);\n }\n });\n }\n });\n return self;\n };\n\n SwiperClass.prototype.emit = function emit () {\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n\n var self = this;\n if (!self.eventsListeners) { return self; }\n var events;\n var data;\n var context;\n if (typeof args[0] === 'string' || Array.isArray(args[0])) {\n events = args[0];\n data = args.slice(1, args.length);\n context = self;\n } else {\n events = args[0].events;\n data = args[0].data;\n context = args[0].context || self;\n }\n var eventsArray = Array.isArray(events) ? events : events.split(' ');\n eventsArray.forEach(function (event) {\n if (self.eventsListeners && self.eventsListeners[event]) {\n var handlers = [];\n self.eventsListeners[event].forEach(function (eventHandler) {\n handlers.push(eventHandler);\n });\n handlers.forEach(function (eventHandler) {\n eventHandler.apply(context, data);\n });\n }\n });\n return self;\n };\n\n SwiperClass.prototype.useModulesParams = function useModulesParams (instanceParams) {\n var instance = this;\n if (!instance.modules) { return; }\n Object.keys(instance.modules).forEach(function (moduleName) {\n var module = instance.modules[moduleName];\n // Extend params\n if (module.params) {\n Utils.extend(instanceParams, module.params);\n }\n });\n };\n\n SwiperClass.prototype.useModules = function useModules (modulesParams) {\n if ( modulesParams === void 0 ) modulesParams = {};\n\n var instance = this;\n if (!instance.modules) { return; }\n Object.keys(instance.modules).forEach(function (moduleName) {\n var module = instance.modules[moduleName];\n var moduleParams = modulesParams[moduleName] || {};\n // Extend instance methods and props\n if (module.instance) {\n Object.keys(module.instance).forEach(function (modulePropName) {\n var moduleProp = module.instance[modulePropName];\n if (typeof moduleProp === 'function') {\n instance[modulePropName] = moduleProp.bind(instance);\n } else {\n instance[modulePropName] = moduleProp;\n }\n });\n }\n // Add event listeners\n if (module.on && instance.on) {\n Object.keys(module.on).forEach(function (moduleEventName) {\n instance.on(moduleEventName, module.on[moduleEventName]);\n });\n }\n\n // Module create callback\n if (module.create) {\n module.create.bind(instance)(moduleParams);\n }\n });\n };\n\n staticAccessors.components.set = function (components) {\n var Class = this;\n if (!Class.use) { return; }\n Class.use(components);\n };\n\n SwiperClass.installModule = function installModule (module) {\n var params = [], len = arguments.length - 1;\n while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];\n\n var Class = this;\n if (!Class.prototype.modules) { Class.prototype.modules = {}; }\n var name = module.name || (((Object.keys(Class.prototype.modules).length) + \"_\" + (Utils.now())));\n Class.prototype.modules[name] = module;\n // Prototype\n if (module.proto) {\n Object.keys(module.proto).forEach(function (key) {\n Class.prototype[key] = module.proto[key];\n });\n }\n // Class\n if (module.static) {\n Object.keys(module.static).forEach(function (key) {\n Class[key] = module.static[key];\n });\n }\n // Callback\n if (module.install) {\n module.install.apply(Class, params);\n }\n return Class;\n };\n\n SwiperClass.use = function use (module) {\n var params = [], len = arguments.length - 1;\n while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];\n\n var Class = this;\n if (Array.isArray(module)) {\n module.forEach(function (m) { return Class.installModule(m); });\n return Class;\n }\n return Class.installModule.apply(Class, [ module ].concat( params ));\n };\n\n Object.defineProperties( SwiperClass, staticAccessors );\n\n function updateSize () {\n var swiper = this;\n var width;\n var height;\n var $el = swiper.$el;\n if (typeof swiper.params.width !== 'undefined') {\n width = swiper.params.width;\n } else {\n width = $el[0].clientWidth;\n }\n if (typeof swiper.params.height !== 'undefined') {\n height = swiper.params.height;\n } else {\n height = $el[0].clientHeight;\n }\n if ((width === 0 && swiper.isHorizontal()) || (height === 0 && swiper.isVertical())) {\n return;\n }\n\n // Subtract paddings\n width = width - parseInt($el.css('padding-left'), 10) - parseInt($el.css('padding-right'), 10);\n height = height - parseInt($el.css('padding-top'), 10) - parseInt($el.css('padding-bottom'), 10);\n\n Utils.extend(swiper, {\n width: width,\n height: height,\n size: swiper.isHorizontal() ? width : height,\n });\n }\n\n function updateSlides () {\n var swiper = this;\n var params = swiper.params;\n\n var $wrapperEl = swiper.$wrapperEl;\n var swiperSize = swiper.size;\n var rtl = swiper.rtlTranslate;\n var wrongRTL = swiper.wrongRTL;\n var isVirtual = swiper.virtual && params.virtual.enabled;\n var previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;\n var slides = $wrapperEl.children((\".\" + (swiper.params.slideClass)));\n var slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;\n var snapGrid = [];\n var slidesGrid = [];\n var slidesSizesGrid = [];\n\n var offsetBefore = params.slidesOffsetBefore;\n if (typeof offsetBefore === 'function') {\n offsetBefore = params.slidesOffsetBefore.call(swiper);\n }\n\n var offsetAfter = params.slidesOffsetAfter;\n if (typeof offsetAfter === 'function') {\n offsetAfter = params.slidesOffsetAfter.call(swiper);\n }\n\n var previousSnapGridLength = swiper.snapGrid.length;\n var previousSlidesGridLength = swiper.snapGrid.length;\n\n var spaceBetween = params.spaceBetween;\n var slidePosition = -offsetBefore;\n var prevSlideSize = 0;\n var index = 0;\n if (typeof swiperSize === 'undefined') {\n return;\n }\n if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {\n spaceBetween = (parseFloat(spaceBetween.replace('%', '')) / 100) * swiperSize;\n }\n\n swiper.virtualSize = -spaceBetween;\n\n // reset margins\n if (rtl) { slides.css({ marginLeft: '', marginTop: '' }); }\n else { slides.css({ marginRight: '', marginBottom: '' }); }\n\n var slidesNumberEvenToRows;\n if (params.slidesPerColumn > 1) {\n if (Math.floor(slidesLength / params.slidesPerColumn) === slidesLength / swiper.params.slidesPerColumn) {\n slidesNumberEvenToRows = slidesLength;\n } else {\n slidesNumberEvenToRows = Math.ceil(slidesLength / params.slidesPerColumn) * params.slidesPerColumn;\n }\n if (params.slidesPerView !== 'auto' && params.slidesPerColumnFill === 'row') {\n slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, params.slidesPerView * params.slidesPerColumn);\n }\n }\n\n // Calc slides\n var slideSize;\n var slidesPerColumn = params.slidesPerColumn;\n var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;\n var numFullColumns = Math.floor(slidesLength / params.slidesPerColumn);\n for (var i = 0; i < slidesLength; i += 1) {\n slideSize = 0;\n var slide = slides.eq(i);\n if (params.slidesPerColumn > 1) {\n // Set slides order\n var newSlideOrderIndex = (void 0);\n var column = (void 0);\n var row = (void 0);\n if (params.slidesPerColumnFill === 'column') {\n column = Math.floor(i / slidesPerColumn);\n row = i - (column * slidesPerColumn);\n if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn - 1)) {\n row += 1;\n if (row >= slidesPerColumn) {\n row = 0;\n column += 1;\n }\n }\n newSlideOrderIndex = column + ((row * slidesNumberEvenToRows) / slidesPerColumn);\n slide\n .css({\n '-webkit-box-ordinal-group': newSlideOrderIndex,\n '-moz-box-ordinal-group': newSlideOrderIndex,\n '-ms-flex-order': newSlideOrderIndex,\n '-webkit-order': newSlideOrderIndex,\n order: newSlideOrderIndex,\n });\n } else {\n row = Math.floor(i / slidesPerRow);\n column = i - (row * slidesPerRow);\n }\n slide\n .css(\n (\"margin-\" + (swiper.isHorizontal() ? 'top' : 'left')),\n (row !== 0 && params.spaceBetween) && (((params.spaceBetween) + \"px\"))\n )\n .attr('data-swiper-column', column)\n .attr('data-swiper-row', row);\n }\n if (slide.css('display') === 'none') { continue; } // eslint-disable-line\n\n if (params.slidesPerView === 'auto') {\n var slideStyles = win.getComputedStyle(slide[0], null);\n var currentTransform = slide[0].style.transform;\n var currentWebKitTransform = slide[0].style.webkitTransform;\n if (currentTransform) {\n slide[0].style.transform = 'none';\n }\n if (currentWebKitTransform) {\n slide[0].style.webkitTransform = 'none';\n }\n if (params.roundLengths) {\n slideSize = swiper.isHorizontal()\n ? slide.outerWidth(true)\n : slide.outerHeight(true);\n } else {\n // eslint-disable-next-line\n if (swiper.isHorizontal()) {\n var width = parseFloat(slideStyles.getPropertyValue('width'));\n var paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left'));\n var paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right'));\n var marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left'));\n var marginRight = parseFloat(slideStyles.getPropertyValue('margin-right'));\n var boxSizing = slideStyles.getPropertyValue('box-sizing');\n if (boxSizing && boxSizing === 'border-box') {\n slideSize = width + marginLeft + marginRight;\n } else {\n slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight;\n }\n } else {\n var height = parseFloat(slideStyles.getPropertyValue('height'));\n var paddingTop = parseFloat(slideStyles.getPropertyValue('padding-top'));\n var paddingBottom = parseFloat(slideStyles.getPropertyValue('padding-bottom'));\n var marginTop = parseFloat(slideStyles.getPropertyValue('margin-top'));\n var marginBottom = parseFloat(slideStyles.getPropertyValue('margin-bottom'));\n var boxSizing$1 = slideStyles.getPropertyValue('box-sizing');\n if (boxSizing$1 && boxSizing$1 === 'border-box') {\n slideSize = height + marginTop + marginBottom;\n } else {\n slideSize = height + paddingTop + paddingBottom + marginTop + marginBottom;\n }\n }\n }\n if (currentTransform) {\n slide[0].style.transform = currentTransform;\n }\n if (currentWebKitTransform) {\n slide[0].style.webkitTransform = currentWebKitTransform;\n }\n if (params.roundLengths) { slideSize = Math.floor(slideSize); }\n } else {\n slideSize = (swiperSize - ((params.slidesPerView - 1) * spaceBetween)) / params.slidesPerView;\n if (params.roundLengths) { slideSize = Math.floor(slideSize); }\n\n if (slides[i]) {\n if (swiper.isHorizontal()) {\n slides[i].style.width = slideSize + \"px\";\n } else {\n slides[i].style.height = slideSize + \"px\";\n }\n }\n }\n if (slides[i]) {\n slides[i].swiperSlideSize = slideSize;\n }\n slidesSizesGrid.push(slideSize);\n\n\n if (params.centeredSlides) {\n slidePosition = slidePosition + (slideSize / 2) + (prevSlideSize / 2) + spaceBetween;\n if (prevSlideSize === 0 && i !== 0) { slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; }\n if (i === 0) { slidePosition = slidePosition - (swiperSize / 2) - spaceBetween; }\n if (Math.abs(slidePosition) < 1 / 1000) { slidePosition = 0; }\n if (params.roundLengths) { slidePosition = Math.floor(slidePosition); }\n if ((index) % params.slidesPerGroup === 0) { snapGrid.push(slidePosition); }\n slidesGrid.push(slidePosition);\n } else {\n if (params.roundLengths) { slidePosition = Math.floor(slidePosition); }\n if ((index) % params.slidesPerGroup === 0) { snapGrid.push(slidePosition); }\n slidesGrid.push(slidePosition);\n slidePosition = slidePosition + slideSize + spaceBetween;\n }\n\n swiper.virtualSize += slideSize + spaceBetween;\n\n prevSlideSize = slideSize;\n\n index += 1;\n }\n swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;\n var newSlidesGrid;\n\n if (\n rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {\n $wrapperEl.css({ width: ((swiper.virtualSize + params.spaceBetween) + \"px\") });\n }\n if (!Support.flexbox || params.setWrapperSize) {\n if (swiper.isHorizontal()) { $wrapperEl.css({ width: ((swiper.virtualSize + params.spaceBetween) + \"px\") }); }\n else { $wrapperEl.css({ height: ((swiper.virtualSize + params.spaceBetween) + \"px\") }); }\n }\n\n if (params.slidesPerColumn > 1) {\n swiper.virtualSize = (slideSize + params.spaceBetween) * slidesNumberEvenToRows;\n swiper.virtualSize = Math.ceil(swiper.virtualSize / params.slidesPerColumn) - params.spaceBetween;\n if (swiper.isHorizontal()) { $wrapperEl.css({ width: ((swiper.virtualSize + params.spaceBetween) + \"px\") }); }\n else { $wrapperEl.css({ height: ((swiper.virtualSize + params.spaceBetween) + \"px\") }); }\n if (params.centeredSlides) {\n newSlidesGrid = [];\n for (var i$1 = 0; i$1 < snapGrid.length; i$1 += 1) {\n var slidesGridItem = snapGrid[i$1];\n if (params.roundLengths) { slidesGridItem = Math.floor(slidesGridItem); }\n if (snapGrid[i$1] < swiper.virtualSize + snapGrid[0]) { newSlidesGrid.push(slidesGridItem); }\n }\n snapGrid = newSlidesGrid;\n }\n }\n\n // Remove last grid elements depending on width\n if (!params.centeredSlides) {\n newSlidesGrid = [];\n for (var i$2 = 0; i$2 < snapGrid.length; i$2 += 1) {\n var slidesGridItem$1 = snapGrid[i$2];\n if (params.roundLengths) { slidesGridItem$1 = Math.floor(slidesGridItem$1); }\n if (snapGrid[i$2] <= swiper.virtualSize - swiperSize) {\n newSlidesGrid.push(slidesGridItem$1);\n }\n }\n snapGrid = newSlidesGrid;\n if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {\n snapGrid.push(swiper.virtualSize - swiperSize);\n }\n }\n if (snapGrid.length === 0) { snapGrid = [0]; }\n\n if (params.spaceBetween !== 0) {\n if (swiper.isHorizontal()) {\n if (rtl) { slides.css({ marginLeft: (spaceBetween + \"px\") }); }\n else { slides.css({ marginRight: (spaceBetween + \"px\") }); }\n } else { slides.css({ marginBottom: (spaceBetween + \"px\") }); }\n }\n\n if (params.centerInsufficientSlides) {\n var allSlidesSize = 0;\n slidesSizesGrid.forEach(function (slideSizeValue) {\n allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);\n });\n allSlidesSize -= params.spaceBetween;\n if (allSlidesSize < swiperSize) {\n var allSlidesOffset = (swiperSize - allSlidesSize) / 2;\n snapGrid.forEach(function (snap, snapIndex) {\n snapGrid[snapIndex] = snap - allSlidesOffset;\n });\n slidesGrid.forEach(function (snap, snapIndex) {\n slidesGrid[snapIndex] = snap + allSlidesOffset;\n });\n }\n }\n\n Utils.extend(swiper, {\n slides: slides,\n snapGrid: snapGrid,\n slidesGrid: slidesGrid,\n slidesSizesGrid: slidesSizesGrid,\n });\n\n if (slidesLength !== previousSlidesLength) {\n swiper.emit('slidesLengthChange');\n }\n if (snapGrid.length !== previousSnapGridLength) {\n if (swiper.params.watchOverflow) { swiper.checkOverflow(); }\n swiper.emit('snapGridLengthChange');\n }\n if (slidesGrid.length !== previousSlidesGridLength) {\n swiper.emit('slidesGridLengthChange');\n }\n\n if (params.watchSlidesProgress || params.watchSlidesVisibility) {\n swiper.updateSlidesOffset();\n }\n }\n\n function updateAutoHeight (speed) {\n var swiper = this;\n var activeSlides = [];\n var newHeight = 0;\n var i;\n if (typeof speed === 'number') {\n swiper.setTransition(speed);\n } else if (speed === true) {\n swiper.setTransition(swiper.params.speed);\n }\n // Find slides currently in view\n if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {\n for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {\n var index = swiper.activeIndex + i;\n if (index > swiper.slides.length) { break; }\n activeSlides.push(swiper.slides.eq(index)[0]);\n }\n } else {\n activeSlides.push(swiper.slides.eq(swiper.activeIndex)[0]);\n }\n\n // Find new height from highest slide in view\n for (i = 0; i < activeSlides.length; i += 1) {\n if (typeof activeSlides[i] !== 'undefined') {\n var height = activeSlides[i].offsetHeight;\n newHeight = height > newHeight ? height : newHeight;\n }\n }\n\n // Update Height\n if (newHeight) { swiper.$wrapperEl.css('height', (newHeight + \"px\")); }\n }\n\n function updateSlidesOffset () {\n var swiper = this;\n var slides = swiper.slides;\n for (var i = 0; i < slides.length; i += 1) {\n slides[i].swiperSlideOffset = swiper.isHorizontal() ? slides[i].offsetLeft : slides[i].offsetTop;\n }\n }\n\n function updateSlidesProgress (translate) {\n if ( translate === void 0 ) translate = (this && this.translate) || 0;\n\n var swiper = this;\n var params = swiper.params;\n\n var slides = swiper.slides;\n var rtl = swiper.rtlTranslate;\n\n if (slides.length === 0) { return; }\n if (typeof slides[0].swiperSlideOffset === 'undefined') { swiper.updateSlidesOffset(); }\n\n var offsetCenter = -translate;\n if (rtl) { offsetCenter = translate; }\n\n // Visible Slides\n slides.removeClass(params.slideVisibleClass);\n\n swiper.visibleSlidesIndexes = [];\n swiper.visibleSlides = [];\n\n for (var i = 0; i < slides.length; i += 1) {\n var slide = slides[i];\n var slideProgress = (\n (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0)) - slide.swiperSlideOffset\n ) / (slide.swiperSlideSize + params.spaceBetween);\n if (params.watchSlidesVisibility) {\n var slideBefore = -(offsetCenter - slide.swiperSlideOffset);\n var slideAfter = slideBefore + swiper.slidesSizesGrid[i];\n var isVisible = (slideBefore >= 0 && slideBefore < swiper.size)\n || (slideAfter > 0 && slideAfter <= swiper.size)\n || (slideBefore <= 0 && slideAfter >= swiper.size);\n if (isVisible) {\n swiper.visibleSlides.push(slide);\n swiper.visibleSlidesIndexes.push(i);\n slides.eq(i).addClass(params.slideVisibleClass);\n }\n }\n slide.progress = rtl ? -slideProgress : slideProgress;\n }\n swiper.visibleSlides = $(swiper.visibleSlides);\n }\n\n function updateProgress (translate) {\n if ( translate === void 0 ) translate = (this && this.translate) || 0;\n\n var swiper = this;\n var params = swiper.params;\n\n var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n var progress = swiper.progress;\n var isBeginning = swiper.isBeginning;\n var isEnd = swiper.isEnd;\n var wasBeginning = isBeginning;\n var wasEnd = isEnd;\n if (translatesDiff === 0) {\n progress = 0;\n isBeginning = true;\n isEnd = true;\n } else {\n progress = (translate - swiper.minTranslate()) / (translatesDiff);\n isBeginning = progress <= 0;\n isEnd = progress >= 1;\n }\n Utils.extend(swiper, {\n progress: progress,\n isBeginning: isBeginning,\n isEnd: isEnd,\n });\n\n if (params.watchSlidesProgress || params.watchSlidesVisibility) { swiper.updateSlidesProgress(translate); }\n\n if (isBeginning && !wasBeginning) {\n swiper.emit('reachBeginning toEdge');\n }\n if (isEnd && !wasEnd) {\n swiper.emit('reachEnd toEdge');\n }\n if ((wasBeginning && !isBeginning) || (wasEnd && !isEnd)) {\n swiper.emit('fromEdge');\n }\n\n swiper.emit('progress', progress);\n }\n\n function updateSlidesClasses () {\n var swiper = this;\n\n var slides = swiper.slides;\n var params = swiper.params;\n var $wrapperEl = swiper.$wrapperEl;\n var activeIndex = swiper.activeIndex;\n var realIndex = swiper.realIndex;\n var isVirtual = swiper.virtual && params.virtual.enabled;\n\n slides.removeClass(((params.slideActiveClass) + \" \" + (params.slideNextClass) + \" \" + (params.slidePrevClass) + \" \" + (params.slideDuplicateActiveClass) + \" \" + (params.slideDuplicateNextClass) + \" \" + (params.slideDuplicatePrevClass)));\n\n var activeSlide;\n if (isVirtual) {\n activeSlide = swiper.$wrapperEl.find((\".\" + (params.slideClass) + \"[data-swiper-slide-index=\\\"\" + activeIndex + \"\\\"]\"));\n } else {\n activeSlide = slides.eq(activeIndex);\n }\n\n // Active classes\n activeSlide.addClass(params.slideActiveClass);\n\n if (params.loop) {\n // Duplicate to all looped slides\n if (activeSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl\n .children((\".\" + (params.slideClass) + \":not(.\" + (params.slideDuplicateClass) + \")[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]\"))\n .addClass(params.slideDuplicateActiveClass);\n } else {\n $wrapperEl\n .children((\".\" + (params.slideClass) + \".\" + (params.slideDuplicateClass) + \"[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]\"))\n .addClass(params.slideDuplicateActiveClass);\n }\n }\n // Next Slide\n var nextSlide = activeSlide.nextAll((\".\" + (params.slideClass))).eq(0).addClass(params.slideNextClass);\n if (params.loop && nextSlide.length === 0) {\n nextSlide = slides.eq(0);\n nextSlide.addClass(params.slideNextClass);\n }\n // Prev Slide\n var prevSlide = activeSlide.prevAll((\".\" + (params.slideClass))).eq(0).addClass(params.slidePrevClass);\n if (params.loop && prevSlide.length === 0) {\n prevSlide = slides.eq(-1);\n prevSlide.addClass(params.slidePrevClass);\n }\n if (params.loop) {\n // Duplicate to all looped slides\n if (nextSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl\n .children((\".\" + (params.slideClass) + \":not(.\" + (params.slideDuplicateClass) + \")[data-swiper-slide-index=\\\"\" + (nextSlide.attr('data-swiper-slide-index')) + \"\\\"]\"))\n .addClass(params.slideDuplicateNextClass);\n } else {\n $wrapperEl\n .children((\".\" + (params.slideClass) + \".\" + (params.slideDuplicateClass) + \"[data-swiper-slide-index=\\\"\" + (nextSlide.attr('data-swiper-slide-index')) + \"\\\"]\"))\n .addClass(params.slideDuplicateNextClass);\n }\n if (prevSlide.hasClass(params.slideDuplicateClass)) {\n $wrapperEl\n .children((\".\" + (params.slideClass) + \":not(.\" + (params.slideDuplicateClass) + \")[data-swiper-slide-index=\\\"\" + (prevSlide.attr('data-swiper-slide-index')) + \"\\\"]\"))\n .addClass(params.slideDuplicatePrevClass);\n } else {\n $wrapperEl\n .children((\".\" + (params.slideClass) + \".\" + (params.slideDuplicateClass) + \"[data-swiper-slide-index=\\\"\" + (prevSlide.attr('data-swiper-slide-index')) + \"\\\"]\"))\n .addClass(params.slideDuplicatePrevClass);\n }\n }\n }\n\n function updateActiveIndex (newActiveIndex) {\n var swiper = this;\n var translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;\n var slidesGrid = swiper.slidesGrid;\n var snapGrid = swiper.snapGrid;\n var params = swiper.params;\n var previousIndex = swiper.activeIndex;\n var previousRealIndex = swiper.realIndex;\n var previousSnapIndex = swiper.snapIndex;\n var activeIndex = newActiveIndex;\n var snapIndex;\n if (typeof activeIndex === 'undefined') {\n for (var i = 0; i < slidesGrid.length; i += 1) {\n if (typeof slidesGrid[i + 1] !== 'undefined') {\n if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - ((slidesGrid[i + 1] - slidesGrid[i]) / 2)) {\n activeIndex = i;\n } else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {\n activeIndex = i + 1;\n }\n } else if (translate >= slidesGrid[i]) {\n activeIndex = i;\n }\n }\n // Normalize slideIndex\n if (params.normalizeSlideIndex) {\n if (activeIndex < 0 || typeof activeIndex === 'undefined') { activeIndex = 0; }\n }\n }\n if (snapGrid.indexOf(translate) >= 0) {\n snapIndex = snapGrid.indexOf(translate);\n } else {\n snapIndex = Math.floor(activeIndex / params.slidesPerGroup);\n }\n if (snapIndex >= snapGrid.length) { snapIndex = snapGrid.length - 1; }\n if (activeIndex === previousIndex) {\n if (snapIndex !== previousSnapIndex) {\n swiper.snapIndex = snapIndex;\n swiper.emit('snapIndexChange');\n }\n return;\n }\n\n // Get real index\n var realIndex = parseInt(swiper.slides.eq(activeIndex).attr('data-swiper-slide-index') || activeIndex, 10);\n\n Utils.extend(swiper, {\n snapIndex: snapIndex,\n realIndex: realIndex,\n previousIndex: previousIndex,\n activeIndex: activeIndex,\n });\n swiper.emit('activeIndexChange');\n swiper.emit('snapIndexChange');\n if (previousRealIndex !== realIndex) {\n swiper.emit('realIndexChange');\n }\n swiper.emit('slideChange');\n }\n\n function updateClickedSlide (e) {\n var swiper = this;\n var params = swiper.params;\n var slide = $(e.target).closest((\".\" + (params.slideClass)))[0];\n var slideFound = false;\n if (slide) {\n for (var i = 0; i < swiper.slides.length; i += 1) {\n if (swiper.slides[i] === slide) { slideFound = true; }\n }\n }\n\n if (slide && slideFound) {\n swiper.clickedSlide = slide;\n if (swiper.virtual && swiper.params.virtual.enabled) {\n swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10);\n } else {\n swiper.clickedIndex = $(slide).index();\n }\n } else {\n swiper.clickedSlide = undefined;\n swiper.clickedIndex = undefined;\n return;\n }\n if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {\n swiper.slideToClickedSlide();\n }\n }\n\n var update = {\n updateSize: updateSize,\n updateSlides: updateSlides,\n updateAutoHeight: updateAutoHeight,\n updateSlidesOffset: updateSlidesOffset,\n updateSlidesProgress: updateSlidesProgress,\n updateProgress: updateProgress,\n updateSlidesClasses: updateSlidesClasses,\n updateActiveIndex: updateActiveIndex,\n updateClickedSlide: updateClickedSlide,\n };\n\n function getTranslate (axis) {\n if ( axis === void 0 ) axis = this.isHorizontal() ? 'x' : 'y';\n\n var swiper = this;\n\n var params = swiper.params;\n var rtl = swiper.rtlTranslate;\n var translate = swiper.translate;\n var $wrapperEl = swiper.$wrapperEl;\n\n if (params.virtualTranslate) {\n return rtl ? -translate : translate;\n }\n\n var currentTranslate = Utils.getTranslate($wrapperEl[0], axis);\n if (rtl) { currentTranslate = -currentTranslate; }\n\n return currentTranslate || 0;\n }\n\n function setTranslate (translate, byController) {\n var swiper = this;\n var rtl = swiper.rtlTranslate;\n var params = swiper.params;\n var $wrapperEl = swiper.$wrapperEl;\n var progress = swiper.progress;\n var x = 0;\n var y = 0;\n var z = 0;\n\n if (swiper.isHorizontal()) {\n x = rtl ? -translate : translate;\n } else {\n y = translate;\n }\n\n if (params.roundLengths) {\n x = Math.floor(x);\n y = Math.floor(y);\n }\n\n if (!params.virtualTranslate) {\n if (Support.transforms3d) { $wrapperEl.transform((\"translate3d(\" + x + \"px, \" + y + \"px, \" + z + \"px)\")); }\n else { $wrapperEl.transform((\"translate(\" + x + \"px, \" + y + \"px)\")); }\n }\n swiper.previousTranslate = swiper.translate;\n swiper.translate = swiper.isHorizontal() ? x : y;\n\n // Check if we need to update progress\n var newProgress;\n var translatesDiff = swiper.maxTranslate() - swiper.minTranslate();\n if (translatesDiff === 0) {\n newProgress = 0;\n } else {\n newProgress = (translate - swiper.minTranslate()) / (translatesDiff);\n }\n if (newProgress !== progress) {\n swiper.updateProgress(translate);\n }\n\n swiper.emit('setTranslate', swiper.translate, byController);\n }\n\n function minTranslate () {\n return (-this.snapGrid[0]);\n }\n\n function maxTranslate () {\n return (-this.snapGrid[this.snapGrid.length - 1]);\n }\n\n var translate = {\n getTranslate: getTranslate,\n setTranslate: setTranslate,\n minTranslate: minTranslate,\n maxTranslate: maxTranslate,\n };\n\n function setTransition (duration, byController) {\n var swiper = this;\n\n swiper.$wrapperEl.transition(duration);\n\n swiper.emit('setTransition', duration, byController);\n }\n\n function transitionStart (runCallbacks, direction) {\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n var activeIndex = swiper.activeIndex;\n var params = swiper.params;\n var previousIndex = swiper.previousIndex;\n if (params.autoHeight) {\n swiper.updateAutoHeight();\n }\n\n var dir = direction;\n if (!dir) {\n if (activeIndex > previousIndex) { dir = 'next'; }\n else if (activeIndex < previousIndex) { dir = 'prev'; }\n else { dir = 'reset'; }\n }\n\n swiper.emit('transitionStart');\n\n if (runCallbacks && activeIndex !== previousIndex) {\n if (dir === 'reset') {\n swiper.emit('slideResetTransitionStart');\n return;\n }\n swiper.emit('slideChangeTransitionStart');\n if (dir === 'next') {\n swiper.emit('slideNextTransitionStart');\n } else {\n swiper.emit('slidePrevTransitionStart');\n }\n }\n }\n\n function transitionEnd$1 (runCallbacks, direction) {\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n var activeIndex = swiper.activeIndex;\n var previousIndex = swiper.previousIndex;\n swiper.animating = false;\n swiper.setTransition(0);\n\n var dir = direction;\n if (!dir) {\n if (activeIndex > previousIndex) { dir = 'next'; }\n else if (activeIndex < previousIndex) { dir = 'prev'; }\n else { dir = 'reset'; }\n }\n\n swiper.emit('transitionEnd');\n\n if (runCallbacks && activeIndex !== previousIndex) {\n if (dir === 'reset') {\n swiper.emit('slideResetTransitionEnd');\n return;\n }\n swiper.emit('slideChangeTransitionEnd');\n if (dir === 'next') {\n swiper.emit('slideNextTransitionEnd');\n } else {\n swiper.emit('slidePrevTransitionEnd');\n }\n }\n }\n\n var transition$1 = {\n setTransition: setTransition,\n transitionStart: transitionStart,\n transitionEnd: transitionEnd$1,\n };\n\n function slideTo (index, speed, runCallbacks, internal) {\n if ( index === void 0 ) index = 0;\n if ( speed === void 0 ) speed = this.params.speed;\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n var slideIndex = index;\n if (slideIndex < 0) { slideIndex = 0; }\n\n var params = swiper.params;\n var snapGrid = swiper.snapGrid;\n var slidesGrid = swiper.slidesGrid;\n var previousIndex = swiper.previousIndex;\n var activeIndex = swiper.activeIndex;\n var rtl = swiper.rtlTranslate;\n if (swiper.animating && params.preventInteractionOnTransition) {\n return false;\n }\n\n var snapIndex = Math.floor(slideIndex / params.slidesPerGroup);\n if (snapIndex >= snapGrid.length) { snapIndex = snapGrid.length - 1; }\n\n if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {\n swiper.emit('beforeSlideChangeStart');\n }\n\n var translate = -snapGrid[snapIndex];\n\n // Update progress\n swiper.updateProgress(translate);\n\n // Normalize slideIndex\n if (params.normalizeSlideIndex) {\n for (var i = 0; i < slidesGrid.length; i += 1) {\n if (-Math.floor(translate * 100) >= Math.floor(slidesGrid[i] * 100)) {\n slideIndex = i;\n }\n }\n }\n // Directions locks\n if (swiper.initialized && slideIndex !== activeIndex) {\n if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {\n return false;\n }\n if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {\n if ((activeIndex || 0) !== slideIndex) { return false; }\n }\n }\n\n var direction;\n if (slideIndex > activeIndex) { direction = 'next'; }\n else if (slideIndex < activeIndex) { direction = 'prev'; }\n else { direction = 'reset'; }\n\n\n // Update Index\n if ((rtl && -translate === swiper.translate) || (!rtl && translate === swiper.translate)) {\n swiper.updateActiveIndex(slideIndex);\n // Update Height\n if (params.autoHeight) {\n swiper.updateAutoHeight();\n }\n swiper.updateSlidesClasses();\n if (params.effect !== 'slide') {\n swiper.setTranslate(translate);\n }\n if (direction !== 'reset') {\n swiper.transitionStart(runCallbacks, direction);\n swiper.transitionEnd(runCallbacks, direction);\n }\n return false;\n }\n\n if (speed === 0 || !Support.transition) {\n swiper.setTransition(0);\n swiper.setTranslate(translate);\n swiper.updateActiveIndex(slideIndex);\n swiper.updateSlidesClasses();\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.transitionStart(runCallbacks, direction);\n swiper.transitionEnd(runCallbacks, direction);\n } else {\n swiper.setTransition(speed);\n swiper.setTranslate(translate);\n swiper.updateActiveIndex(slideIndex);\n swiper.updateSlidesClasses();\n swiper.emit('beforeTransitionStart', speed, internal);\n swiper.transitionStart(runCallbacks, direction);\n if (!swiper.animating) {\n swiper.animating = true;\n if (!swiper.onSlideToWrapperTransitionEnd) {\n swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {\n if (!swiper || swiper.destroyed) { return; }\n if (e.target !== this) { return; }\n swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);\n swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);\n swiper.onSlideToWrapperTransitionEnd = null;\n delete swiper.onSlideToWrapperTransitionEnd;\n swiper.transitionEnd(runCallbacks, direction);\n };\n }\n swiper.$wrapperEl[0].addEventListener('transitionend', swiper.onSlideToWrapperTransitionEnd);\n swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.onSlideToWrapperTransitionEnd);\n }\n }\n\n return true;\n }\n\n function slideToLoop (index, speed, runCallbacks, internal) {\n if ( index === void 0 ) index = 0;\n if ( speed === void 0 ) speed = this.params.speed;\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n var newIndex = index;\n if (swiper.params.loop) {\n newIndex += swiper.loopedSlides;\n }\n\n return swiper.slideTo(newIndex, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slideNext (speed, runCallbacks, internal) {\n if ( speed === void 0 ) speed = this.params.speed;\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n var params = swiper.params;\n var animating = swiper.animating;\n if (params.loop) {\n if (animating) { return false; }\n swiper.loopFix();\n // eslint-disable-next-line\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal);\n }\n return swiper.slideTo(swiper.activeIndex + params.slidesPerGroup, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slidePrev (speed, runCallbacks, internal) {\n if ( speed === void 0 ) speed = this.params.speed;\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n var params = swiper.params;\n var animating = swiper.animating;\n var snapGrid = swiper.snapGrid;\n var slidesGrid = swiper.slidesGrid;\n var rtlTranslate = swiper.rtlTranslate;\n\n if (params.loop) {\n if (animating) { return false; }\n swiper.loopFix();\n // eslint-disable-next-line\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n }\n var translate = rtlTranslate ? swiper.translate : -swiper.translate;\n function normalize(val) {\n if (val < 0) { return -Math.floor(Math.abs(val)); }\n return Math.floor(val);\n }\n var normalizedTranslate = normalize(translate);\n var normalizedSnapGrid = snapGrid.map(function (val) { return normalize(val); });\n var normalizedSlidesGrid = slidesGrid.map(function (val) { return normalize(val); });\n\n var currentSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate)];\n var prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];\n var prevIndex;\n if (typeof prevSnap !== 'undefined') {\n prevIndex = slidesGrid.indexOf(prevSnap);\n if (prevIndex < 0) { prevIndex = swiper.activeIndex - 1; }\n }\n return swiper.slideTo(prevIndex, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slideReset (speed, runCallbacks, internal) {\n if ( speed === void 0 ) speed = this.params.speed;\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);\n }\n\n /* eslint no-unused-vars: \"off\" */\n function slideToClosest (speed, runCallbacks, internal) {\n if ( speed === void 0 ) speed = this.params.speed;\n if ( runCallbacks === void 0 ) runCallbacks = true;\n\n var swiper = this;\n var index = swiper.activeIndex;\n var snapIndex = Math.floor(index / swiper.params.slidesPerGroup);\n\n if (snapIndex < swiper.snapGrid.length - 1) {\n var translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;\n\n var currentSnap = swiper.snapGrid[snapIndex];\n var nextSnap = swiper.snapGrid[snapIndex + 1];\n\n if ((translate - currentSnap) > (nextSnap - currentSnap) / 2) {\n index = swiper.params.slidesPerGroup;\n }\n }\n\n return swiper.slideTo(index, speed, runCallbacks, internal);\n }\n\n function slideToClickedSlide () {\n var swiper = this;\n var params = swiper.params;\n var $wrapperEl = swiper.$wrapperEl;\n\n var slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;\n var slideToIndex = swiper.clickedIndex;\n var realIndex;\n if (params.loop) {\n if (swiper.animating) { return; }\n realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10);\n if (params.centeredSlides) {\n if (\n (slideToIndex < swiper.loopedSlides - (slidesPerView / 2))\n || (slideToIndex > (swiper.slides.length - swiper.loopedSlides) + (slidesPerView / 2))\n ) {\n swiper.loopFix();\n slideToIndex = $wrapperEl\n .children((\".\" + (params.slideClass) + \"[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]:not(.\" + (params.slideDuplicateClass) + \")\"))\n .eq(0)\n .index();\n\n Utils.nextTick(function () {\n swiper.slideTo(slideToIndex);\n });\n } else {\n swiper.slideTo(slideToIndex);\n }\n } else if (slideToIndex > swiper.slides.length - slidesPerView) {\n swiper.loopFix();\n slideToIndex = $wrapperEl\n .children((\".\" + (params.slideClass) + \"[data-swiper-slide-index=\\\"\" + realIndex + \"\\\"]:not(.\" + (params.slideDuplicateClass) + \")\"))\n .eq(0)\n .index();\n\n Utils.nextTick(function () {\n swiper.slideTo(slideToIndex);\n });\n } else {\n swiper.slideTo(slideToIndex);\n }\n } else {\n swiper.slideTo(slideToIndex);\n }\n }\n\n var slide = {\n slideTo: slideTo,\n slideToLoop: slideToLoop,\n slideNext: slideNext,\n slidePrev: slidePrev,\n slideReset: slideReset,\n slideToClosest: slideToClosest,\n slideToClickedSlide: slideToClickedSlide,\n };\n\n function loopCreate () {\n var swiper = this;\n var params = swiper.params;\n var $wrapperEl = swiper.$wrapperEl;\n // Remove duplicated slides\n $wrapperEl.children((\".\" + (params.slideClass) + \".\" + (params.slideDuplicateClass))).remove();\n\n var slides = $wrapperEl.children((\".\" + (params.slideClass)));\n\n if (params.loopFillGroupWithBlank) {\n var blankSlidesNum = params.slidesPerGroup - (slides.length % params.slidesPerGroup);\n if (blankSlidesNum !== params.slidesPerGroup) {\n for (var i = 0; i < blankSlidesNum; i += 1) {\n var blankNode = $(doc.createElement('div')).addClass(((params.slideClass) + \" \" + (params.slideBlankClass)));\n $wrapperEl.append(blankNode);\n }\n slides = $wrapperEl.children((\".\" + (params.slideClass)));\n }\n }\n\n if (params.slidesPerView === 'auto' && !params.loopedSlides) { params.loopedSlides = slides.length; }\n\n swiper.loopedSlides = parseInt(params.loopedSlides || params.slidesPerView, 10);\n swiper.loopedSlides += params.loopAdditionalSlides;\n if (swiper.loopedSlides > slides.length) {\n swiper.loopedSlides = slides.length;\n }\n\n var prependSlides = [];\n var appendSlides = [];\n slides.each(function (index, el) {\n var slide = $(el);\n if (index < swiper.loopedSlides) { appendSlides.push(el); }\n if (index < slides.length && index >= slides.length - swiper.loopedSlides) { prependSlides.push(el); }\n slide.attr('data-swiper-slide-index', index);\n });\n for (var i$1 = 0; i$1 < appendSlides.length; i$1 += 1) {\n $wrapperEl.append($(appendSlides[i$1].cloneNode(true)).addClass(params.slideDuplicateClass));\n }\n for (var i$2 = prependSlides.length - 1; i$2 >= 0; i$2 -= 1) {\n $wrapperEl.prepend($(prependSlides[i$2].cloneNode(true)).addClass(params.slideDuplicateClass));\n }\n }\n\n function loopFix () {\n var swiper = this;\n var params = swiper.params;\n var activeIndex = swiper.activeIndex;\n var slides = swiper.slides;\n var loopedSlides = swiper.loopedSlides;\n var allowSlidePrev = swiper.allowSlidePrev;\n var allowSlideNext = swiper.allowSlideNext;\n var snapGrid = swiper.snapGrid;\n var rtl = swiper.rtlTranslate;\n var newIndex;\n swiper.allowSlidePrev = true;\n swiper.allowSlideNext = true;\n\n var snapTranslate = -snapGrid[activeIndex];\n var diff = snapTranslate - swiper.getTranslate();\n\n\n // Fix For Negative Oversliding\n if (activeIndex < loopedSlides) {\n newIndex = (slides.length - (loopedSlides * 3)) + activeIndex;\n newIndex += loopedSlides;\n var slideChanged = swiper.slideTo(newIndex, 0, false, true);\n if (slideChanged && diff !== 0) {\n swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);\n }\n } else if ((params.slidesPerView === 'auto' && activeIndex >= loopedSlides * 2) || (activeIndex >= slides.length - loopedSlides)) {\n // Fix For Positive Oversliding\n newIndex = -slides.length + activeIndex + loopedSlides;\n newIndex += loopedSlides;\n var slideChanged$1 = swiper.slideTo(newIndex, 0, false, true);\n if (slideChanged$1 && diff !== 0) {\n swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);\n }\n }\n swiper.allowSlidePrev = allowSlidePrev;\n swiper.allowSlideNext = allowSlideNext;\n }\n\n function loopDestroy () {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl;\n var params = swiper.params;\n var slides = swiper.slides;\n $wrapperEl.children((\".\" + (params.slideClass) + \".\" + (params.slideDuplicateClass) + \",.\" + (params.slideClass) + \".\" + (params.slideBlankClass))).remove();\n slides.removeAttr('data-swiper-slide-index');\n }\n\n var loop = {\n loopCreate: loopCreate,\n loopFix: loopFix,\n loopDestroy: loopDestroy,\n };\n\n function setGrabCursor (moving) {\n var swiper = this;\n if (Support.touch || !swiper.params.simulateTouch || (swiper.params.watchOverflow && swiper.isLocked)) { return; }\n var el = swiper.el;\n el.style.cursor = 'move';\n el.style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';\n el.style.cursor = moving ? '-moz-grabbin' : '-moz-grab';\n el.style.cursor = moving ? 'grabbing' : 'grab';\n }\n\n function unsetGrabCursor () {\n var swiper = this;\n if (Support.touch || (swiper.params.watchOverflow && swiper.isLocked)) { return; }\n swiper.el.style.cursor = '';\n }\n\n var grabCursor = {\n setGrabCursor: setGrabCursor,\n unsetGrabCursor: unsetGrabCursor,\n };\n\n function appendSlide (slides) {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl;\n var params = swiper.params;\n if (params.loop) {\n swiper.loopDestroy();\n }\n if (typeof slides === 'object' && 'length' in slides) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) { $wrapperEl.append(slides[i]); }\n }\n } else {\n $wrapperEl.append(slides);\n }\n if (params.loop) {\n swiper.loopCreate();\n }\n if (!(params.observer && Support.observer)) {\n swiper.update();\n }\n }\n\n function prependSlide (slides) {\n var swiper = this;\n var params = swiper.params;\n var $wrapperEl = swiper.$wrapperEl;\n var activeIndex = swiper.activeIndex;\n\n if (params.loop) {\n swiper.loopDestroy();\n }\n var newActiveIndex = activeIndex + 1;\n if (typeof slides === 'object' && 'length' in slides) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) { $wrapperEl.prepend(slides[i]); }\n }\n newActiveIndex = activeIndex + slides.length;\n } else {\n $wrapperEl.prepend(slides);\n }\n if (params.loop) {\n swiper.loopCreate();\n }\n if (!(params.observer && Support.observer)) {\n swiper.update();\n }\n swiper.slideTo(newActiveIndex, 0, false);\n }\n\n function addSlide (index, slides) {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl;\n var params = swiper.params;\n var activeIndex = swiper.activeIndex;\n var activeIndexBuffer = activeIndex;\n if (params.loop) {\n activeIndexBuffer -= swiper.loopedSlides;\n swiper.loopDestroy();\n swiper.slides = $wrapperEl.children((\".\" + (params.slideClass)));\n }\n var baseLength = swiper.slides.length;\n if (index <= 0) {\n swiper.prependSlide(slides);\n return;\n }\n if (index >= baseLength) {\n swiper.appendSlide(slides);\n return;\n }\n var newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + 1 : activeIndexBuffer;\n\n var slidesBuffer = [];\n for (var i = baseLength - 1; i >= index; i -= 1) {\n var currentSlide = swiper.slides.eq(i);\n currentSlide.remove();\n slidesBuffer.unshift(currentSlide);\n }\n\n if (typeof slides === 'object' && 'length' in slides) {\n for (var i$1 = 0; i$1 < slides.length; i$1 += 1) {\n if (slides[i$1]) { $wrapperEl.append(slides[i$1]); }\n }\n newActiveIndex = activeIndexBuffer > index ? activeIndexBuffer + slides.length : activeIndexBuffer;\n } else {\n $wrapperEl.append(slides);\n }\n\n for (var i$2 = 0; i$2 < slidesBuffer.length; i$2 += 1) {\n $wrapperEl.append(slidesBuffer[i$2]);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n if (!(params.observer && Support.observer)) {\n swiper.update();\n }\n if (params.loop) {\n swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);\n } else {\n swiper.slideTo(newActiveIndex, 0, false);\n }\n }\n\n function removeSlide (slidesIndexes) {\n var swiper = this;\n var params = swiper.params;\n var $wrapperEl = swiper.$wrapperEl;\n var activeIndex = swiper.activeIndex;\n\n var activeIndexBuffer = activeIndex;\n if (params.loop) {\n activeIndexBuffer -= swiper.loopedSlides;\n swiper.loopDestroy();\n swiper.slides = $wrapperEl.children((\".\" + (params.slideClass)));\n }\n var newActiveIndex = activeIndexBuffer;\n var indexToRemove;\n\n if (typeof slidesIndexes === 'object' && 'length' in slidesIndexes) {\n for (var i = 0; i < slidesIndexes.length; i += 1) {\n indexToRemove = slidesIndexes[i];\n if (swiper.slides[indexToRemove]) { swiper.slides.eq(indexToRemove).remove(); }\n if (indexToRemove < newActiveIndex) { newActiveIndex -= 1; }\n }\n newActiveIndex = Math.max(newActiveIndex, 0);\n } else {\n indexToRemove = slidesIndexes;\n if (swiper.slides[indexToRemove]) { swiper.slides.eq(indexToRemove).remove(); }\n if (indexToRemove < newActiveIndex) { newActiveIndex -= 1; }\n newActiveIndex = Math.max(newActiveIndex, 0);\n }\n\n if (params.loop) {\n swiper.loopCreate();\n }\n\n if (!(params.observer && Support.observer)) {\n swiper.update();\n }\n if (params.loop) {\n swiper.slideTo(newActiveIndex + swiper.loopedSlides, 0, false);\n } else {\n swiper.slideTo(newActiveIndex, 0, false);\n }\n }\n\n function removeAllSlides () {\n var swiper = this;\n\n var slidesIndexes = [];\n for (var i = 0; i < swiper.slides.length; i += 1) {\n slidesIndexes.push(i);\n }\n swiper.removeSlide(slidesIndexes);\n }\n\n var manipulation = {\n appendSlide: appendSlide,\n prependSlide: prependSlide,\n addSlide: addSlide,\n removeSlide: removeSlide,\n removeAllSlides: removeAllSlides,\n };\n\n var Device = (function Device() {\n var ua = win.navigator.userAgent;\n\n var device = {\n ios: false,\n android: false,\n androidChrome: false,\n desktop: false,\n windows: false,\n iphone: false,\n ipod: false,\n ipad: false,\n cordova: win.cordova || win.phonegap,\n phonegap: win.cordova || win.phonegap,\n };\n\n var windows = ua.match(/(Windows Phone);?[\\s\\/]+([\\d.]+)?/); // eslint-disable-line\n var android = ua.match(/(Android);?[\\s\\/]+([\\d.]+)?/); // eslint-disable-line\n var ipad = ua.match(/(iPad).*OS\\s([\\d_]+)/);\n var ipod = ua.match(/(iPod)(.*OS\\s([\\d_]+))?/);\n var iphone = !ipad && ua.match(/(iPhone\\sOS|iOS)\\s([\\d_]+)/);\n\n\n // Windows\n if (windows) {\n device.os = 'windows';\n device.osVersion = windows[2];\n device.windows = true;\n }\n // Android\n if (android && !windows) {\n device.os = 'android';\n device.osVersion = android[2];\n device.android = true;\n device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;\n }\n if (ipad || iphone || ipod) {\n device.os = 'ios';\n device.ios = true;\n }\n // iOS\n if (iphone && !ipod) {\n device.osVersion = iphone[2].replace(/_/g, '.');\n device.iphone = true;\n }\n if (ipad) {\n device.osVersion = ipad[2].replace(/_/g, '.');\n device.ipad = true;\n }\n if (ipod) {\n device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;\n device.iphone = true;\n }\n // iOS 8+ changed UA\n if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {\n if (device.osVersion.split('.')[0] === '10') {\n device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];\n }\n }\n\n // Desktop\n device.desktop = !(device.os || device.android || device.webView);\n\n // Webview\n device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i);\n\n // Minimal UI\n if (device.os && device.os === 'ios') {\n var osVersionArr = device.osVersion.split('.');\n var metaViewport = doc.querySelector('meta[name=\"viewport\"]');\n device.minimalUi = !device.webView\n && (ipod || iphone)\n && (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7)\n && metaViewport && metaViewport.getAttribute('content').indexOf('minimal-ui') >= 0;\n }\n\n // Pixel Ratio\n device.pixelRatio = win.devicePixelRatio || 1;\n\n // Export object\n return device;\n }());\n\n function onTouchStart (event) {\n var swiper = this;\n var data = swiper.touchEventsData;\n var params = swiper.params;\n var touches = swiper.touches;\n if (swiper.animating && params.preventInteractionOnTransition) {\n return;\n }\n var e = event;\n if (e.originalEvent) { e = e.originalEvent; }\n data.isTouchEvent = e.type === 'touchstart';\n if (!data.isTouchEvent && 'which' in e && e.which === 3) { return; }\n if (!data.isTouchEvent && 'button' in e && e.button > 0) { return; }\n if (data.isTouched && data.isMoved) { return; }\n if (params.noSwiping && $(e.target).closest(params.noSwipingSelector ? params.noSwipingSelector : (\".\" + (params.noSwipingClass)))[0]) {\n swiper.allowClick = true;\n return;\n }\n if (params.swipeHandler) {\n if (!$(e).closest(params.swipeHandler)[0]) { return; }\n }\n\n touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n var startX = touches.currentX;\n var startY = touches.currentY;\n\n // Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore\n\n var edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;\n var edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;\n if (\n edgeSwipeDetection\n && ((startX <= edgeSwipeThreshold)\n || (startX >= win.screen.width - edgeSwipeThreshold))\n ) {\n return;\n }\n\n Utils.extend(data, {\n isTouched: true,\n isMoved: false,\n allowTouchCallbacks: true,\n isScrolling: undefined,\n startMoving: undefined,\n });\n\n touches.startX = startX;\n touches.startY = startY;\n data.touchStartTime = Utils.now();\n swiper.allowClick = true;\n swiper.updateSize();\n swiper.swipeDirection = undefined;\n if (params.threshold > 0) { data.allowThresholdMove = false; }\n if (e.type !== 'touchstart') {\n var preventDefault = true;\n if ($(e.target).is(data.formElements)) { preventDefault = false; }\n if (\n doc.activeElement\n && $(doc.activeElement).is(data.formElements)\n && doc.activeElement !== e.target\n ) {\n doc.activeElement.blur();\n }\n\n var shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;\n if (params.touchStartForcePreventDefault || shouldPreventDefault) {\n e.preventDefault();\n }\n }\n swiper.emit('touchStart', e);\n }\n\n function onTouchMove (event) {\n var swiper = this;\n var data = swiper.touchEventsData;\n var params = swiper.params;\n var touches = swiper.touches;\n var rtl = swiper.rtlTranslate;\n var e = event;\n if (e.originalEvent) { e = e.originalEvent; }\n if (!data.isTouched) {\n if (data.startMoving && data.isScrolling) {\n swiper.emit('touchMoveOpposite', e);\n }\n return;\n }\n if (data.isTouchEvent && e.type === 'mousemove') { return; }\n var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n if (e.preventedByNestedSwiper) {\n touches.startX = pageX;\n touches.startY = pageY;\n return;\n }\n if (!swiper.allowTouchMove) {\n // isMoved = true;\n swiper.allowClick = false;\n if (data.isTouched) {\n Utils.extend(touches, {\n startX: pageX,\n startY: pageY,\n currentX: pageX,\n currentY: pageY,\n });\n data.touchStartTime = Utils.now();\n }\n return;\n }\n if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) {\n if (swiper.isVertical()) {\n // Vertical\n if (\n (pageY < touches.startY && swiper.translate <= swiper.maxTranslate())\n || (pageY > touches.startY && swiper.translate >= swiper.minTranslate())\n ) {\n data.isTouched = false;\n data.isMoved = false;\n return;\n }\n } else if (\n (pageX < touches.startX && swiper.translate <= swiper.maxTranslate())\n || (pageX > touches.startX && swiper.translate >= swiper.minTranslate())\n ) {\n return;\n }\n }\n if (data.isTouchEvent && doc.activeElement) {\n if (e.target === doc.activeElement && $(e.target).is(data.formElements)) {\n data.isMoved = true;\n swiper.allowClick = false;\n return;\n }\n }\n if (data.allowTouchCallbacks) {\n swiper.emit('touchMove', e);\n }\n if (e.targetTouches && e.targetTouches.length > 1) { return; }\n\n touches.currentX = pageX;\n touches.currentY = pageY;\n\n var diffX = touches.currentX - touches.startX;\n var diffY = touches.currentY - touches.startY;\n if (swiper.params.threshold && Math.sqrt((Math.pow( diffX, 2 )) + (Math.pow( diffY, 2 ))) < swiper.params.threshold) { return; }\n\n if (typeof data.isScrolling === 'undefined') {\n var touchAngle;\n if ((swiper.isHorizontal() && touches.currentY === touches.startY) || (swiper.isVertical() && touches.currentX === touches.startX)) {\n data.isScrolling = false;\n } else {\n // eslint-disable-next-line\n if ((diffX * diffX) + (diffY * diffY) >= 25) {\n touchAngle = (Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180) / Math.PI;\n data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : (90 - touchAngle > params.touchAngle);\n }\n }\n }\n if (data.isScrolling) {\n swiper.emit('touchMoveOpposite', e);\n }\n if (typeof data.startMoving === 'undefined') {\n if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {\n data.startMoving = true;\n }\n }\n if (data.isScrolling) {\n data.isTouched = false;\n return;\n }\n if (!data.startMoving) {\n return;\n }\n swiper.allowClick = false;\n e.preventDefault();\n if (params.touchMoveStopPropagation && !params.nested) {\n e.stopPropagation();\n }\n\n if (!data.isMoved) {\n if (params.loop) {\n swiper.loopFix();\n }\n data.startTranslate = swiper.getTranslate();\n swiper.setTransition(0);\n if (swiper.animating) {\n swiper.$wrapperEl.trigger('webkitTransitionEnd transitionend');\n }\n data.allowMomentumBounce = false;\n // Grab Cursor\n if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {\n swiper.setGrabCursor(true);\n }\n swiper.emit('sliderFirstMove', e);\n }\n swiper.emit('sliderMove', e);\n data.isMoved = true;\n\n var diff = swiper.isHorizontal() ? diffX : diffY;\n touches.diff = diff;\n\n diff *= params.touchRatio;\n if (rtl) { diff = -diff; }\n\n swiper.swipeDirection = diff > 0 ? 'prev' : 'next';\n data.currentTranslate = diff + data.startTranslate;\n\n var disableParentSwiper = true;\n var resistanceRatio = params.resistanceRatio;\n if (params.touchReleaseOnEdges) {\n resistanceRatio = 0;\n }\n if ((diff > 0 && data.currentTranslate > swiper.minTranslate())) {\n disableParentSwiper = false;\n if (params.resistance) { data.currentTranslate = (swiper.minTranslate() - 1) + (Math.pow( (-swiper.minTranslate() + data.startTranslate + diff), resistanceRatio )); }\n } else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) {\n disableParentSwiper = false;\n if (params.resistance) { data.currentTranslate = (swiper.maxTranslate() + 1) - (Math.pow( (swiper.maxTranslate() - data.startTranslate - diff), resistanceRatio )); }\n }\n\n if (disableParentSwiper) {\n e.preventedByNestedSwiper = true;\n }\n\n // Directions locks\n if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {\n data.currentTranslate = data.startTranslate;\n }\n if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {\n data.currentTranslate = data.startTranslate;\n }\n\n\n // Threshold\n if (params.threshold > 0) {\n if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {\n if (!data.allowThresholdMove) {\n data.allowThresholdMove = true;\n touches.startX = touches.currentX;\n touches.startY = touches.currentY;\n data.currentTranslate = data.startTranslate;\n touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches.startY;\n return;\n }\n } else {\n data.currentTranslate = data.startTranslate;\n return;\n }\n }\n\n if (!params.followFinger) { return; }\n\n // Update active index in free mode\n if (params.freeMode || params.watchSlidesProgress || params.watchSlidesVisibility) {\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n if (params.freeMode) {\n // Velocity\n if (data.velocities.length === 0) {\n data.velocities.push({\n position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],\n time: data.touchStartTime,\n });\n }\n data.velocities.push({\n position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],\n time: Utils.now(),\n });\n }\n // Update progress\n swiper.updateProgress(data.currentTranslate);\n // Update translate\n swiper.setTranslate(data.currentTranslate);\n }\n\n function onTouchEnd (event) {\n var swiper = this;\n var data = swiper.touchEventsData;\n\n var params = swiper.params;\n var touches = swiper.touches;\n var rtl = swiper.rtlTranslate;\n var $wrapperEl = swiper.$wrapperEl;\n var slidesGrid = swiper.slidesGrid;\n var snapGrid = swiper.snapGrid;\n var e = event;\n if (e.originalEvent) { e = e.originalEvent; }\n if (data.allowTouchCallbacks) {\n swiper.emit('touchEnd', e);\n }\n data.allowTouchCallbacks = false;\n if (!data.isTouched) {\n if (data.isMoved && params.grabCursor) {\n swiper.setGrabCursor(false);\n }\n data.isMoved = false;\n data.startMoving = false;\n return;\n }\n // Return Grab Cursor\n if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {\n swiper.setGrabCursor(false);\n }\n\n // Time diff\n var touchEndTime = Utils.now();\n var timeDiff = touchEndTime - data.touchStartTime;\n\n // Tap, doubleTap, Click\n if (swiper.allowClick) {\n swiper.updateClickedSlide(e);\n swiper.emit('tap', e);\n if (timeDiff < 300 && (touchEndTime - data.lastClickTime) > 300) {\n if (data.clickTimeout) { clearTimeout(data.clickTimeout); }\n data.clickTimeout = Utils.nextTick(function () {\n if (!swiper || swiper.destroyed) { return; }\n swiper.emit('click', e);\n }, 300);\n }\n if (timeDiff < 300 && (touchEndTime - data.lastClickTime) < 300) {\n if (data.clickTimeout) { clearTimeout(data.clickTimeout); }\n swiper.emit('doubleTap', e);\n }\n }\n\n data.lastClickTime = Utils.now();\n Utils.nextTick(function () {\n if (!swiper.destroyed) { swiper.allowClick = true; }\n });\n\n if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate === data.startTranslate) {\n data.isTouched = false;\n data.isMoved = false;\n data.startMoving = false;\n return;\n }\n data.isTouched = false;\n data.isMoved = false;\n data.startMoving = false;\n\n var currentPos;\n if (params.followFinger) {\n currentPos = rtl ? swiper.translate : -swiper.translate;\n } else {\n currentPos = -data.currentTranslate;\n }\n\n if (params.freeMode) {\n if (currentPos < -swiper.minTranslate()) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n if (currentPos > -swiper.maxTranslate()) {\n if (swiper.slides.length < snapGrid.length) {\n swiper.slideTo(snapGrid.length - 1);\n } else {\n swiper.slideTo(swiper.slides.length - 1);\n }\n return;\n }\n\n if (params.freeModeMomentum) {\n if (data.velocities.length > 1) {\n var lastMoveEvent = data.velocities.pop();\n var velocityEvent = data.velocities.pop();\n\n var distance = lastMoveEvent.position - velocityEvent.position;\n var time = lastMoveEvent.time - velocityEvent.time;\n swiper.velocity = distance / time;\n swiper.velocity /= 2;\n if (Math.abs(swiper.velocity) < params.freeModeMinimumVelocity) {\n swiper.velocity = 0;\n }\n // this implies that the user stopped moving a finger then released.\n // There would be no events with distance zero, so the last event is stale.\n if (time > 150 || (Utils.now() - lastMoveEvent.time) > 300) {\n swiper.velocity = 0;\n }\n } else {\n swiper.velocity = 0;\n }\n swiper.velocity *= params.freeModeMomentumVelocityRatio;\n\n data.velocities.length = 0;\n var momentumDuration = 1000 * params.freeModeMomentumRatio;\n var momentumDistance = swiper.velocity * momentumDuration;\n\n var newPosition = swiper.translate + momentumDistance;\n if (rtl) { newPosition = -newPosition; }\n\n var doBounce = false;\n var afterBouncePosition;\n var bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeModeMomentumBounceRatio;\n var needsLoopFix;\n if (newPosition < swiper.maxTranslate()) {\n if (params.freeModeMomentumBounce) {\n if (newPosition + swiper.maxTranslate() < -bounceAmount) {\n newPosition = swiper.maxTranslate() - bounceAmount;\n }\n afterBouncePosition = swiper.maxTranslate();\n doBounce = true;\n data.allowMomentumBounce = true;\n } else {\n newPosition = swiper.maxTranslate();\n }\n if (params.loop && params.centeredSlides) { needsLoopFix = true; }\n } else if (newPosition > swiper.minTranslate()) {\n if (params.freeModeMomentumBounce) {\n if (newPosition - swiper.minTranslate() > bounceAmount) {\n newPosition = swiper.minTranslate() + bounceAmount;\n }\n afterBouncePosition = swiper.minTranslate();\n doBounce = true;\n data.allowMomentumBounce = true;\n } else {\n newPosition = swiper.minTranslate();\n }\n if (params.loop && params.centeredSlides) { needsLoopFix = true; }\n } else if (params.freeModeSticky) {\n var nextSlide;\n for (var j = 0; j < snapGrid.length; j += 1) {\n if (snapGrid[j] > -newPosition) {\n nextSlide = j;\n break;\n }\n }\n\n if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) || swiper.swipeDirection === 'next') {\n newPosition = snapGrid[nextSlide];\n } else {\n newPosition = snapGrid[nextSlide - 1];\n }\n newPosition = -newPosition;\n }\n if (needsLoopFix) {\n swiper.once('transitionEnd', function () {\n swiper.loopFix();\n });\n }\n // Fix duration\n if (swiper.velocity !== 0) {\n if (rtl) {\n momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);\n } else {\n momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);\n }\n } else if (params.freeModeSticky) {\n swiper.slideToClosest();\n return;\n }\n\n if (params.freeModeMomentumBounce && doBounce) {\n swiper.updateProgress(afterBouncePosition);\n swiper.setTransition(momentumDuration);\n swiper.setTranslate(newPosition);\n swiper.transitionStart(true, swiper.swipeDirection);\n swiper.animating = true;\n $wrapperEl.transitionEnd(function () {\n if (!swiper || swiper.destroyed || !data.allowMomentumBounce) { return; }\n swiper.emit('momentumBounce');\n\n swiper.setTransition(params.speed);\n swiper.setTranslate(afterBouncePosition);\n $wrapperEl.transitionEnd(function () {\n if (!swiper || swiper.destroyed) { return; }\n swiper.transitionEnd();\n });\n });\n } else if (swiper.velocity) {\n swiper.updateProgress(newPosition);\n swiper.setTransition(momentumDuration);\n swiper.setTranslate(newPosition);\n swiper.transitionStart(true, swiper.swipeDirection);\n if (!swiper.animating) {\n swiper.animating = true;\n $wrapperEl.transitionEnd(function () {\n if (!swiper || swiper.destroyed) { return; }\n swiper.transitionEnd();\n });\n }\n } else {\n swiper.updateProgress(newPosition);\n }\n\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n } else if (params.freeModeSticky) {\n swiper.slideToClosest();\n return;\n }\n\n if (!params.freeModeMomentum || timeDiff >= params.longSwipesMs) {\n swiper.updateProgress();\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n return;\n }\n\n // Find current slide\n var stopIndex = 0;\n var groupSize = swiper.slidesSizesGrid[0];\n for (var i = 0; i < slidesGrid.length; i += params.slidesPerGroup) {\n if (typeof slidesGrid[i + params.slidesPerGroup] !== 'undefined') {\n if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + params.slidesPerGroup]) {\n stopIndex = i;\n groupSize = slidesGrid[i + params.slidesPerGroup] - slidesGrid[i];\n }\n } else if (currentPos >= slidesGrid[i]) {\n stopIndex = i;\n groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];\n }\n }\n\n // Find current slide size\n var ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;\n\n if (timeDiff > params.longSwipesMs) {\n // Long touches\n if (!params.longSwipes) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n if (swiper.swipeDirection === 'next') {\n if (ratio >= params.longSwipesRatio) { swiper.slideTo(stopIndex + params.slidesPerGroup); }\n else { swiper.slideTo(stopIndex); }\n }\n if (swiper.swipeDirection === 'prev') {\n if (ratio > (1 - params.longSwipesRatio)) { swiper.slideTo(stopIndex + params.slidesPerGroup); }\n else { swiper.slideTo(stopIndex); }\n }\n } else {\n // Short swipes\n if (!params.shortSwipes) {\n swiper.slideTo(swiper.activeIndex);\n return;\n }\n if (swiper.swipeDirection === 'next') {\n swiper.slideTo(stopIndex + params.slidesPerGroup);\n }\n if (swiper.swipeDirection === 'prev') {\n swiper.slideTo(stopIndex);\n }\n }\n }\n\n function onResize () {\n var swiper = this;\n\n var params = swiper.params;\n var el = swiper.el;\n\n if (el && el.offsetWidth === 0) { return; }\n\n // Breakpoints\n if (params.breakpoints) {\n swiper.setBreakpoint();\n }\n\n // Save locks\n var allowSlideNext = swiper.allowSlideNext;\n var allowSlidePrev = swiper.allowSlidePrev;\n var snapGrid = swiper.snapGrid;\n\n // Disable locks on resize\n swiper.allowSlideNext = true;\n swiper.allowSlidePrev = true;\n\n swiper.updateSize();\n swiper.updateSlides();\n\n if (params.freeMode) {\n var newTranslate = Math.min(Math.max(swiper.translate, swiper.maxTranslate()), swiper.minTranslate());\n swiper.setTranslate(newTranslate);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n\n if (params.autoHeight) {\n swiper.updateAutoHeight();\n }\n } else {\n swiper.updateSlidesClasses();\n if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {\n swiper.slideTo(swiper.slides.length - 1, 0, false, true);\n } else {\n swiper.slideTo(swiper.activeIndex, 0, false, true);\n }\n }\n // Return locks after resize\n swiper.allowSlidePrev = allowSlidePrev;\n swiper.allowSlideNext = allowSlideNext;\n\n if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {\n swiper.checkOverflow();\n }\n }\n\n function onClick (e) {\n var swiper = this;\n if (!swiper.allowClick) {\n if (swiper.params.preventClicks) { e.preventDefault(); }\n if (swiper.params.preventClicksPropagation && swiper.animating) {\n e.stopPropagation();\n e.stopImmediatePropagation();\n }\n }\n }\n\n function attachEvents() {\n var swiper = this;\n var params = swiper.params;\n var touchEvents = swiper.touchEvents;\n var el = swiper.el;\n var wrapperEl = swiper.wrapperEl;\n\n {\n swiper.onTouchStart = onTouchStart.bind(swiper);\n swiper.onTouchMove = onTouchMove.bind(swiper);\n swiper.onTouchEnd = onTouchEnd.bind(swiper);\n }\n\n swiper.onClick = onClick.bind(swiper);\n\n var target = params.touchEventsTarget === 'container' ? el : wrapperEl;\n var capture = !!params.nested;\n\n // Touch Events\n {\n if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) {\n target.addEventListener(touchEvents.start, swiper.onTouchStart, false);\n doc.addEventListener(touchEvents.move, swiper.onTouchMove, capture);\n doc.addEventListener(touchEvents.end, swiper.onTouchEnd, false);\n } else {\n if (Support.touch) {\n var passiveListener = touchEvents.start === 'touchstart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;\n target.addEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);\n target.addEventListener(touchEvents.move, swiper.onTouchMove, Support.passiveListener ? { passive: false, capture: capture } : capture);\n target.addEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);\n }\n if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) {\n target.addEventListener('mousedown', swiper.onTouchStart, false);\n doc.addEventListener('mousemove', swiper.onTouchMove, capture);\n doc.addEventListener('mouseup', swiper.onTouchEnd, false);\n }\n }\n // Prevent Links Clicks\n if (params.preventClicks || params.preventClicksPropagation) {\n target.addEventListener('click', swiper.onClick, true);\n }\n }\n\n // Resize handler\n swiper.on((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize, true);\n }\n\n function detachEvents() {\n var swiper = this;\n\n var params = swiper.params;\n var touchEvents = swiper.touchEvents;\n var el = swiper.el;\n var wrapperEl = swiper.wrapperEl;\n\n var target = params.touchEventsTarget === 'container' ? el : wrapperEl;\n var capture = !!params.nested;\n\n // Touch Events\n {\n if (!Support.touch && (Support.pointerEvents || Support.prefixedPointerEvents)) {\n target.removeEventListener(touchEvents.start, swiper.onTouchStart, false);\n doc.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);\n doc.removeEventListener(touchEvents.end, swiper.onTouchEnd, false);\n } else {\n if (Support.touch) {\n var passiveListener = touchEvents.start === 'onTouchStart' && Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;\n target.removeEventListener(touchEvents.start, swiper.onTouchStart, passiveListener);\n target.removeEventListener(touchEvents.move, swiper.onTouchMove, capture);\n target.removeEventListener(touchEvents.end, swiper.onTouchEnd, passiveListener);\n }\n if ((params.simulateTouch && !Device.ios && !Device.android) || (params.simulateTouch && !Support.touch && Device.ios)) {\n target.removeEventListener('mousedown', swiper.onTouchStart, false);\n doc.removeEventListener('mousemove', swiper.onTouchMove, capture);\n doc.removeEventListener('mouseup', swiper.onTouchEnd, false);\n }\n }\n // Prevent Links Clicks\n if (params.preventClicks || params.preventClicksPropagation) {\n target.removeEventListener('click', swiper.onClick, true);\n }\n }\n\n // Resize handler\n swiper.off((Device.ios || Device.android ? 'resize orientationchange observerUpdate' : 'resize observerUpdate'), onResize);\n }\n\n var events = {\n attachEvents: attachEvents,\n detachEvents: detachEvents,\n };\n\n function setBreakpoint () {\n var swiper = this;\n var activeIndex = swiper.activeIndex;\n var initialized = swiper.initialized;\n var loopedSlides = swiper.loopedSlides; if ( loopedSlides === void 0 ) loopedSlides = 0;\n var params = swiper.params;\n var breakpoints = params.breakpoints;\n if (!breakpoints || (breakpoints && Object.keys(breakpoints).length === 0)) { return; }\n\n // Set breakpoint for window width and update parameters\n var breakpoint = swiper.getBreakpoint(breakpoints);\n\n if (breakpoint && swiper.currentBreakpoint !== breakpoint) {\n var breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;\n if (breakpointOnlyParams) {\n ['slidesPerView', 'spaceBetween', 'slidesPerGroup'].forEach(function (param) {\n var paramValue = breakpointOnlyParams[param];\n if (typeof paramValue === 'undefined') { return; }\n if (param === 'slidesPerView' && (paramValue === 'AUTO' || paramValue === 'auto')) {\n breakpointOnlyParams[param] = 'auto';\n } else if (param === 'slidesPerView') {\n breakpointOnlyParams[param] = parseFloat(paramValue);\n } else {\n breakpointOnlyParams[param] = parseInt(paramValue, 10);\n }\n });\n }\n\n var breakpointParams = breakpointOnlyParams || swiper.originalParams;\n var directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;\n var needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);\n\n if (directionChanged && initialized) {\n swiper.changeDirection();\n }\n\n Utils.extend(swiper.params, breakpointParams);\n\n Utils.extend(swiper, {\n allowTouchMove: swiper.params.allowTouchMove,\n allowSlideNext: swiper.params.allowSlideNext,\n allowSlidePrev: swiper.params.allowSlidePrev,\n });\n\n swiper.currentBreakpoint = breakpoint;\n\n if (needsReLoop && initialized) {\n swiper.loopDestroy();\n swiper.loopCreate();\n swiper.updateSlides();\n swiper.slideTo((activeIndex - loopedSlides) + swiper.loopedSlides, 0, false);\n }\n\n swiper.emit('breakpoint', breakpointParams);\n }\n }\n\n function getBreakpoint (breakpoints) {\n var swiper = this;\n // Get breakpoint for window width\n if (!breakpoints) { return undefined; }\n var breakpoint = false;\n var points = [];\n Object.keys(breakpoints).forEach(function (point) {\n points.push(point);\n });\n points.sort(function (a, b) { return parseInt(a, 10) - parseInt(b, 10); });\n for (var i = 0; i < points.length; i += 1) {\n var point = points[i];\n if (swiper.params.breakpointsInverse) {\n if (point <= win.innerWidth) {\n breakpoint = point;\n }\n } else if (point >= win.innerWidth && !breakpoint) {\n breakpoint = point;\n }\n }\n return breakpoint || 'max';\n }\n\n var breakpoints = { setBreakpoint: setBreakpoint, getBreakpoint: getBreakpoint };\n\n function addClasses () {\n var swiper = this;\n var classNames = swiper.classNames;\n var params = swiper.params;\n var rtl = swiper.rtl;\n var $el = swiper.$el;\n var suffixes = [];\n\n suffixes.push('initialized');\n suffixes.push(params.direction);\n\n if (params.freeMode) {\n suffixes.push('free-mode');\n }\n if (!Support.flexbox) {\n suffixes.push('no-flexbox');\n }\n if (params.autoHeight) {\n suffixes.push('autoheight');\n }\n if (rtl) {\n suffixes.push('rtl');\n }\n if (params.slidesPerColumn > 1) {\n suffixes.push('multirow');\n }\n if (Device.android) {\n suffixes.push('android');\n }\n if (Device.ios) {\n suffixes.push('ios');\n }\n // WP8 Touch Events Fix\n if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) {\n suffixes.push((\"wp8-\" + (params.direction)));\n }\n\n suffixes.forEach(function (suffix) {\n classNames.push(params.containerModifierClass + suffix);\n });\n\n $el.addClass(classNames.join(' '));\n }\n\n function removeClasses () {\n var swiper = this;\n var $el = swiper.$el;\n var classNames = swiper.classNames;\n\n $el.removeClass(classNames.join(' '));\n }\n\n var classes = { addClasses: addClasses, removeClasses: removeClasses };\n\n function loadImage (imageEl, src, srcset, sizes, checkForComplete, callback) {\n var image;\n function onReady() {\n if (callback) { callback(); }\n }\n if (!imageEl.complete || !checkForComplete) {\n if (src) {\n image = new win.Image();\n image.onload = onReady;\n image.onerror = onReady;\n if (sizes) {\n image.sizes = sizes;\n }\n if (srcset) {\n image.srcset = srcset;\n }\n if (src) {\n image.src = src;\n }\n } else {\n onReady();\n }\n } else {\n // image already loaded...\n onReady();\n }\n }\n\n function preloadImages () {\n var swiper = this;\n swiper.imagesToLoad = swiper.$el.find('img');\n function onReady() {\n if (typeof swiper === 'undefined' || swiper === null || !swiper || swiper.destroyed) { return; }\n if (swiper.imagesLoaded !== undefined) { swiper.imagesLoaded += 1; }\n if (swiper.imagesLoaded === swiper.imagesToLoad.length) {\n if (swiper.params.updateOnImagesReady) { swiper.update(); }\n swiper.emit('imagesReady');\n }\n }\n for (var i = 0; i < swiper.imagesToLoad.length; i += 1) {\n var imageEl = swiper.imagesToLoad[i];\n swiper.loadImage(\n imageEl,\n imageEl.currentSrc || imageEl.getAttribute('src'),\n imageEl.srcset || imageEl.getAttribute('srcset'),\n imageEl.sizes || imageEl.getAttribute('sizes'),\n true,\n onReady\n );\n }\n }\n\n var images = {\n loadImage: loadImage,\n preloadImages: preloadImages,\n };\n\n function checkOverflow() {\n var swiper = this;\n var wasLocked = swiper.isLocked;\n\n swiper.isLocked = swiper.snapGrid.length === 1;\n swiper.allowSlideNext = !swiper.isLocked;\n swiper.allowSlidePrev = !swiper.isLocked;\n\n // events\n if (wasLocked !== swiper.isLocked) { swiper.emit(swiper.isLocked ? 'lock' : 'unlock'); }\n\n if (wasLocked && wasLocked !== swiper.isLocked) {\n swiper.isEnd = false;\n swiper.navigation.update();\n }\n }\n\n var checkOverflow$1 = { checkOverflow: checkOverflow };\n\n var defaults = {\n init: true,\n direction: 'horizontal',\n touchEventsTarget: 'container',\n initialSlide: 0,\n speed: 300,\n //\n preventInteractionOnTransition: false,\n\n // To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).\n edgeSwipeDetection: false,\n edgeSwipeThreshold: 20,\n\n // Free mode\n freeMode: false,\n freeModeMomentum: true,\n freeModeMomentumRatio: 1,\n freeModeMomentumBounce: true,\n freeModeMomentumBounceRatio: 1,\n freeModeMomentumVelocityRatio: 1,\n freeModeSticky: false,\n freeModeMinimumVelocity: 0.02,\n\n // Autoheight\n autoHeight: false,\n\n // Set wrapper width\n setWrapperSize: false,\n\n // Virtual Translate\n virtualTranslate: false,\n\n // Effects\n effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'\n\n // Breakpoints\n breakpoints: undefined,\n breakpointsInverse: false,\n\n // Slides grid\n spaceBetween: 0,\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerColumnFill: 'column',\n slidesPerGroup: 1,\n centeredSlides: false,\n slidesOffsetBefore: 0, // in px\n slidesOffsetAfter: 0, // in px\n normalizeSlideIndex: true,\n centerInsufficientSlides: false,\n\n // Disable swiper and hide navigation when container not overflow\n watchOverflow: false,\n\n // Round length\n roundLengths: false,\n\n // Touches\n touchRatio: 1,\n touchAngle: 45,\n simulateTouch: true,\n shortSwipes: true,\n longSwipes: true,\n longSwipesRatio: 0.5,\n longSwipesMs: 300,\n followFinger: true,\n allowTouchMove: true,\n threshold: 0,\n touchMoveStopPropagation: true,\n touchStartPreventDefault: true,\n touchStartForcePreventDefault: false,\n touchReleaseOnEdges: false,\n\n // Unique Navigation Elements\n uniqueNavElements: true,\n\n // Resistance\n resistance: true,\n resistanceRatio: 0.85,\n\n // Progress\n watchSlidesProgress: false,\n watchSlidesVisibility: false,\n\n // Cursor\n grabCursor: false,\n\n // Clicks\n preventClicks: true,\n preventClicksPropagation: true,\n slideToClickedSlide: false,\n\n // Images\n preloadImages: true,\n updateOnImagesReady: true,\n\n // loop\n loop: false,\n loopAdditionalSlides: 0,\n loopedSlides: null,\n loopFillGroupWithBlank: false,\n\n // Swiping/no swiping\n allowSlidePrev: true,\n allowSlideNext: true,\n swipeHandler: null, // '.swipe-handler',\n noSwiping: true,\n noSwipingClass: 'swiper-no-swiping',\n noSwipingSelector: null,\n\n // Passive Listeners\n passiveListeners: true,\n\n // NS\n containerModifierClass: 'swiper-container-', // NEW\n slideClass: 'swiper-slide',\n slideBlankClass: 'swiper-slide-invisible-blank',\n slideActiveClass: 'swiper-slide-active',\n slideDuplicateActiveClass: 'swiper-slide-duplicate-active',\n slideVisibleClass: 'swiper-slide-visible',\n slideDuplicateClass: 'swiper-slide-duplicate',\n slideNextClass: 'swiper-slide-next',\n slideDuplicateNextClass: 'swiper-slide-duplicate-next',\n slidePrevClass: 'swiper-slide-prev',\n slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',\n wrapperClass: 'swiper-wrapper',\n\n // Callbacks\n runCallbacksOnInit: true,\n };\n\n /* eslint no-param-reassign: \"off\" */\n\n var prototypes = {\n update: update,\n translate: translate,\n transition: transition$1,\n slide: slide,\n loop: loop,\n grabCursor: grabCursor,\n manipulation: manipulation,\n events: events,\n breakpoints: breakpoints,\n checkOverflow: checkOverflow$1,\n classes: classes,\n images: images,\n };\n\n var extendedDefaults = {};\n\n var Swiper = /*@__PURE__*/(function (SwiperClass) {\n function Swiper() {\n var assign;\n\n var args = [], len = arguments.length;\n while ( len-- ) args[ len ] = arguments[ len ];\n var el;\n var params;\n if (args.length === 1 && args[0].constructor && args[0].constructor === Object) {\n params = args[0];\n } else {\n (assign = args, el = assign[0], params = assign[1]);\n }\n if (!params) { params = {}; }\n\n params = Utils.extend({}, params);\n if (el && !params.el) { params.el = el; }\n\n SwiperClass.call(this, params);\n\n Object.keys(prototypes).forEach(function (prototypeGroup) {\n Object.keys(prototypes[prototypeGroup]).forEach(function (protoMethod) {\n if (!Swiper.prototype[protoMethod]) {\n Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];\n }\n });\n });\n\n // Swiper Instance\n var swiper = this;\n if (typeof swiper.modules === 'undefined') {\n swiper.modules = {};\n }\n Object.keys(swiper.modules).forEach(function (moduleName) {\n var module = swiper.modules[moduleName];\n if (module.params) {\n var moduleParamName = Object.keys(module.params)[0];\n var moduleParams = module.params[moduleParamName];\n if (typeof moduleParams !== 'object' || moduleParams === null) { return; }\n if (!(moduleParamName in params && 'enabled' in moduleParams)) { return; }\n if (params[moduleParamName] === true) {\n params[moduleParamName] = { enabled: true };\n }\n if (\n typeof params[moduleParamName] === 'object'\n && !('enabled' in params[moduleParamName])\n ) {\n params[moduleParamName].enabled = true;\n }\n if (!params[moduleParamName]) { params[moduleParamName] = { enabled: false }; }\n }\n });\n\n // Extend defaults with modules params\n var swiperParams = Utils.extend({}, defaults);\n swiper.useModulesParams(swiperParams);\n\n // Extend defaults with passed params\n swiper.params = Utils.extend({}, swiperParams, extendedDefaults, params);\n swiper.originalParams = Utils.extend({}, swiper.params);\n swiper.passedParams = Utils.extend({}, params);\n\n // Save Dom lib\n swiper.$ = $;\n\n // Find el\n var $el = $(swiper.params.el);\n el = $el[0];\n\n if (!el) {\n return undefined;\n }\n\n if ($el.length > 1) {\n var swipers = [];\n $el.each(function (index, containerEl) {\n var newParams = Utils.extend({}, params, { el: containerEl });\n swipers.push(new Swiper(newParams));\n });\n return swipers;\n }\n\n el.swiper = swiper;\n $el.data('swiper', swiper);\n\n // Find Wrapper\n var $wrapperEl = $el.children((\".\" + (swiper.params.wrapperClass)));\n\n // Extend Swiper\n Utils.extend(swiper, {\n $el: $el,\n el: el,\n $wrapperEl: $wrapperEl,\n wrapperEl: $wrapperEl[0],\n\n // Classes\n classNames: [],\n\n // Slides\n slides: $(),\n slidesGrid: [],\n snapGrid: [],\n slidesSizesGrid: [],\n\n // isDirection\n isHorizontal: function isHorizontal() {\n return swiper.params.direction === 'horizontal';\n },\n isVertical: function isVertical() {\n return swiper.params.direction === 'vertical';\n },\n // RTL\n rtl: (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),\n rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),\n wrongRTL: $wrapperEl.css('display') === '-webkit-box',\n\n // Indexes\n activeIndex: 0,\n realIndex: 0,\n\n //\n isBeginning: true,\n isEnd: false,\n\n // Props\n translate: 0,\n previousTranslate: 0,\n progress: 0,\n velocity: 0,\n animating: false,\n\n // Locks\n allowSlideNext: swiper.params.allowSlideNext,\n allowSlidePrev: swiper.params.allowSlidePrev,\n\n // Touch Events\n touchEvents: (function touchEvents() {\n var touch = ['touchstart', 'touchmove', 'touchend'];\n var desktop = ['mousedown', 'mousemove', 'mouseup'];\n if (Support.pointerEvents) {\n desktop = ['pointerdown', 'pointermove', 'pointerup'];\n } else if (Support.prefixedPointerEvents) {\n desktop = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];\n }\n swiper.touchEventsTouch = {\n start: touch[0],\n move: touch[1],\n end: touch[2],\n };\n swiper.touchEventsDesktop = {\n start: desktop[0],\n move: desktop[1],\n end: desktop[2],\n };\n return Support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop;\n }()),\n touchEventsData: {\n isTouched: undefined,\n isMoved: undefined,\n allowTouchCallbacks: undefined,\n touchStartTime: undefined,\n isScrolling: undefined,\n currentTranslate: undefined,\n startTranslate: undefined,\n allowThresholdMove: undefined,\n // Form elements to match\n formElements: 'input, select, option, textarea, button, video',\n // Last click time\n lastClickTime: Utils.now(),\n clickTimeout: undefined,\n // Velocities\n velocities: [],\n allowMomentumBounce: undefined,\n isTouchEvent: undefined,\n startMoving: undefined,\n },\n\n // Clicks\n allowClick: true,\n\n // Touches\n allowTouchMove: swiper.params.allowTouchMove,\n\n touches: {\n startX: 0,\n startY: 0,\n currentX: 0,\n currentY: 0,\n diff: 0,\n },\n\n // Images\n imagesToLoad: [],\n imagesLoaded: 0,\n\n });\n\n // Install Modules\n swiper.useModules();\n\n // Init\n if (swiper.params.init) {\n swiper.init();\n }\n\n // Return app instance\n return swiper;\n }\n\n if ( SwiperClass ) Swiper.__proto__ = SwiperClass;\n Swiper.prototype = Object.create( SwiperClass && SwiperClass.prototype );\n Swiper.prototype.constructor = Swiper;\n\n var staticAccessors = { extendedDefaults: { configurable: true },defaults: { configurable: true },Class: { configurable: true },$: { configurable: true } };\n\n Swiper.prototype.slidesPerViewDynamic = function slidesPerViewDynamic () {\n var swiper = this;\n var params = swiper.params;\n var slides = swiper.slides;\n var slidesGrid = swiper.slidesGrid;\n var swiperSize = swiper.size;\n var activeIndex = swiper.activeIndex;\n var spv = 1;\n if (params.centeredSlides) {\n var slideSize = slides[activeIndex].swiperSlideSize;\n var breakLoop;\n for (var i = activeIndex + 1; i < slides.length; i += 1) {\n if (slides[i] && !breakLoop) {\n slideSize += slides[i].swiperSlideSize;\n spv += 1;\n if (slideSize > swiperSize) { breakLoop = true; }\n }\n }\n for (var i$1 = activeIndex - 1; i$1 >= 0; i$1 -= 1) {\n if (slides[i$1] && !breakLoop) {\n slideSize += slides[i$1].swiperSlideSize;\n spv += 1;\n if (slideSize > swiperSize) { breakLoop = true; }\n }\n }\n } else {\n for (var i$2 = activeIndex + 1; i$2 < slides.length; i$2 += 1) {\n if (slidesGrid[i$2] - slidesGrid[activeIndex] < swiperSize) {\n spv += 1;\n }\n }\n }\n return spv;\n };\n\n Swiper.prototype.update = function update () {\n var swiper = this;\n if (!swiper || swiper.destroyed) { return; }\n var snapGrid = swiper.snapGrid;\n var params = swiper.params;\n // Breakpoints\n if (params.breakpoints) {\n swiper.setBreakpoint();\n }\n swiper.updateSize();\n swiper.updateSlides();\n swiper.updateProgress();\n swiper.updateSlidesClasses();\n\n function setTranslate() {\n var translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;\n var newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());\n swiper.setTranslate(newTranslate);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n }\n var translated;\n if (swiper.params.freeMode) {\n setTranslate();\n if (swiper.params.autoHeight) {\n swiper.updateAutoHeight();\n }\n } else {\n if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {\n translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);\n } else {\n translated = swiper.slideTo(swiper.activeIndex, 0, false, true);\n }\n if (!translated) {\n setTranslate();\n }\n }\n if (params.watchOverflow && snapGrid !== swiper.snapGrid) {\n swiper.checkOverflow();\n }\n swiper.emit('update');\n };\n\n Swiper.prototype.changeDirection = function changeDirection (newDirection, needUpdate) {\n if ( needUpdate === void 0 ) needUpdate = true;\n\n var swiper = this;\n var currentDirection = swiper.params.direction;\n if (!newDirection) {\n // eslint-disable-next-line\n newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';\n }\n if ((newDirection === currentDirection) || (newDirection !== 'horizontal' && newDirection !== 'vertical')) {\n return swiper;\n }\n\n if (currentDirection === 'vertical') {\n swiper.$el\n .removeClass(((swiper.params.containerModifierClass) + \"vertical wp8-vertical\"))\n .addClass((\"\" + (swiper.params.containerModifierClass) + newDirection));\n\n if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) {\n swiper.$el.addClass(((swiper.params.containerModifierClass) + \"wp8-\" + newDirection));\n }\n }\n if (currentDirection === 'horizontal') {\n swiper.$el\n .removeClass(((swiper.params.containerModifierClass) + \"horizontal wp8-horizontal\"))\n .addClass((\"\" + (swiper.params.containerModifierClass) + newDirection));\n\n if ((Browser.isIE || Browser.isEdge) && (Support.pointerEvents || Support.prefixedPointerEvents)) {\n swiper.$el.addClass(((swiper.params.containerModifierClass) + \"wp8-\" + newDirection));\n }\n }\n\n swiper.params.direction = newDirection;\n\n swiper.slides.each(function (slideIndex, slideEl) {\n if (newDirection === 'vertical') {\n slideEl.style.width = '';\n } else {\n slideEl.style.height = '';\n }\n });\n\n swiper.emit('changeDirection');\n if (needUpdate) { swiper.update(); }\n\n return swiper;\n };\n\n Swiper.prototype.init = function init () {\n var swiper = this;\n if (swiper.initialized) { return; }\n\n swiper.emit('beforeInit');\n\n // Set breakpoint\n if (swiper.params.breakpoints) {\n swiper.setBreakpoint();\n }\n\n // Add Classes\n swiper.addClasses();\n\n // Create loop\n if (swiper.params.loop) {\n swiper.loopCreate();\n }\n\n // Update size\n swiper.updateSize();\n\n // Update slides\n swiper.updateSlides();\n\n if (swiper.params.watchOverflow) {\n swiper.checkOverflow();\n }\n\n // Set Grab Cursor\n if (swiper.params.grabCursor) {\n swiper.setGrabCursor();\n }\n\n if (swiper.params.preloadImages) {\n swiper.preloadImages();\n }\n\n // Slide To Initial Slide\n if (swiper.params.loop) {\n swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit);\n } else {\n swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit);\n }\n\n // Attach events\n swiper.attachEvents();\n\n // Init Flag\n swiper.initialized = true;\n\n // Emit\n swiper.emit('init');\n };\n\n Swiper.prototype.destroy = function destroy (deleteInstance, cleanStyles) {\n if ( deleteInstance === void 0 ) deleteInstance = true;\n if ( cleanStyles === void 0 ) cleanStyles = true;\n\n var swiper = this;\n var params = swiper.params;\n var $el = swiper.$el;\n var $wrapperEl = swiper.$wrapperEl;\n var slides = swiper.slides;\n\n if (typeof swiper.params === 'undefined' || swiper.destroyed) {\n return null;\n }\n\n swiper.emit('beforeDestroy');\n\n // Init Flag\n swiper.initialized = false;\n\n // Detach events\n swiper.detachEvents();\n\n // Destroy loop\n if (params.loop) {\n swiper.loopDestroy();\n }\n\n // Cleanup styles\n if (cleanStyles) {\n swiper.removeClasses();\n $el.removeAttr('style');\n $wrapperEl.removeAttr('style');\n if (slides && slides.length) {\n slides\n .removeClass([\n params.slideVisibleClass,\n params.slideActiveClass,\n params.slideNextClass,\n params.slidePrevClass ].join(' '))\n .removeAttr('style')\n .removeAttr('data-swiper-slide-index')\n .removeAttr('data-swiper-column')\n .removeAttr('data-swiper-row');\n }\n }\n\n swiper.emit('destroy');\n\n // Detach emitter events\n Object.keys(swiper.eventsListeners).forEach(function (eventName) {\n swiper.off(eventName);\n });\n\n if (deleteInstance !== false) {\n swiper.$el[0].swiper = null;\n swiper.$el.data('swiper', null);\n Utils.deleteProps(swiper);\n }\n swiper.destroyed = true;\n\n return null;\n };\n\n Swiper.extendDefaults = function extendDefaults (newDefaults) {\n Utils.extend(extendedDefaults, newDefaults);\n };\n\n staticAccessors.extendedDefaults.get = function () {\n return extendedDefaults;\n };\n\n staticAccessors.defaults.get = function () {\n return defaults;\n };\n\n staticAccessors.Class.get = function () {\n return SwiperClass;\n };\n\n staticAccessors.$.get = function () {\n return $;\n };\n\n Object.defineProperties( Swiper, staticAccessors );\n\n return Swiper;\n }(SwiperClass));\n\n var Device$1 = {\n name: 'device',\n proto: {\n device: Device,\n },\n static: {\n device: Device,\n },\n };\n\n var Support$1 = {\n name: 'support',\n proto: {\n support: Support,\n },\n static: {\n support: Support,\n },\n };\n\n var Browser$1 = {\n name: 'browser',\n proto: {\n browser: Browser,\n },\n static: {\n browser: Browser,\n },\n };\n\n var Resize = {\n name: 'resize',\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n resize: {\n resizeHandler: function resizeHandler() {\n if (!swiper || swiper.destroyed || !swiper.initialized) { return; }\n swiper.emit('beforeResize');\n swiper.emit('resize');\n },\n orientationChangeHandler: function orientationChangeHandler() {\n if (!swiper || swiper.destroyed || !swiper.initialized) { return; }\n swiper.emit('orientationchange');\n },\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n // Emit resize\n win.addEventListener('resize', swiper.resize.resizeHandler);\n\n // Emit orientationchange\n win.addEventListener('orientationchange', swiper.resize.orientationChangeHandler);\n },\n destroy: function destroy() {\n var swiper = this;\n win.removeEventListener('resize', swiper.resize.resizeHandler);\n win.removeEventListener('orientationchange', swiper.resize.orientationChangeHandler);\n },\n },\n };\n\n var Observer = {\n func: win.MutationObserver || win.WebkitMutationObserver,\n attach: function attach(target, options) {\n if ( options === void 0 ) options = {};\n\n var swiper = this;\n\n var ObserverFunc = Observer.func;\n var observer = new ObserverFunc(function (mutations) {\n // The observerUpdate event should only be triggered\n // once despite the number of mutations. Additional\n // triggers are redundant and are very costly\n if (mutations.length === 1) {\n swiper.emit('observerUpdate', mutations[0]);\n return;\n }\n var observerUpdate = function observerUpdate() {\n swiper.emit('observerUpdate', mutations[0]);\n };\n\n if (win.requestAnimationFrame) {\n win.requestAnimationFrame(observerUpdate);\n } else {\n win.setTimeout(observerUpdate, 0);\n }\n });\n\n observer.observe(target, {\n attributes: typeof options.attributes === 'undefined' ? true : options.attributes,\n childList: typeof options.childList === 'undefined' ? true : options.childList,\n characterData: typeof options.characterData === 'undefined' ? true : options.characterData,\n });\n\n swiper.observer.observers.push(observer);\n },\n init: function init() {\n var swiper = this;\n if (!Support.observer || !swiper.params.observer) { return; }\n if (swiper.params.observeParents) {\n var containerParents = swiper.$el.parents();\n for (var i = 0; i < containerParents.length; i += 1) {\n swiper.observer.attach(containerParents[i]);\n }\n }\n // Observe container\n swiper.observer.attach(swiper.$el[0], { childList: swiper.params.observeSlideChildren });\n\n // Observe wrapper\n swiper.observer.attach(swiper.$wrapperEl[0], { attributes: false });\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.observer.observers.forEach(function (observer) {\n observer.disconnect();\n });\n swiper.observer.observers = [];\n },\n };\n\n var Observer$1 = {\n name: 'observer',\n params: {\n observer: false,\n observeParents: false,\n observeSlideChildren: false,\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n observer: {\n init: Observer.init.bind(swiper),\n attach: Observer.attach.bind(swiper),\n destroy: Observer.destroy.bind(swiper),\n observers: [],\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n swiper.observer.init();\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.observer.destroy();\n },\n },\n };\n\n var Virtual = {\n update: function update(force) {\n var swiper = this;\n var ref = swiper.params;\n var slidesPerView = ref.slidesPerView;\n var slidesPerGroup = ref.slidesPerGroup;\n var centeredSlides = ref.centeredSlides;\n var ref$1 = swiper.params.virtual;\n var addSlidesBefore = ref$1.addSlidesBefore;\n var addSlidesAfter = ref$1.addSlidesAfter;\n var ref$2 = swiper.virtual;\n var previousFrom = ref$2.from;\n var previousTo = ref$2.to;\n var slides = ref$2.slides;\n var previousSlidesGrid = ref$2.slidesGrid;\n var renderSlide = ref$2.renderSlide;\n var previousOffset = ref$2.offset;\n swiper.updateActiveIndex();\n var activeIndex = swiper.activeIndex || 0;\n\n var offsetProp;\n if (swiper.rtlTranslate) { offsetProp = 'right'; }\n else { offsetProp = swiper.isHorizontal() ? 'left' : 'top'; }\n\n var slidesAfter;\n var slidesBefore;\n if (centeredSlides) {\n slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;\n slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;\n } else {\n slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesBefore;\n slidesBefore = slidesPerGroup + addSlidesAfter;\n }\n var from = Math.max((activeIndex || 0) - slidesBefore, 0);\n var to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);\n var offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);\n\n Utils.extend(swiper.virtual, {\n from: from,\n to: to,\n offset: offset,\n slidesGrid: swiper.slidesGrid,\n });\n\n function onRendered() {\n swiper.updateSlides();\n swiper.updateProgress();\n swiper.updateSlidesClasses();\n if (swiper.lazy && swiper.params.lazy.enabled) {\n swiper.lazy.load();\n }\n }\n\n if (previousFrom === from && previousTo === to && !force) {\n if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {\n swiper.slides.css(offsetProp, (offset + \"px\"));\n }\n swiper.updateProgress();\n return;\n }\n if (swiper.params.virtual.renderExternal) {\n swiper.params.virtual.renderExternal.call(swiper, {\n offset: offset,\n from: from,\n to: to,\n slides: (function getSlides() {\n var slidesToRender = [];\n for (var i = from; i <= to; i += 1) {\n slidesToRender.push(slides[i]);\n }\n return slidesToRender;\n }()),\n });\n onRendered();\n return;\n }\n var prependIndexes = [];\n var appendIndexes = [];\n if (force) {\n swiper.$wrapperEl.find((\".\" + (swiper.params.slideClass))).remove();\n } else {\n for (var i = previousFrom; i <= previousTo; i += 1) {\n if (i < from || i > to) {\n swiper.$wrapperEl.find((\".\" + (swiper.params.slideClass) + \"[data-swiper-slide-index=\\\"\" + i + \"\\\"]\")).remove();\n }\n }\n }\n for (var i$1 = 0; i$1 < slides.length; i$1 += 1) {\n if (i$1 >= from && i$1 <= to) {\n if (typeof previousTo === 'undefined' || force) {\n appendIndexes.push(i$1);\n } else {\n if (i$1 > previousTo) { appendIndexes.push(i$1); }\n if (i$1 < previousFrom) { prependIndexes.push(i$1); }\n }\n }\n }\n appendIndexes.forEach(function (index) {\n swiper.$wrapperEl.append(renderSlide(slides[index], index));\n });\n prependIndexes.sort(function (a, b) { return b - a; }).forEach(function (index) {\n swiper.$wrapperEl.prepend(renderSlide(slides[index], index));\n });\n swiper.$wrapperEl.children('.swiper-slide').css(offsetProp, (offset + \"px\"));\n onRendered();\n },\n renderSlide: function renderSlide(slide, index) {\n var swiper = this;\n var params = swiper.params.virtual;\n if (params.cache && swiper.virtual.cache[index]) {\n return swiper.virtual.cache[index];\n }\n var $slideEl = params.renderSlide\n ? $(params.renderSlide.call(swiper, slide, index))\n : $((\"
            \" + slide + \"
            \"));\n if (!$slideEl.attr('data-swiper-slide-index')) { $slideEl.attr('data-swiper-slide-index', index); }\n if (params.cache) { swiper.virtual.cache[index] = $slideEl; }\n return $slideEl;\n },\n appendSlide: function appendSlide(slides) {\n var swiper = this;\n if (typeof slides === 'object' && 'length' in slides) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) { swiper.virtual.slides.push(slides[i]); }\n }\n } else {\n swiper.virtual.slides.push(slides);\n }\n swiper.virtual.update(true);\n },\n prependSlide: function prependSlide(slides) {\n var swiper = this;\n var activeIndex = swiper.activeIndex;\n var newActiveIndex = activeIndex + 1;\n var numberOfNewSlides = 1;\n\n if (Array.isArray(slides)) {\n for (var i = 0; i < slides.length; i += 1) {\n if (slides[i]) { swiper.virtual.slides.unshift(slides[i]); }\n }\n newActiveIndex = activeIndex + slides.length;\n numberOfNewSlides = slides.length;\n } else {\n swiper.virtual.slides.unshift(slides);\n }\n if (swiper.params.virtual.cache) {\n var cache = swiper.virtual.cache;\n var newCache = {};\n Object.keys(cache).forEach(function (cachedIndex) {\n newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cache[cachedIndex];\n });\n swiper.virtual.cache = newCache;\n }\n swiper.virtual.update(true);\n swiper.slideTo(newActiveIndex, 0);\n },\n removeSlide: function removeSlide(slidesIndexes) {\n var swiper = this;\n if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) { return; }\n var activeIndex = swiper.activeIndex;\n if (Array.isArray(slidesIndexes)) {\n for (var i = slidesIndexes.length - 1; i >= 0; i -= 1) {\n swiper.virtual.slides.splice(slidesIndexes[i], 1);\n if (swiper.params.virtual.cache) {\n delete swiper.virtual.cache[slidesIndexes[i]];\n }\n if (slidesIndexes[i] < activeIndex) { activeIndex -= 1; }\n activeIndex = Math.max(activeIndex, 0);\n }\n } else {\n swiper.virtual.slides.splice(slidesIndexes, 1);\n if (swiper.params.virtual.cache) {\n delete swiper.virtual.cache[slidesIndexes];\n }\n if (slidesIndexes < activeIndex) { activeIndex -= 1; }\n activeIndex = Math.max(activeIndex, 0);\n }\n swiper.virtual.update(true);\n swiper.slideTo(activeIndex, 0);\n },\n removeAllSlides: function removeAllSlides() {\n var swiper = this;\n swiper.virtual.slides = [];\n if (swiper.params.virtual.cache) {\n swiper.virtual.cache = {};\n }\n swiper.virtual.update(true);\n swiper.slideTo(0, 0);\n },\n };\n\n var Virtual$1 = {\n name: 'virtual',\n params: {\n virtual: {\n enabled: false,\n slides: [],\n cache: true,\n renderSlide: null,\n renderExternal: null,\n addSlidesBefore: 0,\n addSlidesAfter: 0,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n virtual: {\n update: Virtual.update.bind(swiper),\n appendSlide: Virtual.appendSlide.bind(swiper),\n prependSlide: Virtual.prependSlide.bind(swiper),\n removeSlide: Virtual.removeSlide.bind(swiper),\n removeAllSlides: Virtual.removeAllSlides.bind(swiper),\n renderSlide: Virtual.renderSlide.bind(swiper),\n slides: swiper.params.virtual.slides,\n cache: {},\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n if (!swiper.params.virtual.enabled) { return; }\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"virtual\"));\n var overwriteParams = {\n watchSlidesProgress: true,\n };\n Utils.extend(swiper.params, overwriteParams);\n Utils.extend(swiper.originalParams, overwriteParams);\n\n if (!swiper.params.initialSlide) {\n swiper.virtual.update();\n }\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n if (!swiper.params.virtual.enabled) { return; }\n swiper.virtual.update();\n },\n },\n };\n\n var Keyboard = {\n handle: function handle(event) {\n var swiper = this;\n var rtl = swiper.rtlTranslate;\n var e = event;\n if (e.originalEvent) { e = e.originalEvent; } // jquery fix\n var kc = e.keyCode || e.charCode;\n // Directions locks\n if (!swiper.allowSlideNext && ((swiper.isHorizontal() && kc === 39) || (swiper.isVertical() && kc === 40))) {\n return false;\n }\n if (!swiper.allowSlidePrev && ((swiper.isHorizontal() && kc === 37) || (swiper.isVertical() && kc === 38))) {\n return false;\n }\n if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {\n return undefined;\n }\n if (doc.activeElement && doc.activeElement.nodeName && (doc.activeElement.nodeName.toLowerCase() === 'input' || doc.activeElement.nodeName.toLowerCase() === 'textarea')) {\n return undefined;\n }\n if (swiper.params.keyboard.onlyInViewport && (kc === 37 || kc === 39 || kc === 38 || kc === 40)) {\n var inView = false;\n // Check that swiper should be inside of visible area of window\n if (swiper.$el.parents((\".\" + (swiper.params.slideClass))).length > 0 && swiper.$el.parents((\".\" + (swiper.params.slideActiveClass))).length === 0) {\n return undefined;\n }\n var windowWidth = win.innerWidth;\n var windowHeight = win.innerHeight;\n var swiperOffset = swiper.$el.offset();\n if (rtl) { swiperOffset.left -= swiper.$el[0].scrollLeft; }\n var swiperCoord = [\n [swiperOffset.left, swiperOffset.top],\n [swiperOffset.left + swiper.width, swiperOffset.top],\n [swiperOffset.left, swiperOffset.top + swiper.height],\n [swiperOffset.left + swiper.width, swiperOffset.top + swiper.height] ];\n for (var i = 0; i < swiperCoord.length; i += 1) {\n var point = swiperCoord[i];\n if (\n point[0] >= 0 && point[0] <= windowWidth\n && point[1] >= 0 && point[1] <= windowHeight\n ) {\n inView = true;\n }\n }\n if (!inView) { return undefined; }\n }\n if (swiper.isHorizontal()) {\n if (kc === 37 || kc === 39) {\n if (e.preventDefault) { e.preventDefault(); }\n else { e.returnValue = false; }\n }\n if ((kc === 39 && !rtl) || (kc === 37 && rtl)) { swiper.slideNext(); }\n if ((kc === 37 && !rtl) || (kc === 39 && rtl)) { swiper.slidePrev(); }\n } else {\n if (kc === 38 || kc === 40) {\n if (e.preventDefault) { e.preventDefault(); }\n else { e.returnValue = false; }\n }\n if (kc === 40) { swiper.slideNext(); }\n if (kc === 38) { swiper.slidePrev(); }\n }\n swiper.emit('keyPress', kc);\n return undefined;\n },\n enable: function enable() {\n var swiper = this;\n if (swiper.keyboard.enabled) { return; }\n $(doc).on('keydown', swiper.keyboard.handle);\n swiper.keyboard.enabled = true;\n },\n disable: function disable() {\n var swiper = this;\n if (!swiper.keyboard.enabled) { return; }\n $(doc).off('keydown', swiper.keyboard.handle);\n swiper.keyboard.enabled = false;\n },\n };\n\n var Keyboard$1 = {\n name: 'keyboard',\n params: {\n keyboard: {\n enabled: false,\n onlyInViewport: true,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n keyboard: {\n enabled: false,\n enable: Keyboard.enable.bind(swiper),\n disable: Keyboard.disable.bind(swiper),\n handle: Keyboard.handle.bind(swiper),\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n if (swiper.params.keyboard.enabled) {\n swiper.keyboard.enable();\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.keyboard.enabled) {\n swiper.keyboard.disable();\n }\n },\n },\n };\n\n function isEventSupported() {\n var eventName = 'onwheel';\n var isSupported = eventName in doc;\n\n if (!isSupported) {\n var element = doc.createElement('div');\n element.setAttribute(eventName, 'return;');\n isSupported = typeof element[eventName] === 'function';\n }\n\n if (!isSupported\n && doc.implementation\n && doc.implementation.hasFeature\n // always returns true in newer browsers as per the standard.\n // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature\n && doc.implementation.hasFeature('', '') !== true\n ) {\n // This is the only way to test support for the `wheel` event in IE9+.\n isSupported = doc.implementation.hasFeature('Events.wheel', '3.0');\n }\n\n return isSupported;\n }\n var Mousewheel = {\n lastScrollTime: Utils.now(),\n event: (function getEvent() {\n if (win.navigator.userAgent.indexOf('firefox') > -1) { return 'DOMMouseScroll'; }\n return isEventSupported() ? 'wheel' : 'mousewheel';\n }()),\n normalize: function normalize(e) {\n // Reasonable defaults\n var PIXEL_STEP = 10;\n var LINE_HEIGHT = 40;\n var PAGE_HEIGHT = 800;\n\n var sX = 0;\n var sY = 0; // spinX, spinY\n var pX = 0;\n var pY = 0; // pixelX, pixelY\n\n // Legacy\n if ('detail' in e) {\n sY = e.detail;\n }\n if ('wheelDelta' in e) {\n sY = -e.wheelDelta / 120;\n }\n if ('wheelDeltaY' in e) {\n sY = -e.wheelDeltaY / 120;\n }\n if ('wheelDeltaX' in e) {\n sX = -e.wheelDeltaX / 120;\n }\n\n // side scrolling on FF with DOMMouseScroll\n if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {\n sX = sY;\n sY = 0;\n }\n\n pX = sX * PIXEL_STEP;\n pY = sY * PIXEL_STEP;\n\n if ('deltaY' in e) {\n pY = e.deltaY;\n }\n if ('deltaX' in e) {\n pX = e.deltaX;\n }\n\n if ((pX || pY) && e.deltaMode) {\n if (e.deltaMode === 1) { // delta in LINE units\n pX *= LINE_HEIGHT;\n pY *= LINE_HEIGHT;\n } else { // delta in PAGE units\n pX *= PAGE_HEIGHT;\n pY *= PAGE_HEIGHT;\n }\n }\n\n // Fall-back if spin cannot be determined\n if (pX && !sX) {\n sX = (pX < 1) ? -1 : 1;\n }\n if (pY && !sY) {\n sY = (pY < 1) ? -1 : 1;\n }\n\n return {\n spinX: sX,\n spinY: sY,\n pixelX: pX,\n pixelY: pY,\n };\n },\n handleMouseEnter: function handleMouseEnter() {\n var swiper = this;\n swiper.mouseEntered = true;\n },\n handleMouseLeave: function handleMouseLeave() {\n var swiper = this;\n swiper.mouseEntered = false;\n },\n handle: function handle(event) {\n var e = event;\n var swiper = this;\n var params = swiper.params.mousewheel;\n\n if (!swiper.mouseEntered && !params.releaseOnEdges) { return true; }\n\n if (e.originalEvent) { e = e.originalEvent; } // jquery fix\n var delta = 0;\n var rtlFactor = swiper.rtlTranslate ? -1 : 1;\n\n var data = Mousewheel.normalize(e);\n\n if (params.forceToAxis) {\n if (swiper.isHorizontal()) {\n if (Math.abs(data.pixelX) > Math.abs(data.pixelY)) { delta = data.pixelX * rtlFactor; }\n else { return true; }\n } else if (Math.abs(data.pixelY) > Math.abs(data.pixelX)) { delta = data.pixelY; }\n else { return true; }\n } else {\n delta = Math.abs(data.pixelX) > Math.abs(data.pixelY) ? -data.pixelX * rtlFactor : -data.pixelY;\n }\n\n if (delta === 0) { return true; }\n\n if (params.invert) { delta = -delta; }\n\n if (!swiper.params.freeMode) {\n if (Utils.now() - swiper.mousewheel.lastScrollTime > 60) {\n if (delta < 0) {\n if ((!swiper.isEnd || swiper.params.loop) && !swiper.animating) {\n swiper.slideNext();\n swiper.emit('scroll', e);\n } else if (params.releaseOnEdges) { return true; }\n } else if ((!swiper.isBeginning || swiper.params.loop) && !swiper.animating) {\n swiper.slidePrev();\n swiper.emit('scroll', e);\n } else if (params.releaseOnEdges) { return true; }\n }\n swiper.mousewheel.lastScrollTime = (new win.Date()).getTime();\n } else {\n // Freemode or scrollContainer:\n if (swiper.params.loop) {\n swiper.loopFix();\n }\n var position = swiper.getTranslate() + (delta * params.sensitivity);\n var wasBeginning = swiper.isBeginning;\n var wasEnd = swiper.isEnd;\n\n if (position >= swiper.minTranslate()) { position = swiper.minTranslate(); }\n if (position <= swiper.maxTranslate()) { position = swiper.maxTranslate(); }\n\n swiper.setTransition(0);\n swiper.setTranslate(position);\n swiper.updateProgress();\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n\n if ((!wasBeginning && swiper.isBeginning) || (!wasEnd && swiper.isEnd)) {\n swiper.updateSlidesClasses();\n }\n\n if (swiper.params.freeModeSticky) {\n clearTimeout(swiper.mousewheel.timeout);\n swiper.mousewheel.timeout = Utils.nextTick(function () {\n swiper.slideToClosest();\n }, 300);\n }\n // Emit event\n swiper.emit('scroll', e);\n\n // Stop autoplay\n if (swiper.params.autoplay && swiper.params.autoplayDisableOnInteraction) { swiper.autoplay.stop(); }\n // Return page scroll on edge positions\n if (position === swiper.minTranslate() || position === swiper.maxTranslate()) { return true; }\n }\n\n if (e.preventDefault) { e.preventDefault(); }\n else { e.returnValue = false; }\n return false;\n },\n enable: function enable() {\n var swiper = this;\n if (!Mousewheel.event) { return false; }\n if (swiper.mousewheel.enabled) { return false; }\n var target = swiper.$el;\n if (swiper.params.mousewheel.eventsTarged !== 'container') {\n target = $(swiper.params.mousewheel.eventsTarged);\n }\n target.on('mouseenter', swiper.mousewheel.handleMouseEnter);\n target.on('mouseleave', swiper.mousewheel.handleMouseLeave);\n target.on(Mousewheel.event, swiper.mousewheel.handle);\n swiper.mousewheel.enabled = true;\n return true;\n },\n disable: function disable() {\n var swiper = this;\n if (!Mousewheel.event) { return false; }\n if (!swiper.mousewheel.enabled) { return false; }\n var target = swiper.$el;\n if (swiper.params.mousewheel.eventsTarged !== 'container') {\n target = $(swiper.params.mousewheel.eventsTarged);\n }\n target.off(Mousewheel.event, swiper.mousewheel.handle);\n swiper.mousewheel.enabled = false;\n return true;\n },\n };\n\n var Mousewheel$1 = {\n name: 'mousewheel',\n params: {\n mousewheel: {\n enabled: false,\n releaseOnEdges: false,\n invert: false,\n forceToAxis: false,\n sensitivity: 1,\n eventsTarged: 'container',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n mousewheel: {\n enabled: false,\n enable: Mousewheel.enable.bind(swiper),\n disable: Mousewheel.disable.bind(swiper),\n handle: Mousewheel.handle.bind(swiper),\n handleMouseEnter: Mousewheel.handleMouseEnter.bind(swiper),\n handleMouseLeave: Mousewheel.handleMouseLeave.bind(swiper),\n lastScrollTime: Utils.now(),\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n if (swiper.params.mousewheel.enabled) { swiper.mousewheel.enable(); }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.mousewheel.enabled) { swiper.mousewheel.disable(); }\n },\n },\n };\n\n var Navigation = {\n update: function update() {\n // Update Navigation Buttons\n var swiper = this;\n var params = swiper.params.navigation;\n\n if (swiper.params.loop) { return; }\n var ref = swiper.navigation;\n var $nextEl = ref.$nextEl;\n var $prevEl = ref.$prevEl;\n\n if ($prevEl && $prevEl.length > 0) {\n if (swiper.isBeginning) {\n $prevEl.addClass(params.disabledClass);\n } else {\n $prevEl.removeClass(params.disabledClass);\n }\n $prevEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n }\n if ($nextEl && $nextEl.length > 0) {\n if (swiper.isEnd) {\n $nextEl.addClass(params.disabledClass);\n } else {\n $nextEl.removeClass(params.disabledClass);\n }\n $nextEl[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n }\n },\n onPrevClick: function onPrevClick(e) {\n var swiper = this;\n e.preventDefault();\n if (swiper.isBeginning && !swiper.params.loop) { return; }\n swiper.slidePrev();\n },\n onNextClick: function onNextClick(e) {\n var swiper = this;\n e.preventDefault();\n if (swiper.isEnd && !swiper.params.loop) { return; }\n swiper.slideNext();\n },\n init: function init() {\n var swiper = this;\n var params = swiper.params.navigation;\n if (!(params.nextEl || params.prevEl)) { return; }\n\n var $nextEl;\n var $prevEl;\n if (params.nextEl) {\n $nextEl = $(params.nextEl);\n if (\n swiper.params.uniqueNavElements\n && typeof params.nextEl === 'string'\n && $nextEl.length > 1\n && swiper.$el.find(params.nextEl).length === 1\n ) {\n $nextEl = swiper.$el.find(params.nextEl);\n }\n }\n if (params.prevEl) {\n $prevEl = $(params.prevEl);\n if (\n swiper.params.uniqueNavElements\n && typeof params.prevEl === 'string'\n && $prevEl.length > 1\n && swiper.$el.find(params.prevEl).length === 1\n ) {\n $prevEl = swiper.$el.find(params.prevEl);\n }\n }\n\n if ($nextEl && $nextEl.length > 0) {\n $nextEl.on('click', swiper.navigation.onNextClick);\n }\n if ($prevEl && $prevEl.length > 0) {\n $prevEl.on('click', swiper.navigation.onPrevClick);\n }\n\n Utils.extend(swiper.navigation, {\n $nextEl: $nextEl,\n nextEl: $nextEl && $nextEl[0],\n $prevEl: $prevEl,\n prevEl: $prevEl && $prevEl[0],\n });\n },\n destroy: function destroy() {\n var swiper = this;\n var ref = swiper.navigation;\n var $nextEl = ref.$nextEl;\n var $prevEl = ref.$prevEl;\n if ($nextEl && $nextEl.length) {\n $nextEl.off('click', swiper.navigation.onNextClick);\n $nextEl.removeClass(swiper.params.navigation.disabledClass);\n }\n if ($prevEl && $prevEl.length) {\n $prevEl.off('click', swiper.navigation.onPrevClick);\n $prevEl.removeClass(swiper.params.navigation.disabledClass);\n }\n },\n };\n\n var Navigation$1 = {\n name: 'navigation',\n params: {\n navigation: {\n nextEl: null,\n prevEl: null,\n\n hideOnClick: false,\n disabledClass: 'swiper-button-disabled',\n hiddenClass: 'swiper-button-hidden',\n lockClass: 'swiper-button-lock',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n navigation: {\n init: Navigation.init.bind(swiper),\n update: Navigation.update.bind(swiper),\n destroy: Navigation.destroy.bind(swiper),\n onNextClick: Navigation.onNextClick.bind(swiper),\n onPrevClick: Navigation.onPrevClick.bind(swiper),\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n swiper.navigation.init();\n swiper.navigation.update();\n },\n toEdge: function toEdge() {\n var swiper = this;\n swiper.navigation.update();\n },\n fromEdge: function fromEdge() {\n var swiper = this;\n swiper.navigation.update();\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.navigation.destroy();\n },\n click: function click(e) {\n var swiper = this;\n var ref = swiper.navigation;\n var $nextEl = ref.$nextEl;\n var $prevEl = ref.$prevEl;\n if (\n swiper.params.navigation.hideOnClick\n && !$(e.target).is($prevEl)\n && !$(e.target).is($nextEl)\n ) {\n var isHidden;\n if ($nextEl) {\n isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass);\n } else if ($prevEl) {\n isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass);\n }\n if (isHidden === true) {\n swiper.emit('navigationShow', swiper);\n } else {\n swiper.emit('navigationHide', swiper);\n }\n if ($nextEl) {\n $nextEl.toggleClass(swiper.params.navigation.hiddenClass);\n }\n if ($prevEl) {\n $prevEl.toggleClass(swiper.params.navigation.hiddenClass);\n }\n }\n },\n },\n };\n\n var Pagination = {\n update: function update() {\n // Render || Update Pagination bullets/items\n var swiper = this;\n var rtl = swiper.rtl;\n var params = swiper.params.pagination;\n if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) { return; }\n var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n var $el = swiper.pagination.$el;\n // Current/Total\n var current;\n var total = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n if (swiper.params.loop) {\n current = Math.ceil((swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup);\n if (current > slidesLength - 1 - (swiper.loopedSlides * 2)) {\n current -= (slidesLength - (swiper.loopedSlides * 2));\n }\n if (current > total - 1) { current -= total; }\n if (current < 0 && swiper.params.paginationType !== 'bullets') { current = total + current; }\n } else if (typeof swiper.snapIndex !== 'undefined') {\n current = swiper.snapIndex;\n } else {\n current = swiper.activeIndex || 0;\n }\n // Types\n if (params.type === 'bullets' && swiper.pagination.bullets && swiper.pagination.bullets.length > 0) {\n var bullets = swiper.pagination.bullets;\n var firstIndex;\n var lastIndex;\n var midIndex;\n if (params.dynamicBullets) {\n swiper.pagination.bulletSize = bullets.eq(0)[swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'](true);\n $el.css(swiper.isHorizontal() ? 'width' : 'height', ((swiper.pagination.bulletSize * (params.dynamicMainBullets + 4)) + \"px\"));\n if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {\n swiper.pagination.dynamicBulletIndex += (current - swiper.previousIndex);\n if (swiper.pagination.dynamicBulletIndex > (params.dynamicMainBullets - 1)) {\n swiper.pagination.dynamicBulletIndex = params.dynamicMainBullets - 1;\n } else if (swiper.pagination.dynamicBulletIndex < 0) {\n swiper.pagination.dynamicBulletIndex = 0;\n }\n }\n firstIndex = current - swiper.pagination.dynamicBulletIndex;\n lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);\n midIndex = (lastIndex + firstIndex) / 2;\n }\n bullets.removeClass(((params.bulletActiveClass) + \" \" + (params.bulletActiveClass) + \"-next \" + (params.bulletActiveClass) + \"-next-next \" + (params.bulletActiveClass) + \"-prev \" + (params.bulletActiveClass) + \"-prev-prev \" + (params.bulletActiveClass) + \"-main\"));\n if ($el.length > 1) {\n bullets.each(function (index, bullet) {\n var $bullet = $(bullet);\n var bulletIndex = $bullet.index();\n if (bulletIndex === current) {\n $bullet.addClass(params.bulletActiveClass);\n }\n if (params.dynamicBullets) {\n if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {\n $bullet.addClass(((params.bulletActiveClass) + \"-main\"));\n }\n if (bulletIndex === firstIndex) {\n $bullet\n .prev()\n .addClass(((params.bulletActiveClass) + \"-prev\"))\n .prev()\n .addClass(((params.bulletActiveClass) + \"-prev-prev\"));\n }\n if (bulletIndex === lastIndex) {\n $bullet\n .next()\n .addClass(((params.bulletActiveClass) + \"-next\"))\n .next()\n .addClass(((params.bulletActiveClass) + \"-next-next\"));\n }\n }\n });\n } else {\n var $bullet = bullets.eq(current);\n $bullet.addClass(params.bulletActiveClass);\n if (params.dynamicBullets) {\n var $firstDisplayedBullet = bullets.eq(firstIndex);\n var $lastDisplayedBullet = bullets.eq(lastIndex);\n for (var i = firstIndex; i <= lastIndex; i += 1) {\n bullets.eq(i).addClass(((params.bulletActiveClass) + \"-main\"));\n }\n $firstDisplayedBullet\n .prev()\n .addClass(((params.bulletActiveClass) + \"-prev\"))\n .prev()\n .addClass(((params.bulletActiveClass) + \"-prev-prev\"));\n $lastDisplayedBullet\n .next()\n .addClass(((params.bulletActiveClass) + \"-next\"))\n .next()\n .addClass(((params.bulletActiveClass) + \"-next-next\"));\n }\n }\n if (params.dynamicBullets) {\n var dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);\n var bulletsOffset = (((swiper.pagination.bulletSize * dynamicBulletsLength) - (swiper.pagination.bulletSize)) / 2) - (midIndex * swiper.pagination.bulletSize);\n var offsetProp = rtl ? 'right' : 'left';\n bullets.css(swiper.isHorizontal() ? offsetProp : 'top', (bulletsOffset + \"px\"));\n }\n }\n if (params.type === 'fraction') {\n $el.find((\".\" + (params.currentClass))).text(params.formatFractionCurrent(current + 1));\n $el.find((\".\" + (params.totalClass))).text(params.formatFractionTotal(total));\n }\n if (params.type === 'progressbar') {\n var progressbarDirection;\n if (params.progressbarOpposite) {\n progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';\n } else {\n progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';\n }\n var scale = (current + 1) / total;\n var scaleX = 1;\n var scaleY = 1;\n if (progressbarDirection === 'horizontal') {\n scaleX = scale;\n } else {\n scaleY = scale;\n }\n $el.find((\".\" + (params.progressbarFillClass))).transform((\"translate3d(0,0,0) scaleX(\" + scaleX + \") scaleY(\" + scaleY + \")\")).transition(swiper.params.speed);\n }\n if (params.type === 'custom' && params.renderCustom) {\n $el.html(params.renderCustom(swiper, current + 1, total));\n swiper.emit('paginationRender', swiper, $el[0]);\n } else {\n swiper.emit('paginationUpdate', swiper, $el[0]);\n }\n $el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](params.lockClass);\n },\n render: function render() {\n // Render Container\n var swiper = this;\n var params = swiper.params.pagination;\n if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) { return; }\n var slidesLength = swiper.virtual && swiper.params.virtual.enabled ? swiper.virtual.slides.length : swiper.slides.length;\n\n var $el = swiper.pagination.$el;\n var paginationHTML = '';\n if (params.type === 'bullets') {\n var numberOfBullets = swiper.params.loop ? Math.ceil((slidesLength - (swiper.loopedSlides * 2)) / swiper.params.slidesPerGroup) : swiper.snapGrid.length;\n for (var i = 0; i < numberOfBullets; i += 1) {\n if (params.renderBullet) {\n paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);\n } else {\n paginationHTML += \"<\" + (params.bulletElement) + \" class=\\\"\" + (params.bulletClass) + \"\\\">\";\n }\n }\n $el.html(paginationHTML);\n swiper.pagination.bullets = $el.find((\".\" + (params.bulletClass)));\n }\n if (params.type === 'fraction') {\n if (params.renderFraction) {\n paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);\n } else {\n paginationHTML = \"\"\n + ' / '\n + \"\";\n }\n $el.html(paginationHTML);\n }\n if (params.type === 'progressbar') {\n if (params.renderProgressbar) {\n paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);\n } else {\n paginationHTML = \"\";\n }\n $el.html(paginationHTML);\n }\n if (params.type !== 'custom') {\n swiper.emit('paginationRender', swiper.pagination.$el[0]);\n }\n },\n init: function init() {\n var swiper = this;\n var params = swiper.params.pagination;\n if (!params.el) { return; }\n\n var $el = $(params.el);\n if ($el.length === 0) { return; }\n\n if (\n swiper.params.uniqueNavElements\n && typeof params.el === 'string'\n && $el.length > 1\n && swiper.$el.find(params.el).length === 1\n ) {\n $el = swiper.$el.find(params.el);\n }\n\n if (params.type === 'bullets' && params.clickable) {\n $el.addClass(params.clickableClass);\n }\n\n $el.addClass(params.modifierClass + params.type);\n\n if (params.type === 'bullets' && params.dynamicBullets) {\n $el.addClass((\"\" + (params.modifierClass) + (params.type) + \"-dynamic\"));\n swiper.pagination.dynamicBulletIndex = 0;\n if (params.dynamicMainBullets < 1) {\n params.dynamicMainBullets = 1;\n }\n }\n if (params.type === 'progressbar' && params.progressbarOpposite) {\n $el.addClass(params.progressbarOppositeClass);\n }\n\n if (params.clickable) {\n $el.on('click', (\".\" + (params.bulletClass)), function onClick(e) {\n e.preventDefault();\n var index = $(this).index() * swiper.params.slidesPerGroup;\n if (swiper.params.loop) { index += swiper.loopedSlides; }\n swiper.slideTo(index);\n });\n }\n\n Utils.extend(swiper.pagination, {\n $el: $el,\n el: $el[0],\n });\n },\n destroy: function destroy() {\n var swiper = this;\n var params = swiper.params.pagination;\n if (!params.el || !swiper.pagination.el || !swiper.pagination.$el || swiper.pagination.$el.length === 0) { return; }\n var $el = swiper.pagination.$el;\n\n $el.removeClass(params.hiddenClass);\n $el.removeClass(params.modifierClass + params.type);\n if (swiper.pagination.bullets) { swiper.pagination.bullets.removeClass(params.bulletActiveClass); }\n if (params.clickable) {\n $el.off('click', (\".\" + (params.bulletClass)));\n }\n },\n };\n\n var Pagination$1 = {\n name: 'pagination',\n params: {\n pagination: {\n el: null,\n bulletElement: 'span',\n clickable: false,\n hideOnClick: false,\n renderBullet: null,\n renderProgressbar: null,\n renderFraction: null,\n renderCustom: null,\n progressbarOpposite: false,\n type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom'\n dynamicBullets: false,\n dynamicMainBullets: 1,\n formatFractionCurrent: function (number) { return number; },\n formatFractionTotal: function (number) { return number; },\n bulletClass: 'swiper-pagination-bullet',\n bulletActiveClass: 'swiper-pagination-bullet-active',\n modifierClass: 'swiper-pagination-', // NEW\n currentClass: 'swiper-pagination-current',\n totalClass: 'swiper-pagination-total',\n hiddenClass: 'swiper-pagination-hidden',\n progressbarFillClass: 'swiper-pagination-progressbar-fill',\n progressbarOppositeClass: 'swiper-pagination-progressbar-opposite',\n clickableClass: 'swiper-pagination-clickable', // NEW\n lockClass: 'swiper-pagination-lock',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n pagination: {\n init: Pagination.init.bind(swiper),\n render: Pagination.render.bind(swiper),\n update: Pagination.update.bind(swiper),\n destroy: Pagination.destroy.bind(swiper),\n dynamicBulletIndex: 0,\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n swiper.pagination.init();\n swiper.pagination.render();\n swiper.pagination.update();\n },\n activeIndexChange: function activeIndexChange() {\n var swiper = this;\n if (swiper.params.loop) {\n swiper.pagination.update();\n } else if (typeof swiper.snapIndex === 'undefined') {\n swiper.pagination.update();\n }\n },\n snapIndexChange: function snapIndexChange() {\n var swiper = this;\n if (!swiper.params.loop) {\n swiper.pagination.update();\n }\n },\n slidesLengthChange: function slidesLengthChange() {\n var swiper = this;\n if (swiper.params.loop) {\n swiper.pagination.render();\n swiper.pagination.update();\n }\n },\n snapGridLengthChange: function snapGridLengthChange() {\n var swiper = this;\n if (!swiper.params.loop) {\n swiper.pagination.render();\n swiper.pagination.update();\n }\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.pagination.destroy();\n },\n click: function click(e) {\n var swiper = this;\n if (\n swiper.params.pagination.el\n && swiper.params.pagination.hideOnClick\n && swiper.pagination.$el.length > 0\n && !$(e.target).hasClass(swiper.params.pagination.bulletClass)\n ) {\n var isHidden = swiper.pagination.$el.hasClass(swiper.params.pagination.hiddenClass);\n if (isHidden === true) {\n swiper.emit('paginationShow', swiper);\n } else {\n swiper.emit('paginationHide', swiper);\n }\n swiper.pagination.$el.toggleClass(swiper.params.pagination.hiddenClass);\n }\n },\n },\n };\n\n var Scrollbar = {\n setTranslate: function setTranslate() {\n var swiper = this;\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) { return; }\n var scrollbar = swiper.scrollbar;\n var rtl = swiper.rtlTranslate;\n var progress = swiper.progress;\n var dragSize = scrollbar.dragSize;\n var trackSize = scrollbar.trackSize;\n var $dragEl = scrollbar.$dragEl;\n var $el = scrollbar.$el;\n var params = swiper.params.scrollbar;\n\n var newSize = dragSize;\n var newPos = (trackSize - dragSize) * progress;\n if (rtl) {\n newPos = -newPos;\n if (newPos > 0) {\n newSize = dragSize - newPos;\n newPos = 0;\n } else if (-newPos + dragSize > trackSize) {\n newSize = trackSize + newPos;\n }\n } else if (newPos < 0) {\n newSize = dragSize + newPos;\n newPos = 0;\n } else if (newPos + dragSize > trackSize) {\n newSize = trackSize - newPos;\n }\n if (swiper.isHorizontal()) {\n if (Support.transforms3d) {\n $dragEl.transform((\"translate3d(\" + newPos + \"px, 0, 0)\"));\n } else {\n $dragEl.transform((\"translateX(\" + newPos + \"px)\"));\n }\n $dragEl[0].style.width = newSize + \"px\";\n } else {\n if (Support.transforms3d) {\n $dragEl.transform((\"translate3d(0px, \" + newPos + \"px, 0)\"));\n } else {\n $dragEl.transform((\"translateY(\" + newPos + \"px)\"));\n }\n $dragEl[0].style.height = newSize + \"px\";\n }\n if (params.hide) {\n clearTimeout(swiper.scrollbar.timeout);\n $el[0].style.opacity = 1;\n swiper.scrollbar.timeout = setTimeout(function () {\n $el[0].style.opacity = 0;\n $el.transition(400);\n }, 1000);\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) { return; }\n swiper.scrollbar.$dragEl.transition(duration);\n },\n updateSize: function updateSize() {\n var swiper = this;\n if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) { return; }\n\n var scrollbar = swiper.scrollbar;\n var $dragEl = scrollbar.$dragEl;\n var $el = scrollbar.$el;\n\n $dragEl[0].style.width = '';\n $dragEl[0].style.height = '';\n var trackSize = swiper.isHorizontal() ? $el[0].offsetWidth : $el[0].offsetHeight;\n\n var divider = swiper.size / swiper.virtualSize;\n var moveDivider = divider * (trackSize / swiper.size);\n var dragSize;\n if (swiper.params.scrollbar.dragSize === 'auto') {\n dragSize = trackSize * divider;\n } else {\n dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);\n }\n\n if (swiper.isHorizontal()) {\n $dragEl[0].style.width = dragSize + \"px\";\n } else {\n $dragEl[0].style.height = dragSize + \"px\";\n }\n\n if (divider >= 1) {\n $el[0].style.display = 'none';\n } else {\n $el[0].style.display = '';\n }\n if (swiper.params.scrollbar.hide) {\n $el[0].style.opacity = 0;\n }\n Utils.extend(scrollbar, {\n trackSize: trackSize,\n divider: divider,\n moveDivider: moveDivider,\n dragSize: dragSize,\n });\n scrollbar.$el[swiper.params.watchOverflow && swiper.isLocked ? 'addClass' : 'removeClass'](swiper.params.scrollbar.lockClass);\n },\n setDragPosition: function setDragPosition(e) {\n var swiper = this;\n var scrollbar = swiper.scrollbar;\n var rtl = swiper.rtlTranslate;\n var $el = scrollbar.$el;\n var dragSize = scrollbar.dragSize;\n var trackSize = scrollbar.trackSize;\n\n var pointerPosition;\n if (swiper.isHorizontal()) {\n pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX);\n } else {\n pointerPosition = ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY);\n }\n var positionRatio;\n positionRatio = ((pointerPosition) - $el.offset()[swiper.isHorizontal() ? 'left' : 'top'] - (dragSize / 2)) / (trackSize - dragSize);\n positionRatio = Math.max(Math.min(positionRatio, 1), 0);\n if (rtl) {\n positionRatio = 1 - positionRatio;\n }\n\n var position = swiper.minTranslate() + ((swiper.maxTranslate() - swiper.minTranslate()) * positionRatio);\n\n swiper.updateProgress(position);\n swiper.setTranslate(position);\n swiper.updateActiveIndex();\n swiper.updateSlidesClasses();\n },\n onDragStart: function onDragStart(e) {\n var swiper = this;\n var params = swiper.params.scrollbar;\n var scrollbar = swiper.scrollbar;\n var $wrapperEl = swiper.$wrapperEl;\n var $el = scrollbar.$el;\n var $dragEl = scrollbar.$dragEl;\n swiper.scrollbar.isTouched = true;\n e.preventDefault();\n e.stopPropagation();\n\n $wrapperEl.transition(100);\n $dragEl.transition(100);\n scrollbar.setDragPosition(e);\n\n clearTimeout(swiper.scrollbar.dragTimeout);\n\n $el.transition(0);\n if (params.hide) {\n $el.css('opacity', 1);\n }\n swiper.emit('scrollbarDragStart', e);\n },\n onDragMove: function onDragMove(e) {\n var swiper = this;\n var scrollbar = swiper.scrollbar;\n var $wrapperEl = swiper.$wrapperEl;\n var $el = scrollbar.$el;\n var $dragEl = scrollbar.$dragEl;\n\n if (!swiper.scrollbar.isTouched) { return; }\n if (e.preventDefault) { e.preventDefault(); }\n else { e.returnValue = false; }\n scrollbar.setDragPosition(e);\n $wrapperEl.transition(0);\n $el.transition(0);\n $dragEl.transition(0);\n swiper.emit('scrollbarDragMove', e);\n },\n onDragEnd: function onDragEnd(e) {\n var swiper = this;\n\n var params = swiper.params.scrollbar;\n var scrollbar = swiper.scrollbar;\n var $el = scrollbar.$el;\n\n if (!swiper.scrollbar.isTouched) { return; }\n swiper.scrollbar.isTouched = false;\n if (params.hide) {\n clearTimeout(swiper.scrollbar.dragTimeout);\n swiper.scrollbar.dragTimeout = Utils.nextTick(function () {\n $el.css('opacity', 0);\n $el.transition(400);\n }, 1000);\n }\n swiper.emit('scrollbarDragEnd', e);\n if (params.snapOnRelease) {\n swiper.slideToClosest();\n }\n },\n enableDraggable: function enableDraggable() {\n var swiper = this;\n if (!swiper.params.scrollbar.el) { return; }\n var scrollbar = swiper.scrollbar;\n var touchEventsTouch = swiper.touchEventsTouch;\n var touchEventsDesktop = swiper.touchEventsDesktop;\n var params = swiper.params;\n var $el = scrollbar.$el;\n var target = $el[0];\n var activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false;\n var passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;\n if (!Support.touch) {\n target.addEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);\n doc.addEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);\n doc.addEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);\n } else {\n target.addEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);\n target.addEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);\n target.addEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);\n }\n },\n disableDraggable: function disableDraggable() {\n var swiper = this;\n if (!swiper.params.scrollbar.el) { return; }\n var scrollbar = swiper.scrollbar;\n var touchEventsTouch = swiper.touchEventsTouch;\n var touchEventsDesktop = swiper.touchEventsDesktop;\n var params = swiper.params;\n var $el = scrollbar.$el;\n var target = $el[0];\n var activeListener = Support.passiveListener && params.passiveListeners ? { passive: false, capture: false } : false;\n var passiveListener = Support.passiveListener && params.passiveListeners ? { passive: true, capture: false } : false;\n if (!Support.touch) {\n target.removeEventListener(touchEventsDesktop.start, swiper.scrollbar.onDragStart, activeListener);\n doc.removeEventListener(touchEventsDesktop.move, swiper.scrollbar.onDragMove, activeListener);\n doc.removeEventListener(touchEventsDesktop.end, swiper.scrollbar.onDragEnd, passiveListener);\n } else {\n target.removeEventListener(touchEventsTouch.start, swiper.scrollbar.onDragStart, activeListener);\n target.removeEventListener(touchEventsTouch.move, swiper.scrollbar.onDragMove, activeListener);\n target.removeEventListener(touchEventsTouch.end, swiper.scrollbar.onDragEnd, passiveListener);\n }\n },\n init: function init() {\n var swiper = this;\n if (!swiper.params.scrollbar.el) { return; }\n var scrollbar = swiper.scrollbar;\n var $swiperEl = swiper.$el;\n var params = swiper.params.scrollbar;\n\n var $el = $(params.el);\n if (swiper.params.uniqueNavElements && typeof params.el === 'string' && $el.length > 1 && $swiperEl.find(params.el).length === 1) {\n $el = $swiperEl.find(params.el);\n }\n\n var $dragEl = $el.find((\".\" + (swiper.params.scrollbar.dragClass)));\n if ($dragEl.length === 0) {\n $dragEl = $((\"
            \"));\n $el.append($dragEl);\n }\n\n Utils.extend(scrollbar, {\n $el: $el,\n el: $el[0],\n $dragEl: $dragEl,\n dragEl: $dragEl[0],\n });\n\n if (params.draggable) {\n scrollbar.enableDraggable();\n }\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.scrollbar.disableDraggable();\n },\n };\n\n var Scrollbar$1 = {\n name: 'scrollbar',\n params: {\n scrollbar: {\n el: null,\n dragSize: 'auto',\n hide: false,\n draggable: false,\n snapOnRelease: true,\n lockClass: 'swiper-scrollbar-lock',\n dragClass: 'swiper-scrollbar-drag',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n scrollbar: {\n init: Scrollbar.init.bind(swiper),\n destroy: Scrollbar.destroy.bind(swiper),\n updateSize: Scrollbar.updateSize.bind(swiper),\n setTranslate: Scrollbar.setTranslate.bind(swiper),\n setTransition: Scrollbar.setTransition.bind(swiper),\n enableDraggable: Scrollbar.enableDraggable.bind(swiper),\n disableDraggable: Scrollbar.disableDraggable.bind(swiper),\n setDragPosition: Scrollbar.setDragPosition.bind(swiper),\n onDragStart: Scrollbar.onDragStart.bind(swiper),\n onDragMove: Scrollbar.onDragMove.bind(swiper),\n onDragEnd: Scrollbar.onDragEnd.bind(swiper),\n isTouched: false,\n timeout: null,\n dragTimeout: null,\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n swiper.scrollbar.init();\n swiper.scrollbar.updateSize();\n swiper.scrollbar.setTranslate();\n },\n update: function update() {\n var swiper = this;\n swiper.scrollbar.updateSize();\n },\n resize: function resize() {\n var swiper = this;\n swiper.scrollbar.updateSize();\n },\n observerUpdate: function observerUpdate() {\n var swiper = this;\n swiper.scrollbar.updateSize();\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n swiper.scrollbar.setTranslate();\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n swiper.scrollbar.setTransition(duration);\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.scrollbar.destroy();\n },\n },\n };\n\n var Parallax = {\n setTransform: function setTransform(el, progress) {\n var swiper = this;\n var rtl = swiper.rtl;\n\n var $el = $(el);\n var rtlFactor = rtl ? -1 : 1;\n\n var p = $el.attr('data-swiper-parallax') || '0';\n var x = $el.attr('data-swiper-parallax-x');\n var y = $el.attr('data-swiper-parallax-y');\n var scale = $el.attr('data-swiper-parallax-scale');\n var opacity = $el.attr('data-swiper-parallax-opacity');\n\n if (x || y) {\n x = x || '0';\n y = y || '0';\n } else if (swiper.isHorizontal()) {\n x = p;\n y = '0';\n } else {\n y = p;\n x = '0';\n }\n\n if ((x).indexOf('%') >= 0) {\n x = (parseInt(x, 10) * progress * rtlFactor) + \"%\";\n } else {\n x = (x * progress * rtlFactor) + \"px\";\n }\n if ((y).indexOf('%') >= 0) {\n y = (parseInt(y, 10) * progress) + \"%\";\n } else {\n y = (y * progress) + \"px\";\n }\n\n if (typeof opacity !== 'undefined' && opacity !== null) {\n var currentOpacity = opacity - ((opacity - 1) * (1 - Math.abs(progress)));\n $el[0].style.opacity = currentOpacity;\n }\n if (typeof scale === 'undefined' || scale === null) {\n $el.transform((\"translate3d(\" + x + \", \" + y + \", 0px)\"));\n } else {\n var currentScale = scale - ((scale - 1) * (1 - Math.abs(progress)));\n $el.transform((\"translate3d(\" + x + \", \" + y + \", 0px) scale(\" + currentScale + \")\"));\n }\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n var $el = swiper.$el;\n var slides = swiper.slides;\n var progress = swiper.progress;\n var snapGrid = swiper.snapGrid;\n $el.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')\n .each(function (index, el) {\n swiper.parallax.setTransform(el, progress);\n });\n slides.each(function (slideIndex, slideEl) {\n var slideProgress = slideEl.progress;\n if (swiper.params.slidesPerGroup > 1 && swiper.params.slidesPerView !== 'auto') {\n slideProgress += Math.ceil(slideIndex / 2) - (progress * (snapGrid.length - 1));\n }\n slideProgress = Math.min(Math.max(slideProgress, -1), 1);\n $(slideEl).find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')\n .each(function (index, el) {\n swiper.parallax.setTransform(el, slideProgress);\n });\n });\n },\n setTransition: function setTransition(duration) {\n if ( duration === void 0 ) duration = this.params.speed;\n\n var swiper = this;\n var $el = swiper.$el;\n $el.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]')\n .each(function (index, parallaxEl) {\n var $parallaxEl = $(parallaxEl);\n var parallaxDuration = parseInt($parallaxEl.attr('data-swiper-parallax-duration'), 10) || duration;\n if (duration === 0) { parallaxDuration = 0; }\n $parallaxEl.transition(parallaxDuration);\n });\n },\n };\n\n var Parallax$1 = {\n name: 'parallax',\n params: {\n parallax: {\n enabled: false,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n parallax: {\n setTransform: Parallax.setTransform.bind(swiper),\n setTranslate: Parallax.setTranslate.bind(swiper),\n setTransition: Parallax.setTransition.bind(swiper),\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n if (!swiper.params.parallax.enabled) { return; }\n swiper.params.watchSlidesProgress = true;\n swiper.originalParams.watchSlidesProgress = true;\n },\n init: function init() {\n var swiper = this;\n if (!swiper.params.parallax.enabled) { return; }\n swiper.parallax.setTranslate();\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n if (!swiper.params.parallax.enabled) { return; }\n swiper.parallax.setTranslate();\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n if (!swiper.params.parallax.enabled) { return; }\n swiper.parallax.setTransition(duration);\n },\n },\n };\n\n var Zoom = {\n // Calc Scale From Multi-touches\n getDistanceBetweenTouches: function getDistanceBetweenTouches(e) {\n if (e.targetTouches.length < 2) { return 1; }\n var x1 = e.targetTouches[0].pageX;\n var y1 = e.targetTouches[0].pageY;\n var x2 = e.targetTouches[1].pageX;\n var y2 = e.targetTouches[1].pageY;\n var distance = Math.sqrt((Math.pow( (x2 - x1), 2 )) + (Math.pow( (y2 - y1), 2 )));\n return distance;\n },\n // Events\n onGestureStart: function onGestureStart(e) {\n var swiper = this;\n var params = swiper.params.zoom;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n zoom.fakeGestureTouched = false;\n zoom.fakeGestureMoved = false;\n if (!Support.gestures) {\n if (e.type !== 'touchstart' || (e.type === 'touchstart' && e.targetTouches.length < 2)) {\n return;\n }\n zoom.fakeGestureTouched = true;\n gesture.scaleStart = Zoom.getDistanceBetweenTouches(e);\n }\n if (!gesture.$slideEl || !gesture.$slideEl.length) {\n gesture.$slideEl = $(e.target).closest('.swiper-slide');\n if (gesture.$slideEl.length === 0) { gesture.$slideEl = swiper.slides.eq(swiper.activeIndex); }\n gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas');\n gesture.$imageWrapEl = gesture.$imageEl.parent((\".\" + (params.containerClass)));\n gesture.maxRatio = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n if (gesture.$imageWrapEl.length === 0) {\n gesture.$imageEl = undefined;\n return;\n }\n }\n gesture.$imageEl.transition(0);\n swiper.zoom.isScaling = true;\n },\n onGestureChange: function onGestureChange(e) {\n var swiper = this;\n var params = swiper.params.zoom;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n if (!Support.gestures) {\n if (e.type !== 'touchmove' || (e.type === 'touchmove' && e.targetTouches.length < 2)) {\n return;\n }\n zoom.fakeGestureMoved = true;\n gesture.scaleMove = Zoom.getDistanceBetweenTouches(e);\n }\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; }\n if (Support.gestures) {\n zoom.scale = e.scale * zoom.currentScale;\n } else {\n zoom.scale = (gesture.scaleMove / gesture.scaleStart) * zoom.currentScale;\n }\n if (zoom.scale > gesture.maxRatio) {\n zoom.scale = (gesture.maxRatio - 1) + (Math.pow( ((zoom.scale - gesture.maxRatio) + 1), 0.5 ));\n }\n if (zoom.scale < params.minRatio) {\n zoom.scale = (params.minRatio + 1) - (Math.pow( ((params.minRatio - zoom.scale) + 1), 0.5 ));\n }\n gesture.$imageEl.transform((\"translate3d(0,0,0) scale(\" + (zoom.scale) + \")\"));\n },\n onGestureEnd: function onGestureEnd(e) {\n var swiper = this;\n var params = swiper.params.zoom;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n if (!Support.gestures) {\n if (!zoom.fakeGestureTouched || !zoom.fakeGestureMoved) {\n return;\n }\n if (e.type !== 'touchend' || (e.type === 'touchend' && e.changedTouches.length < 2 && !Device.android)) {\n return;\n }\n zoom.fakeGestureTouched = false;\n zoom.fakeGestureMoved = false;\n }\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; }\n zoom.scale = Math.max(Math.min(zoom.scale, gesture.maxRatio), params.minRatio);\n gesture.$imageEl.transition(swiper.params.speed).transform((\"translate3d(0,0,0) scale(\" + (zoom.scale) + \")\"));\n zoom.currentScale = zoom.scale;\n zoom.isScaling = false;\n if (zoom.scale === 1) { gesture.$slideEl = undefined; }\n },\n onTouchStart: function onTouchStart(e) {\n var swiper = this;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n var image = zoom.image;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; }\n if (image.isTouched) { return; }\n if (Device.android) { e.preventDefault(); }\n image.isTouched = true;\n image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;\n image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;\n },\n onTouchMove: function onTouchMove(e) {\n var swiper = this;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n var image = zoom.image;\n var velocity = zoom.velocity;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; }\n swiper.allowClick = false;\n if (!image.isTouched || !gesture.$slideEl) { return; }\n\n if (!image.isMoved) {\n image.width = gesture.$imageEl[0].offsetWidth;\n image.height = gesture.$imageEl[0].offsetHeight;\n image.startX = Utils.getTranslate(gesture.$imageWrapEl[0], 'x') || 0;\n image.startY = Utils.getTranslate(gesture.$imageWrapEl[0], 'y') || 0;\n gesture.slideWidth = gesture.$slideEl[0].offsetWidth;\n gesture.slideHeight = gesture.$slideEl[0].offsetHeight;\n gesture.$imageWrapEl.transition(0);\n if (swiper.rtl) {\n image.startX = -image.startX;\n image.startY = -image.startY;\n }\n }\n // Define if we need image drag\n var scaledWidth = image.width * zoom.scale;\n var scaledHeight = image.height * zoom.scale;\n\n if (scaledWidth < gesture.slideWidth && scaledHeight < gesture.slideHeight) { return; }\n\n image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0);\n image.maxX = -image.minX;\n image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0);\n image.maxY = -image.minY;\n\n image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;\n image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;\n\n if (!image.isMoved && !zoom.isScaling) {\n if (\n swiper.isHorizontal()\n && (\n (Math.floor(image.minX) === Math.floor(image.startX) && image.touchesCurrent.x < image.touchesStart.x)\n || (Math.floor(image.maxX) === Math.floor(image.startX) && image.touchesCurrent.x > image.touchesStart.x)\n )\n ) {\n image.isTouched = false;\n return;\n } if (\n !swiper.isHorizontal()\n && (\n (Math.floor(image.minY) === Math.floor(image.startY) && image.touchesCurrent.y < image.touchesStart.y)\n || (Math.floor(image.maxY) === Math.floor(image.startY) && image.touchesCurrent.y > image.touchesStart.y)\n )\n ) {\n image.isTouched = false;\n return;\n }\n }\n e.preventDefault();\n e.stopPropagation();\n\n image.isMoved = true;\n image.currentX = (image.touchesCurrent.x - image.touchesStart.x) + image.startX;\n image.currentY = (image.touchesCurrent.y - image.touchesStart.y) + image.startY;\n\n if (image.currentX < image.minX) {\n image.currentX = (image.minX + 1) - (Math.pow( ((image.minX - image.currentX) + 1), 0.8 ));\n }\n if (image.currentX > image.maxX) {\n image.currentX = (image.maxX - 1) + (Math.pow( ((image.currentX - image.maxX) + 1), 0.8 ));\n }\n\n if (image.currentY < image.minY) {\n image.currentY = (image.minY + 1) - (Math.pow( ((image.minY - image.currentY) + 1), 0.8 ));\n }\n if (image.currentY > image.maxY) {\n image.currentY = (image.maxY - 1) + (Math.pow( ((image.currentY - image.maxY) + 1), 0.8 ));\n }\n\n // Velocity\n if (!velocity.prevPositionX) { velocity.prevPositionX = image.touchesCurrent.x; }\n if (!velocity.prevPositionY) { velocity.prevPositionY = image.touchesCurrent.y; }\n if (!velocity.prevTime) { velocity.prevTime = Date.now(); }\n velocity.x = (image.touchesCurrent.x - velocity.prevPositionX) / (Date.now() - velocity.prevTime) / 2;\n velocity.y = (image.touchesCurrent.y - velocity.prevPositionY) / (Date.now() - velocity.prevTime) / 2;\n if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2) { velocity.x = 0; }\n if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2) { velocity.y = 0; }\n velocity.prevPositionX = image.touchesCurrent.x;\n velocity.prevPositionY = image.touchesCurrent.y;\n velocity.prevTime = Date.now();\n\n gesture.$imageWrapEl.transform((\"translate3d(\" + (image.currentX) + \"px, \" + (image.currentY) + \"px,0)\"));\n },\n onTouchEnd: function onTouchEnd() {\n var swiper = this;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n var image = zoom.image;\n var velocity = zoom.velocity;\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; }\n if (!image.isTouched || !image.isMoved) {\n image.isTouched = false;\n image.isMoved = false;\n return;\n }\n image.isTouched = false;\n image.isMoved = false;\n var momentumDurationX = 300;\n var momentumDurationY = 300;\n var momentumDistanceX = velocity.x * momentumDurationX;\n var newPositionX = image.currentX + momentumDistanceX;\n var momentumDistanceY = velocity.y * momentumDurationY;\n var newPositionY = image.currentY + momentumDistanceY;\n\n // Fix duration\n if (velocity.x !== 0) { momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x); }\n if (velocity.y !== 0) { momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y); }\n var momentumDuration = Math.max(momentumDurationX, momentumDurationY);\n\n image.currentX = newPositionX;\n image.currentY = newPositionY;\n\n // Define if we need image drag\n var scaledWidth = image.width * zoom.scale;\n var scaledHeight = image.height * zoom.scale;\n image.minX = Math.min(((gesture.slideWidth / 2) - (scaledWidth / 2)), 0);\n image.maxX = -image.minX;\n image.minY = Math.min(((gesture.slideHeight / 2) - (scaledHeight / 2)), 0);\n image.maxY = -image.minY;\n image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX);\n image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY);\n\n gesture.$imageWrapEl.transition(momentumDuration).transform((\"translate3d(\" + (image.currentX) + \"px, \" + (image.currentY) + \"px,0)\"));\n },\n onTransitionEnd: function onTransitionEnd() {\n var swiper = this;\n var zoom = swiper.zoom;\n var gesture = zoom.gesture;\n if (gesture.$slideEl && swiper.previousIndex !== swiper.activeIndex) {\n gesture.$imageEl.transform('translate3d(0,0,0) scale(1)');\n gesture.$imageWrapEl.transform('translate3d(0,0,0)');\n\n zoom.scale = 1;\n zoom.currentScale = 1;\n\n gesture.$slideEl = undefined;\n gesture.$imageEl = undefined;\n gesture.$imageWrapEl = undefined;\n }\n },\n // Toggle Zoom\n toggle: function toggle(e) {\n var swiper = this;\n var zoom = swiper.zoom;\n\n if (zoom.scale && zoom.scale !== 1) {\n // Zoom Out\n zoom.out();\n } else {\n // Zoom In\n zoom.in(e);\n }\n },\n in: function in$1(e) {\n var swiper = this;\n\n var zoom = swiper.zoom;\n var params = swiper.params.zoom;\n var gesture = zoom.gesture;\n var image = zoom.image;\n\n if (!gesture.$slideEl) {\n gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex);\n gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas');\n gesture.$imageWrapEl = gesture.$imageEl.parent((\".\" + (params.containerClass)));\n }\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; }\n\n gesture.$slideEl.addClass((\"\" + (params.zoomedSlideClass)));\n\n var touchX;\n var touchY;\n var offsetX;\n var offsetY;\n var diffX;\n var diffY;\n var translateX;\n var translateY;\n var imageWidth;\n var imageHeight;\n var scaledWidth;\n var scaledHeight;\n var translateMinX;\n var translateMinY;\n var translateMaxX;\n var translateMaxY;\n var slideWidth;\n var slideHeight;\n\n if (typeof image.touchesStart.x === 'undefined' && e) {\n touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;\n touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;\n } else {\n touchX = image.touchesStart.x;\n touchY = image.touchesStart.y;\n }\n\n zoom.scale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n zoom.currentScale = gesture.$imageWrapEl.attr('data-swiper-zoom') || params.maxRatio;\n if (e) {\n slideWidth = gesture.$slideEl[0].offsetWidth;\n slideHeight = gesture.$slideEl[0].offsetHeight;\n offsetX = gesture.$slideEl.offset().left;\n offsetY = gesture.$slideEl.offset().top;\n diffX = (offsetX + (slideWidth / 2)) - touchX;\n diffY = (offsetY + (slideHeight / 2)) - touchY;\n\n imageWidth = gesture.$imageEl[0].offsetWidth;\n imageHeight = gesture.$imageEl[0].offsetHeight;\n scaledWidth = imageWidth * zoom.scale;\n scaledHeight = imageHeight * zoom.scale;\n\n translateMinX = Math.min(((slideWidth / 2) - (scaledWidth / 2)), 0);\n translateMinY = Math.min(((slideHeight / 2) - (scaledHeight / 2)), 0);\n translateMaxX = -translateMinX;\n translateMaxY = -translateMinY;\n\n translateX = diffX * zoom.scale;\n translateY = diffY * zoom.scale;\n\n if (translateX < translateMinX) {\n translateX = translateMinX;\n }\n if (translateX > translateMaxX) {\n translateX = translateMaxX;\n }\n\n if (translateY < translateMinY) {\n translateY = translateMinY;\n }\n if (translateY > translateMaxY) {\n translateY = translateMaxY;\n }\n } else {\n translateX = 0;\n translateY = 0;\n }\n gesture.$imageWrapEl.transition(300).transform((\"translate3d(\" + translateX + \"px, \" + translateY + \"px,0)\"));\n gesture.$imageEl.transition(300).transform((\"translate3d(0,0,0) scale(\" + (zoom.scale) + \")\"));\n },\n out: function out() {\n var swiper = this;\n\n var zoom = swiper.zoom;\n var params = swiper.params.zoom;\n var gesture = zoom.gesture;\n\n if (!gesture.$slideEl) {\n gesture.$slideEl = swiper.clickedSlide ? $(swiper.clickedSlide) : swiper.slides.eq(swiper.activeIndex);\n gesture.$imageEl = gesture.$slideEl.find('img, svg, canvas');\n gesture.$imageWrapEl = gesture.$imageEl.parent((\".\" + (params.containerClass)));\n }\n if (!gesture.$imageEl || gesture.$imageEl.length === 0) { return; }\n\n zoom.scale = 1;\n zoom.currentScale = 1;\n gesture.$imageWrapEl.transition(300).transform('translate3d(0,0,0)');\n gesture.$imageEl.transition(300).transform('translate3d(0,0,0) scale(1)');\n gesture.$slideEl.removeClass((\"\" + (params.zoomedSlideClass)));\n gesture.$slideEl = undefined;\n },\n // Attach/Detach Events\n enable: function enable() {\n var swiper = this;\n var zoom = swiper.zoom;\n if (zoom.enabled) { return; }\n zoom.enabled = true;\n\n var passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false;\n\n // Scale image\n if (Support.gestures) {\n swiper.$wrapperEl.on('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener);\n swiper.$wrapperEl.on('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener);\n swiper.$wrapperEl.on('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener);\n } else if (swiper.touchEvents.start === 'touchstart') {\n swiper.$wrapperEl.on(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener);\n swiper.$wrapperEl.on(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener);\n swiper.$wrapperEl.on(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener);\n }\n\n // Move image\n swiper.$wrapperEl.on(swiper.touchEvents.move, (\".\" + (swiper.params.zoom.containerClass)), zoom.onTouchMove);\n },\n disable: function disable() {\n var swiper = this;\n var zoom = swiper.zoom;\n if (!zoom.enabled) { return; }\n\n swiper.zoom.enabled = false;\n\n var passiveListener = swiper.touchEvents.start === 'touchstart' && Support.passiveListener && swiper.params.passiveListeners ? { passive: true, capture: false } : false;\n\n // Scale image\n if (Support.gestures) {\n swiper.$wrapperEl.off('gesturestart', '.swiper-slide', zoom.onGestureStart, passiveListener);\n swiper.$wrapperEl.off('gesturechange', '.swiper-slide', zoom.onGestureChange, passiveListener);\n swiper.$wrapperEl.off('gestureend', '.swiper-slide', zoom.onGestureEnd, passiveListener);\n } else if (swiper.touchEvents.start === 'touchstart') {\n swiper.$wrapperEl.off(swiper.touchEvents.start, '.swiper-slide', zoom.onGestureStart, passiveListener);\n swiper.$wrapperEl.off(swiper.touchEvents.move, '.swiper-slide', zoom.onGestureChange, passiveListener);\n swiper.$wrapperEl.off(swiper.touchEvents.end, '.swiper-slide', zoom.onGestureEnd, passiveListener);\n }\n\n // Move image\n swiper.$wrapperEl.off(swiper.touchEvents.move, (\".\" + (swiper.params.zoom.containerClass)), zoom.onTouchMove);\n },\n };\n\n var Zoom$1 = {\n name: 'zoom',\n params: {\n zoom: {\n enabled: false,\n maxRatio: 3,\n minRatio: 1,\n toggle: true,\n containerClass: 'swiper-zoom-container',\n zoomedSlideClass: 'swiper-slide-zoomed',\n },\n },\n create: function create() {\n var swiper = this;\n var zoom = {\n enabled: false,\n scale: 1,\n currentScale: 1,\n isScaling: false,\n gesture: {\n $slideEl: undefined,\n slideWidth: undefined,\n slideHeight: undefined,\n $imageEl: undefined,\n $imageWrapEl: undefined,\n maxRatio: 3,\n },\n image: {\n isTouched: undefined,\n isMoved: undefined,\n currentX: undefined,\n currentY: undefined,\n minX: undefined,\n minY: undefined,\n maxX: undefined,\n maxY: undefined,\n width: undefined,\n height: undefined,\n startX: undefined,\n startY: undefined,\n touchesStart: {},\n touchesCurrent: {},\n },\n velocity: {\n x: undefined,\n y: undefined,\n prevPositionX: undefined,\n prevPositionY: undefined,\n prevTime: undefined,\n },\n };\n\n ('onGestureStart onGestureChange onGestureEnd onTouchStart onTouchMove onTouchEnd onTransitionEnd toggle enable disable in out').split(' ').forEach(function (methodName) {\n zoom[methodName] = Zoom[methodName].bind(swiper);\n });\n Utils.extend(swiper, {\n zoom: zoom,\n });\n\n var scale = 1;\n Object.defineProperty(swiper.zoom, 'scale', {\n get: function get() {\n return scale;\n },\n set: function set(value) {\n if (scale !== value) {\n var imageEl = swiper.zoom.gesture.$imageEl ? swiper.zoom.gesture.$imageEl[0] : undefined;\n var slideEl = swiper.zoom.gesture.$slideEl ? swiper.zoom.gesture.$slideEl[0] : undefined;\n swiper.emit('zoomChange', value, imageEl, slideEl);\n }\n scale = value;\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n if (swiper.params.zoom.enabled) {\n swiper.zoom.enable();\n }\n },\n destroy: function destroy() {\n var swiper = this;\n swiper.zoom.disable();\n },\n touchStart: function touchStart(e) {\n var swiper = this;\n if (!swiper.zoom.enabled) { return; }\n swiper.zoom.onTouchStart(e);\n },\n touchEnd: function touchEnd(e) {\n var swiper = this;\n if (!swiper.zoom.enabled) { return; }\n swiper.zoom.onTouchEnd(e);\n },\n doubleTap: function doubleTap(e) {\n var swiper = this;\n if (swiper.params.zoom.enabled && swiper.zoom.enabled && swiper.params.zoom.toggle) {\n swiper.zoom.toggle(e);\n }\n },\n transitionEnd: function transitionEnd() {\n var swiper = this;\n if (swiper.zoom.enabled && swiper.params.zoom.enabled) {\n swiper.zoom.onTransitionEnd();\n }\n },\n },\n };\n\n var Lazy = {\n loadInSlide: function loadInSlide(index, loadInDuplicate) {\n if ( loadInDuplicate === void 0 ) loadInDuplicate = true;\n\n var swiper = this;\n var params = swiper.params.lazy;\n if (typeof index === 'undefined') { return; }\n if (swiper.slides.length === 0) { return; }\n var isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n\n var $slideEl = isVirtual\n ? swiper.$wrapperEl.children((\".\" + (swiper.params.slideClass) + \"[data-swiper-slide-index=\\\"\" + index + \"\\\"]\"))\n : swiper.slides.eq(index);\n\n var $images = $slideEl.find((\".\" + (params.elementClass) + \":not(.\" + (params.loadedClass) + \"):not(.\" + (params.loadingClass) + \")\"));\n if ($slideEl.hasClass(params.elementClass) && !$slideEl.hasClass(params.loadedClass) && !$slideEl.hasClass(params.loadingClass)) {\n $images = $images.add($slideEl[0]);\n }\n if ($images.length === 0) { return; }\n\n $images.each(function (imageIndex, imageEl) {\n var $imageEl = $(imageEl);\n $imageEl.addClass(params.loadingClass);\n\n var background = $imageEl.attr('data-background');\n var src = $imageEl.attr('data-src');\n var srcset = $imageEl.attr('data-srcset');\n var sizes = $imageEl.attr('data-sizes');\n\n swiper.loadImage($imageEl[0], (src || background), srcset, sizes, false, function () {\n if (typeof swiper === 'undefined' || swiper === null || !swiper || (swiper && !swiper.params) || swiper.destroyed) { return; }\n if (background) {\n $imageEl.css('background-image', (\"url(\\\"\" + background + \"\\\")\"));\n $imageEl.removeAttr('data-background');\n } else {\n if (srcset) {\n $imageEl.attr('srcset', srcset);\n $imageEl.removeAttr('data-srcset');\n }\n if (sizes) {\n $imageEl.attr('sizes', sizes);\n $imageEl.removeAttr('data-sizes');\n }\n if (src) {\n $imageEl.attr('src', src);\n $imageEl.removeAttr('data-src');\n }\n }\n\n $imageEl.addClass(params.loadedClass).removeClass(params.loadingClass);\n $slideEl.find((\".\" + (params.preloaderClass))).remove();\n if (swiper.params.loop && loadInDuplicate) {\n var slideOriginalIndex = $slideEl.attr('data-swiper-slide-index');\n if ($slideEl.hasClass(swiper.params.slideDuplicateClass)) {\n var originalSlide = swiper.$wrapperEl.children((\"[data-swiper-slide-index=\\\"\" + slideOriginalIndex + \"\\\"]:not(.\" + (swiper.params.slideDuplicateClass) + \")\"));\n swiper.lazy.loadInSlide(originalSlide.index(), false);\n } else {\n var duplicatedSlide = swiper.$wrapperEl.children((\".\" + (swiper.params.slideDuplicateClass) + \"[data-swiper-slide-index=\\\"\" + slideOriginalIndex + \"\\\"]\"));\n swiper.lazy.loadInSlide(duplicatedSlide.index(), false);\n }\n }\n swiper.emit('lazyImageReady', $slideEl[0], $imageEl[0]);\n });\n\n swiper.emit('lazyImageLoad', $slideEl[0], $imageEl[0]);\n });\n },\n load: function load() {\n var swiper = this;\n var $wrapperEl = swiper.$wrapperEl;\n var swiperParams = swiper.params;\n var slides = swiper.slides;\n var activeIndex = swiper.activeIndex;\n var isVirtual = swiper.virtual && swiperParams.virtual.enabled;\n var params = swiperParams.lazy;\n\n var slidesPerView = swiperParams.slidesPerView;\n if (slidesPerView === 'auto') {\n slidesPerView = 0;\n }\n\n function slideExist(index) {\n if (isVirtual) {\n if ($wrapperEl.children((\".\" + (swiperParams.slideClass) + \"[data-swiper-slide-index=\\\"\" + index + \"\\\"]\")).length) {\n return true;\n }\n } else if (slides[index]) { return true; }\n return false;\n }\n function slideIndex(slideEl) {\n if (isVirtual) {\n return $(slideEl).attr('data-swiper-slide-index');\n }\n return $(slideEl).index();\n }\n\n if (!swiper.lazy.initialImageLoaded) { swiper.lazy.initialImageLoaded = true; }\n if (swiper.params.watchSlidesVisibility) {\n $wrapperEl.children((\".\" + (swiperParams.slideVisibleClass))).each(function (elIndex, slideEl) {\n var index = isVirtual ? $(slideEl).attr('data-swiper-slide-index') : $(slideEl).index();\n swiper.lazy.loadInSlide(index);\n });\n } else if (slidesPerView > 1) {\n for (var i = activeIndex; i < activeIndex + slidesPerView; i += 1) {\n if (slideExist(i)) { swiper.lazy.loadInSlide(i); }\n }\n } else {\n swiper.lazy.loadInSlide(activeIndex);\n }\n if (params.loadPrevNext) {\n if (slidesPerView > 1 || (params.loadPrevNextAmount && params.loadPrevNextAmount > 1)) {\n var amount = params.loadPrevNextAmount;\n var spv = slidesPerView;\n var maxIndex = Math.min(activeIndex + spv + Math.max(amount, spv), slides.length);\n var minIndex = Math.max(activeIndex - Math.max(spv, amount), 0);\n // Next Slides\n for (var i$1 = activeIndex + slidesPerView; i$1 < maxIndex; i$1 += 1) {\n if (slideExist(i$1)) { swiper.lazy.loadInSlide(i$1); }\n }\n // Prev Slides\n for (var i$2 = minIndex; i$2 < activeIndex; i$2 += 1) {\n if (slideExist(i$2)) { swiper.lazy.loadInSlide(i$2); }\n }\n } else {\n var nextSlide = $wrapperEl.children((\".\" + (swiperParams.slideNextClass)));\n if (nextSlide.length > 0) { swiper.lazy.loadInSlide(slideIndex(nextSlide)); }\n\n var prevSlide = $wrapperEl.children((\".\" + (swiperParams.slidePrevClass)));\n if (prevSlide.length > 0) { swiper.lazy.loadInSlide(slideIndex(prevSlide)); }\n }\n }\n },\n };\n\n var Lazy$1 = {\n name: 'lazy',\n params: {\n lazy: {\n enabled: false,\n loadPrevNext: false,\n loadPrevNextAmount: 1,\n loadOnTransitionStart: false,\n\n elementClass: 'swiper-lazy',\n loadingClass: 'swiper-lazy-loading',\n loadedClass: 'swiper-lazy-loaded',\n preloaderClass: 'swiper-lazy-preloader',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n lazy: {\n initialImageLoaded: false,\n load: Lazy.load.bind(swiper),\n loadInSlide: Lazy.loadInSlide.bind(swiper),\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n if (swiper.params.lazy.enabled && swiper.params.preloadImages) {\n swiper.params.preloadImages = false;\n }\n },\n init: function init() {\n var swiper = this;\n if (swiper.params.lazy.enabled && !swiper.params.loop && swiper.params.initialSlide === 0) {\n swiper.lazy.load();\n }\n },\n scroll: function scroll() {\n var swiper = this;\n if (swiper.params.freeMode && !swiper.params.freeModeSticky) {\n swiper.lazy.load();\n }\n },\n resize: function resize() {\n var swiper = this;\n if (swiper.params.lazy.enabled) {\n swiper.lazy.load();\n }\n },\n scrollbarDragMove: function scrollbarDragMove() {\n var swiper = this;\n if (swiper.params.lazy.enabled) {\n swiper.lazy.load();\n }\n },\n transitionStart: function transitionStart() {\n var swiper = this;\n if (swiper.params.lazy.enabled) {\n if (swiper.params.lazy.loadOnTransitionStart || (!swiper.params.lazy.loadOnTransitionStart && !swiper.lazy.initialImageLoaded)) {\n swiper.lazy.load();\n }\n }\n },\n transitionEnd: function transitionEnd() {\n var swiper = this;\n if (swiper.params.lazy.enabled && !swiper.params.lazy.loadOnTransitionStart) {\n swiper.lazy.load();\n }\n },\n },\n };\n\n /* eslint no-bitwise: [\"error\", { \"allow\": [\">>\"] }] */\n\n var Controller = {\n LinearSpline: function LinearSpline(x, y) {\n var binarySearch = (function search() {\n var maxIndex;\n var minIndex;\n var guess;\n return function (array, val) {\n minIndex = -1;\n maxIndex = array.length;\n while (maxIndex - minIndex > 1) {\n guess = maxIndex + minIndex >> 1;\n if (array[guess] <= val) {\n minIndex = guess;\n } else {\n maxIndex = guess;\n }\n }\n return maxIndex;\n };\n }());\n this.x = x;\n this.y = y;\n this.lastIndex = x.length - 1;\n // Given an x value (x2), return the expected y2 value:\n // (x1,y1) is the known point before given value,\n // (x3,y3) is the known point after given value.\n var i1;\n var i3;\n\n this.interpolate = function interpolate(x2) {\n if (!x2) { return 0; }\n\n // Get the indexes of x1 and x3 (the array indexes before and after given x2):\n i3 = binarySearch(this.x, x2);\n i1 = i3 - 1;\n\n // We have our indexes i1 & i3, so we can calculate already:\n // y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1\n return (((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1])) + this.y[i1];\n };\n return this;\n },\n // xxx: for now i will just save one spline function to to\n getInterpolateFunction: function getInterpolateFunction(c) {\n var swiper = this;\n if (!swiper.controller.spline) {\n swiper.controller.spline = swiper.params.loop\n ? new Controller.LinearSpline(swiper.slidesGrid, c.slidesGrid)\n : new Controller.LinearSpline(swiper.snapGrid, c.snapGrid);\n }\n },\n setTranslate: function setTranslate(setTranslate$1, byController) {\n var swiper = this;\n var controlled = swiper.controller.control;\n var multiplier;\n var controlledTranslate;\n function setControlledTranslate(c) {\n // this will create an Interpolate function based on the snapGrids\n // x is the Grid of the scrolled scroller and y will be the controlled scroller\n // it makes sense to create this only once and recall it for the interpolation\n // the function does a lot of value caching for performance\n var translate = swiper.rtlTranslate ? -swiper.translate : swiper.translate;\n if (swiper.params.controller.by === 'slide') {\n swiper.controller.getInterpolateFunction(c);\n // i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid\n // but it did not work out\n controlledTranslate = -swiper.controller.spline.interpolate(-translate);\n }\n\n if (!controlledTranslate || swiper.params.controller.by === 'container') {\n multiplier = (c.maxTranslate() - c.minTranslate()) / (swiper.maxTranslate() - swiper.minTranslate());\n controlledTranslate = ((translate - swiper.minTranslate()) * multiplier) + c.minTranslate();\n }\n\n if (swiper.params.controller.inverse) {\n controlledTranslate = c.maxTranslate() - controlledTranslate;\n }\n c.updateProgress(controlledTranslate);\n c.setTranslate(controlledTranslate, swiper);\n c.updateActiveIndex();\n c.updateSlidesClasses();\n }\n if (Array.isArray(controlled)) {\n for (var i = 0; i < controlled.length; i += 1) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n setControlledTranslate(controlled[i]);\n }\n }\n } else if (controlled instanceof Swiper && byController !== controlled) {\n setControlledTranslate(controlled);\n }\n },\n setTransition: function setTransition(duration, byController) {\n var swiper = this;\n var controlled = swiper.controller.control;\n var i;\n function setControlledTransition(c) {\n c.setTransition(duration, swiper);\n if (duration !== 0) {\n c.transitionStart();\n if (c.params.autoHeight) {\n Utils.nextTick(function () {\n c.updateAutoHeight();\n });\n }\n c.$wrapperEl.transitionEnd(function () {\n if (!controlled) { return; }\n if (c.params.loop && swiper.params.controller.by === 'slide') {\n c.loopFix();\n }\n c.transitionEnd();\n });\n }\n }\n if (Array.isArray(controlled)) {\n for (i = 0; i < controlled.length; i += 1) {\n if (controlled[i] !== byController && controlled[i] instanceof Swiper) {\n setControlledTransition(controlled[i]);\n }\n }\n } else if (controlled instanceof Swiper && byController !== controlled) {\n setControlledTransition(controlled);\n }\n },\n };\n var Controller$1 = {\n name: 'controller',\n params: {\n controller: {\n control: undefined,\n inverse: false,\n by: 'slide', // or 'container'\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n controller: {\n control: swiper.params.controller.control,\n getInterpolateFunction: Controller.getInterpolateFunction.bind(swiper),\n setTranslate: Controller.setTranslate.bind(swiper),\n setTransition: Controller.setTransition.bind(swiper),\n },\n });\n },\n on: {\n update: function update() {\n var swiper = this;\n if (!swiper.controller.control) { return; }\n if (swiper.controller.spline) {\n swiper.controller.spline = undefined;\n delete swiper.controller.spline;\n }\n },\n resize: function resize() {\n var swiper = this;\n if (!swiper.controller.control) { return; }\n if (swiper.controller.spline) {\n swiper.controller.spline = undefined;\n delete swiper.controller.spline;\n }\n },\n observerUpdate: function observerUpdate() {\n var swiper = this;\n if (!swiper.controller.control) { return; }\n if (swiper.controller.spline) {\n swiper.controller.spline = undefined;\n delete swiper.controller.spline;\n }\n },\n setTranslate: function setTranslate(translate, byController) {\n var swiper = this;\n if (!swiper.controller.control) { return; }\n swiper.controller.setTranslate(translate, byController);\n },\n setTransition: function setTransition(duration, byController) {\n var swiper = this;\n if (!swiper.controller.control) { return; }\n swiper.controller.setTransition(duration, byController);\n },\n },\n };\n\n var a11y = {\n makeElFocusable: function makeElFocusable($el) {\n $el.attr('tabIndex', '0');\n return $el;\n },\n addElRole: function addElRole($el, role) {\n $el.attr('role', role);\n return $el;\n },\n addElLabel: function addElLabel($el, label) {\n $el.attr('aria-label', label);\n return $el;\n },\n disableEl: function disableEl($el) {\n $el.attr('aria-disabled', true);\n return $el;\n },\n enableEl: function enableEl($el) {\n $el.attr('aria-disabled', false);\n return $el;\n },\n onEnterKey: function onEnterKey(e) {\n var swiper = this;\n var params = swiper.params.a11y;\n if (e.keyCode !== 13) { return; }\n var $targetEl = $(e.target);\n if (swiper.navigation && swiper.navigation.$nextEl && $targetEl.is(swiper.navigation.$nextEl)) {\n if (!(swiper.isEnd && !swiper.params.loop)) {\n swiper.slideNext();\n }\n if (swiper.isEnd) {\n swiper.a11y.notify(params.lastSlideMessage);\n } else {\n swiper.a11y.notify(params.nextSlideMessage);\n }\n }\n if (swiper.navigation && swiper.navigation.$prevEl && $targetEl.is(swiper.navigation.$prevEl)) {\n if (!(swiper.isBeginning && !swiper.params.loop)) {\n swiper.slidePrev();\n }\n if (swiper.isBeginning) {\n swiper.a11y.notify(params.firstSlideMessage);\n } else {\n swiper.a11y.notify(params.prevSlideMessage);\n }\n }\n if (swiper.pagination && $targetEl.is((\".\" + (swiper.params.pagination.bulletClass)))) {\n $targetEl[0].click();\n }\n },\n notify: function notify(message) {\n var swiper = this;\n var notification = swiper.a11y.liveRegion;\n if (notification.length === 0) { return; }\n notification.html('');\n notification.html(message);\n },\n updateNavigation: function updateNavigation() {\n var swiper = this;\n\n if (swiper.params.loop) { return; }\n var ref = swiper.navigation;\n var $nextEl = ref.$nextEl;\n var $prevEl = ref.$prevEl;\n\n if ($prevEl && $prevEl.length > 0) {\n if (swiper.isBeginning) {\n swiper.a11y.disableEl($prevEl);\n } else {\n swiper.a11y.enableEl($prevEl);\n }\n }\n if ($nextEl && $nextEl.length > 0) {\n if (swiper.isEnd) {\n swiper.a11y.disableEl($nextEl);\n } else {\n swiper.a11y.enableEl($nextEl);\n }\n }\n },\n updatePagination: function updatePagination() {\n var swiper = this;\n var params = swiper.params.a11y;\n if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {\n swiper.pagination.bullets.each(function (bulletIndex, bulletEl) {\n var $bulletEl = $(bulletEl);\n swiper.a11y.makeElFocusable($bulletEl);\n swiper.a11y.addElRole($bulletEl, 'button');\n swiper.a11y.addElLabel($bulletEl, params.paginationBulletMessage.replace(/{{index}}/, $bulletEl.index() + 1));\n });\n }\n },\n init: function init() {\n var swiper = this;\n\n swiper.$el.append(swiper.a11y.liveRegion);\n\n // Navigation\n var params = swiper.params.a11y;\n var $nextEl;\n var $prevEl;\n if (swiper.navigation && swiper.navigation.$nextEl) {\n $nextEl = swiper.navigation.$nextEl;\n }\n if (swiper.navigation && swiper.navigation.$prevEl) {\n $prevEl = swiper.navigation.$prevEl;\n }\n if ($nextEl) {\n swiper.a11y.makeElFocusable($nextEl);\n swiper.a11y.addElRole($nextEl, 'button');\n swiper.a11y.addElLabel($nextEl, params.nextSlideMessage);\n $nextEl.on('keydown', swiper.a11y.onEnterKey);\n }\n if ($prevEl) {\n swiper.a11y.makeElFocusable($prevEl);\n swiper.a11y.addElRole($prevEl, 'button');\n swiper.a11y.addElLabel($prevEl, params.prevSlideMessage);\n $prevEl.on('keydown', swiper.a11y.onEnterKey);\n }\n\n // Pagination\n if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {\n swiper.pagination.$el.on('keydown', (\".\" + (swiper.params.pagination.bulletClass)), swiper.a11y.onEnterKey);\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.a11y.liveRegion && swiper.a11y.liveRegion.length > 0) { swiper.a11y.liveRegion.remove(); }\n\n var $nextEl;\n var $prevEl;\n if (swiper.navigation && swiper.navigation.$nextEl) {\n $nextEl = swiper.navigation.$nextEl;\n }\n if (swiper.navigation && swiper.navigation.$prevEl) {\n $prevEl = swiper.navigation.$prevEl;\n }\n if ($nextEl) {\n $nextEl.off('keydown', swiper.a11y.onEnterKey);\n }\n if ($prevEl) {\n $prevEl.off('keydown', swiper.a11y.onEnterKey);\n }\n\n // Pagination\n if (swiper.pagination && swiper.params.pagination.clickable && swiper.pagination.bullets && swiper.pagination.bullets.length) {\n swiper.pagination.$el.off('keydown', (\".\" + (swiper.params.pagination.bulletClass)), swiper.a11y.onEnterKey);\n }\n },\n };\n var A11y = {\n name: 'a11y',\n params: {\n a11y: {\n enabled: true,\n notificationClass: 'swiper-notification',\n prevSlideMessage: 'Previous slide',\n nextSlideMessage: 'Next slide',\n firstSlideMessage: 'This is the first slide',\n lastSlideMessage: 'This is the last slide',\n paginationBulletMessage: 'Go to slide {{index}}',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n a11y: {\n liveRegion: $((\"\")),\n },\n });\n Object.keys(a11y).forEach(function (methodName) {\n swiper.a11y[methodName] = a11y[methodName].bind(swiper);\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n if (!swiper.params.a11y.enabled) { return; }\n swiper.a11y.init();\n swiper.a11y.updateNavigation();\n },\n toEdge: function toEdge() {\n var swiper = this;\n if (!swiper.params.a11y.enabled) { return; }\n swiper.a11y.updateNavigation();\n },\n fromEdge: function fromEdge() {\n var swiper = this;\n if (!swiper.params.a11y.enabled) { return; }\n swiper.a11y.updateNavigation();\n },\n paginationUpdate: function paginationUpdate() {\n var swiper = this;\n if (!swiper.params.a11y.enabled) { return; }\n swiper.a11y.updatePagination();\n },\n destroy: function destroy() {\n var swiper = this;\n if (!swiper.params.a11y.enabled) { return; }\n swiper.a11y.destroy();\n },\n },\n };\n\n var History = {\n init: function init() {\n var swiper = this;\n if (!swiper.params.history) { return; }\n if (!win.history || !win.history.pushState) {\n swiper.params.history.enabled = false;\n swiper.params.hashNavigation.enabled = true;\n return;\n }\n var history = swiper.history;\n history.initialized = true;\n history.paths = History.getPathValues();\n if (!history.paths.key && !history.paths.value) { return; }\n history.scrollToSlide(0, history.paths.value, swiper.params.runCallbacksOnInit);\n if (!swiper.params.history.replaceState) {\n win.addEventListener('popstate', swiper.history.setHistoryPopState);\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (!swiper.params.history.replaceState) {\n win.removeEventListener('popstate', swiper.history.setHistoryPopState);\n }\n },\n setHistoryPopState: function setHistoryPopState() {\n var swiper = this;\n swiper.history.paths = History.getPathValues();\n swiper.history.scrollToSlide(swiper.params.speed, swiper.history.paths.value, false);\n },\n getPathValues: function getPathValues() {\n var pathArray = win.location.pathname.slice(1).split('/').filter(function (part) { return part !== ''; });\n var total = pathArray.length;\n var key = pathArray[total - 2];\n var value = pathArray[total - 1];\n return { key: key, value: value };\n },\n setHistory: function setHistory(key, index) {\n var swiper = this;\n if (!swiper.history.initialized || !swiper.params.history.enabled) { return; }\n var slide = swiper.slides.eq(index);\n var value = History.slugify(slide.attr('data-history'));\n if (!win.location.pathname.includes(key)) {\n value = key + \"/\" + value;\n }\n var currentState = win.history.state;\n if (currentState && currentState.value === value) {\n return;\n }\n if (swiper.params.history.replaceState) {\n win.history.replaceState({ value: value }, null, value);\n } else {\n win.history.pushState({ value: value }, null, value);\n }\n },\n slugify: function slugify(text) {\n return text.toString()\n .replace(/\\s+/g, '-')\n .replace(/[^\\w-]+/g, '')\n .replace(/--+/g, '-')\n .replace(/^-+/, '')\n .replace(/-+$/, '');\n },\n scrollToSlide: function scrollToSlide(speed, value, runCallbacks) {\n var swiper = this;\n if (value) {\n for (var i = 0, length = swiper.slides.length; i < length; i += 1) {\n var slide = swiper.slides.eq(i);\n var slideHistory = History.slugify(slide.attr('data-history'));\n if (slideHistory === value && !slide.hasClass(swiper.params.slideDuplicateClass)) {\n var index = slide.index();\n swiper.slideTo(index, speed, runCallbacks);\n }\n }\n } else {\n swiper.slideTo(0, speed, runCallbacks);\n }\n },\n };\n\n var History$1 = {\n name: 'history',\n params: {\n history: {\n enabled: false,\n replaceState: false,\n key: 'slides',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n history: {\n init: History.init.bind(swiper),\n setHistory: History.setHistory.bind(swiper),\n setHistoryPopState: History.setHistoryPopState.bind(swiper),\n scrollToSlide: History.scrollToSlide.bind(swiper),\n destroy: History.destroy.bind(swiper),\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n if (swiper.params.history.enabled) {\n swiper.history.init();\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.params.history.enabled) {\n swiper.history.destroy();\n }\n },\n transitionEnd: function transitionEnd() {\n var swiper = this;\n if (swiper.history.initialized) {\n swiper.history.setHistory(swiper.params.history.key, swiper.activeIndex);\n }\n },\n },\n };\n\n var HashNavigation = {\n onHashCange: function onHashCange() {\n var swiper = this;\n var newHash = doc.location.hash.replace('#', '');\n var activeSlideHash = swiper.slides.eq(swiper.activeIndex).attr('data-hash');\n if (newHash !== activeSlideHash) {\n var newIndex = swiper.$wrapperEl.children((\".\" + (swiper.params.slideClass) + \"[data-hash=\\\"\" + newHash + \"\\\"]\")).index();\n if (typeof newIndex === 'undefined') { return; }\n swiper.slideTo(newIndex);\n }\n },\n setHash: function setHash() {\n var swiper = this;\n if (!swiper.hashNavigation.initialized || !swiper.params.hashNavigation.enabled) { return; }\n if (swiper.params.hashNavigation.replaceState && win.history && win.history.replaceState) {\n win.history.replaceState(null, null, ((\"#\" + (swiper.slides.eq(swiper.activeIndex).attr('data-hash'))) || ''));\n } else {\n var slide = swiper.slides.eq(swiper.activeIndex);\n var hash = slide.attr('data-hash') || slide.attr('data-history');\n doc.location.hash = hash || '';\n }\n },\n init: function init() {\n var swiper = this;\n if (!swiper.params.hashNavigation.enabled || (swiper.params.history && swiper.params.history.enabled)) { return; }\n swiper.hashNavigation.initialized = true;\n var hash = doc.location.hash.replace('#', '');\n if (hash) {\n var speed = 0;\n for (var i = 0, length = swiper.slides.length; i < length; i += 1) {\n var slide = swiper.slides.eq(i);\n var slideHash = slide.attr('data-hash') || slide.attr('data-history');\n if (slideHash === hash && !slide.hasClass(swiper.params.slideDuplicateClass)) {\n var index = slide.index();\n swiper.slideTo(index, speed, swiper.params.runCallbacksOnInit, true);\n }\n }\n }\n if (swiper.params.hashNavigation.watchState) {\n $(win).on('hashchange', swiper.hashNavigation.onHashCange);\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.params.hashNavigation.watchState) {\n $(win).off('hashchange', swiper.hashNavigation.onHashCange);\n }\n },\n };\n var HashNavigation$1 = {\n name: 'hash-navigation',\n params: {\n hashNavigation: {\n enabled: false,\n replaceState: false,\n watchState: false,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n hashNavigation: {\n initialized: false,\n init: HashNavigation.init.bind(swiper),\n destroy: HashNavigation.destroy.bind(swiper),\n setHash: HashNavigation.setHash.bind(swiper),\n onHashCange: HashNavigation.onHashCange.bind(swiper),\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n if (swiper.params.hashNavigation.enabled) {\n swiper.hashNavigation.init();\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.params.hashNavigation.enabled) {\n swiper.hashNavigation.destroy();\n }\n },\n transitionEnd: function transitionEnd() {\n var swiper = this;\n if (swiper.hashNavigation.initialized) {\n swiper.hashNavigation.setHash();\n }\n },\n },\n };\n\n /* eslint no-underscore-dangle: \"off\" */\n\n var Autoplay = {\n run: function run() {\n var swiper = this;\n var $activeSlideEl = swiper.slides.eq(swiper.activeIndex);\n var delay = swiper.params.autoplay.delay;\n if ($activeSlideEl.attr('data-swiper-autoplay')) {\n delay = $activeSlideEl.attr('data-swiper-autoplay') || swiper.params.autoplay.delay;\n }\n swiper.autoplay.timeout = Utils.nextTick(function () {\n if (swiper.params.autoplay.reverseDirection) {\n if (swiper.params.loop) {\n swiper.loopFix();\n swiper.slidePrev(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.isBeginning) {\n swiper.slidePrev(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else {\n swiper.autoplay.stop();\n }\n } else if (swiper.params.loop) {\n swiper.loopFix();\n swiper.slideNext(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.isEnd) {\n swiper.slideNext(swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else if (!swiper.params.autoplay.stopOnLastSlide) {\n swiper.slideTo(0, swiper.params.speed, true, true);\n swiper.emit('autoplay');\n } else {\n swiper.autoplay.stop();\n }\n }, delay);\n },\n start: function start() {\n var swiper = this;\n if (typeof swiper.autoplay.timeout !== 'undefined') { return false; }\n if (swiper.autoplay.running) { return false; }\n swiper.autoplay.running = true;\n swiper.emit('autoplayStart');\n swiper.autoplay.run();\n return true;\n },\n stop: function stop() {\n var swiper = this;\n if (!swiper.autoplay.running) { return false; }\n if (typeof swiper.autoplay.timeout === 'undefined') { return false; }\n\n if (swiper.autoplay.timeout) {\n clearTimeout(swiper.autoplay.timeout);\n swiper.autoplay.timeout = undefined;\n }\n swiper.autoplay.running = false;\n swiper.emit('autoplayStop');\n return true;\n },\n pause: function pause(speed) {\n var swiper = this;\n if (!swiper.autoplay.running) { return; }\n if (swiper.autoplay.paused) { return; }\n if (swiper.autoplay.timeout) { clearTimeout(swiper.autoplay.timeout); }\n swiper.autoplay.paused = true;\n if (speed === 0 || !swiper.params.autoplay.waitForTransition) {\n swiper.autoplay.paused = false;\n swiper.autoplay.run();\n } else {\n swiper.$wrapperEl[0].addEventListener('transitionend', swiper.autoplay.onTransitionEnd);\n swiper.$wrapperEl[0].addEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);\n }\n },\n };\n\n var Autoplay$1 = {\n name: 'autoplay',\n params: {\n autoplay: {\n enabled: false,\n delay: 3000,\n waitForTransition: true,\n disableOnInteraction: true,\n stopOnLastSlide: false,\n reverseDirection: false,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n autoplay: {\n running: false,\n paused: false,\n run: Autoplay.run.bind(swiper),\n start: Autoplay.start.bind(swiper),\n stop: Autoplay.stop.bind(swiper),\n pause: Autoplay.pause.bind(swiper),\n onTransitionEnd: function onTransitionEnd(e) {\n if (!swiper || swiper.destroyed || !swiper.$wrapperEl) { return; }\n if (e.target !== this) { return; }\n swiper.$wrapperEl[0].removeEventListener('transitionend', swiper.autoplay.onTransitionEnd);\n swiper.$wrapperEl[0].removeEventListener('webkitTransitionEnd', swiper.autoplay.onTransitionEnd);\n swiper.autoplay.paused = false;\n if (!swiper.autoplay.running) {\n swiper.autoplay.stop();\n } else {\n swiper.autoplay.run();\n }\n },\n },\n });\n },\n on: {\n init: function init() {\n var swiper = this;\n if (swiper.params.autoplay.enabled) {\n swiper.autoplay.start();\n }\n },\n beforeTransitionStart: function beforeTransitionStart(speed, internal) {\n var swiper = this;\n if (swiper.autoplay.running) {\n if (internal || !swiper.params.autoplay.disableOnInteraction) {\n swiper.autoplay.pause(speed);\n } else {\n swiper.autoplay.stop();\n }\n }\n },\n sliderFirstMove: function sliderFirstMove() {\n var swiper = this;\n if (swiper.autoplay.running) {\n if (swiper.params.autoplay.disableOnInteraction) {\n swiper.autoplay.stop();\n } else {\n swiper.autoplay.pause();\n }\n }\n },\n destroy: function destroy() {\n var swiper = this;\n if (swiper.autoplay.running) {\n swiper.autoplay.stop();\n }\n },\n },\n };\n\n var Fade = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var slides = swiper.slides;\n for (var i = 0; i < slides.length; i += 1) {\n var $slideEl = swiper.slides.eq(i);\n var offset = $slideEl[0].swiperSlideOffset;\n var tx = -offset;\n if (!swiper.params.virtualTranslate) { tx -= swiper.translate; }\n var ty = 0;\n if (!swiper.isHorizontal()) {\n ty = tx;\n tx = 0;\n }\n var slideOpacity = swiper.params.fadeEffect.crossFade\n ? Math.max(1 - Math.abs($slideEl[0].progress), 0)\n : 1 + Math.min(Math.max($slideEl[0].progress, -1), 0);\n $slideEl\n .css({\n opacity: slideOpacity,\n })\n .transform((\"translate3d(\" + tx + \"px, \" + ty + \"px, 0px)\"));\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n var slides = swiper.slides;\n var $wrapperEl = swiper.$wrapperEl;\n slides.transition(duration);\n if (swiper.params.virtualTranslate && duration !== 0) {\n var eventTriggered = false;\n slides.transitionEnd(function () {\n if (eventTriggered) { return; }\n if (!swiper || swiper.destroyed) { return; }\n eventTriggered = true;\n swiper.animating = false;\n var triggerEvents = ['webkitTransitionEnd', 'transitionend'];\n for (var i = 0; i < triggerEvents.length; i += 1) {\n $wrapperEl.trigger(triggerEvents[i]);\n }\n });\n }\n },\n };\n\n var EffectFade = {\n name: 'effect-fade',\n params: {\n fadeEffect: {\n crossFade: false,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n fadeEffect: {\n setTranslate: Fade.setTranslate.bind(swiper),\n setTransition: Fade.setTransition.bind(swiper),\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n if (swiper.params.effect !== 'fade') { return; }\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"fade\"));\n var overwriteParams = {\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n spaceBetween: 0,\n virtualTranslate: true,\n };\n Utils.extend(swiper.params, overwriteParams);\n Utils.extend(swiper.originalParams, overwriteParams);\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n if (swiper.params.effect !== 'fade') { return; }\n swiper.fadeEffect.setTranslate();\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n if (swiper.params.effect !== 'fade') { return; }\n swiper.fadeEffect.setTransition(duration);\n },\n },\n };\n\n var Cube = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var $el = swiper.$el;\n var $wrapperEl = swiper.$wrapperEl;\n var slides = swiper.slides;\n var swiperWidth = swiper.width;\n var swiperHeight = swiper.height;\n var rtl = swiper.rtlTranslate;\n var swiperSize = swiper.size;\n var params = swiper.params.cubeEffect;\n var isHorizontal = swiper.isHorizontal();\n var isVirtual = swiper.virtual && swiper.params.virtual.enabled;\n var wrapperRotate = 0;\n var $cubeShadowEl;\n if (params.shadow) {\n if (isHorizontal) {\n $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');\n if ($cubeShadowEl.length === 0) {\n $cubeShadowEl = $('
            ');\n $wrapperEl.append($cubeShadowEl);\n }\n $cubeShadowEl.css({ height: (swiperWidth + \"px\") });\n } else {\n $cubeShadowEl = $el.find('.swiper-cube-shadow');\n if ($cubeShadowEl.length === 0) {\n $cubeShadowEl = $('
            ');\n $el.append($cubeShadowEl);\n }\n }\n }\n for (var i = 0; i < slides.length; i += 1) {\n var $slideEl = slides.eq(i);\n var slideIndex = i;\n if (isVirtual) {\n slideIndex = parseInt($slideEl.attr('data-swiper-slide-index'), 10);\n }\n var slideAngle = slideIndex * 90;\n var round = Math.floor(slideAngle / 360);\n if (rtl) {\n slideAngle = -slideAngle;\n round = Math.floor(-slideAngle / 360);\n }\n var progress = Math.max(Math.min($slideEl[0].progress, 1), -1);\n var tx = 0;\n var ty = 0;\n var tz = 0;\n if (slideIndex % 4 === 0) {\n tx = -round * 4 * swiperSize;\n tz = 0;\n } else if ((slideIndex - 1) % 4 === 0) {\n tx = 0;\n tz = -round * 4 * swiperSize;\n } else if ((slideIndex - 2) % 4 === 0) {\n tx = swiperSize + (round * 4 * swiperSize);\n tz = swiperSize;\n } else if ((slideIndex - 3) % 4 === 0) {\n tx = -swiperSize;\n tz = (3 * swiperSize) + (swiperSize * 4 * round);\n }\n if (rtl) {\n tx = -tx;\n }\n\n if (!isHorizontal) {\n ty = tx;\n tx = 0;\n }\n\n var transform = \"rotateX(\" + (isHorizontal ? 0 : -slideAngle) + \"deg) rotateY(\" + (isHorizontal ? slideAngle : 0) + \"deg) translate3d(\" + tx + \"px, \" + ty + \"px, \" + tz + \"px)\";\n if (progress <= 1 && progress > -1) {\n wrapperRotate = (slideIndex * 90) + (progress * 90);\n if (rtl) { wrapperRotate = (-slideIndex * 90) - (progress * 90); }\n }\n $slideEl.transform(transform);\n if (params.slideShadows) {\n // Set shadows\n var shadowBefore = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n var shadowAfter = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n if (shadowBefore.length === 0) {\n shadowBefore = $((\"
            \"));\n $slideEl.append(shadowBefore);\n }\n if (shadowAfter.length === 0) {\n shadowAfter = $((\"
            \"));\n $slideEl.append(shadowAfter);\n }\n if (shadowBefore.length) { shadowBefore[0].style.opacity = Math.max(-progress, 0); }\n if (shadowAfter.length) { shadowAfter[0].style.opacity = Math.max(progress, 0); }\n }\n }\n $wrapperEl.css({\n '-webkit-transform-origin': (\"50% 50% -\" + (swiperSize / 2) + \"px\"),\n '-moz-transform-origin': (\"50% 50% -\" + (swiperSize / 2) + \"px\"),\n '-ms-transform-origin': (\"50% 50% -\" + (swiperSize / 2) + \"px\"),\n 'transform-origin': (\"50% 50% -\" + (swiperSize / 2) + \"px\"),\n });\n\n if (params.shadow) {\n if (isHorizontal) {\n $cubeShadowEl.transform((\"translate3d(0px, \" + ((swiperWidth / 2) + params.shadowOffset) + \"px, \" + (-swiperWidth / 2) + \"px) rotateX(90deg) rotateZ(0deg) scale(\" + (params.shadowScale) + \")\"));\n } else {\n var shadowAngle = Math.abs(wrapperRotate) - (Math.floor(Math.abs(wrapperRotate) / 90) * 90);\n var multiplier = 1.5 - (\n (Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2)\n + (Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2)\n );\n var scale1 = params.shadowScale;\n var scale2 = params.shadowScale / multiplier;\n var offset = params.shadowOffset;\n $cubeShadowEl.transform((\"scale3d(\" + scale1 + \", 1, \" + scale2 + \") translate3d(0px, \" + ((swiperHeight / 2) + offset) + \"px, \" + (-swiperHeight / 2 / scale2) + \"px) rotateX(-90deg)\"));\n }\n }\n var zFactor = (Browser.isSafari || Browser.isUiWebView) ? (-swiperSize / 2) : 0;\n $wrapperEl\n .transform((\"translate3d(0px,0,\" + zFactor + \"px) rotateX(\" + (swiper.isHorizontal() ? 0 : wrapperRotate) + \"deg) rotateY(\" + (swiper.isHorizontal() ? -wrapperRotate : 0) + \"deg)\"));\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n var $el = swiper.$el;\n var slides = swiper.slides;\n slides\n .transition(duration)\n .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left')\n .transition(duration);\n if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {\n $el.find('.swiper-cube-shadow').transition(duration);\n }\n },\n };\n\n var EffectCube = {\n name: 'effect-cube',\n params: {\n cubeEffect: {\n slideShadows: true,\n shadow: true,\n shadowOffset: 20,\n shadowScale: 0.94,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n cubeEffect: {\n setTranslate: Cube.setTranslate.bind(swiper),\n setTransition: Cube.setTransition.bind(swiper),\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n if (swiper.params.effect !== 'cube') { return; }\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"cube\"));\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"3d\"));\n var overwriteParams = {\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n resistanceRatio: 0,\n spaceBetween: 0,\n centeredSlides: false,\n virtualTranslate: true,\n };\n Utils.extend(swiper.params, overwriteParams);\n Utils.extend(swiper.originalParams, overwriteParams);\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n if (swiper.params.effect !== 'cube') { return; }\n swiper.cubeEffect.setTranslate();\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n if (swiper.params.effect !== 'cube') { return; }\n swiper.cubeEffect.setTransition(duration);\n },\n },\n };\n\n var Flip = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var slides = swiper.slides;\n var rtl = swiper.rtlTranslate;\n for (var i = 0; i < slides.length; i += 1) {\n var $slideEl = slides.eq(i);\n var progress = $slideEl[0].progress;\n if (swiper.params.flipEffect.limitRotation) {\n progress = Math.max(Math.min($slideEl[0].progress, 1), -1);\n }\n var offset = $slideEl[0].swiperSlideOffset;\n var rotate = -180 * progress;\n var rotateY = rotate;\n var rotateX = 0;\n var tx = -offset;\n var ty = 0;\n if (!swiper.isHorizontal()) {\n ty = tx;\n tx = 0;\n rotateX = -rotateY;\n rotateY = 0;\n } else if (rtl) {\n rotateY = -rotateY;\n }\n\n $slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length;\n\n if (swiper.params.flipEffect.slideShadows) {\n // Set shadows\n var shadowBefore = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n var shadowAfter = swiper.isHorizontal() ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n if (shadowBefore.length === 0) {\n shadowBefore = $((\"
            \"));\n $slideEl.append(shadowBefore);\n }\n if (shadowAfter.length === 0) {\n shadowAfter = $((\"
            \"));\n $slideEl.append(shadowAfter);\n }\n if (shadowBefore.length) { shadowBefore[0].style.opacity = Math.max(-progress, 0); }\n if (shadowAfter.length) { shadowAfter[0].style.opacity = Math.max(progress, 0); }\n }\n $slideEl\n .transform((\"translate3d(\" + tx + \"px, \" + ty + \"px, 0px) rotateX(\" + rotateX + \"deg) rotateY(\" + rotateY + \"deg)\"));\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n var slides = swiper.slides;\n var activeIndex = swiper.activeIndex;\n var $wrapperEl = swiper.$wrapperEl;\n slides\n .transition(duration)\n .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left')\n .transition(duration);\n if (swiper.params.virtualTranslate && duration !== 0) {\n var eventTriggered = false;\n // eslint-disable-next-line\n slides.eq(activeIndex).transitionEnd(function onTransitionEnd() {\n if (eventTriggered) { return; }\n if (!swiper || swiper.destroyed) { return; }\n // if (!$(this).hasClass(swiper.params.slideActiveClass)) return;\n eventTriggered = true;\n swiper.animating = false;\n var triggerEvents = ['webkitTransitionEnd', 'transitionend'];\n for (var i = 0; i < triggerEvents.length; i += 1) {\n $wrapperEl.trigger(triggerEvents[i]);\n }\n });\n }\n },\n };\n\n var EffectFlip = {\n name: 'effect-flip',\n params: {\n flipEffect: {\n slideShadows: true,\n limitRotation: true,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n flipEffect: {\n setTranslate: Flip.setTranslate.bind(swiper),\n setTransition: Flip.setTransition.bind(swiper),\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n if (swiper.params.effect !== 'flip') { return; }\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"flip\"));\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"3d\"));\n var overwriteParams = {\n slidesPerView: 1,\n slidesPerColumn: 1,\n slidesPerGroup: 1,\n watchSlidesProgress: true,\n spaceBetween: 0,\n virtualTranslate: true,\n };\n Utils.extend(swiper.params, overwriteParams);\n Utils.extend(swiper.originalParams, overwriteParams);\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n if (swiper.params.effect !== 'flip') { return; }\n swiper.flipEffect.setTranslate();\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n if (swiper.params.effect !== 'flip') { return; }\n swiper.flipEffect.setTransition(duration);\n },\n },\n };\n\n var Coverflow = {\n setTranslate: function setTranslate() {\n var swiper = this;\n var swiperWidth = swiper.width;\n var swiperHeight = swiper.height;\n var slides = swiper.slides;\n var $wrapperEl = swiper.$wrapperEl;\n var slidesSizesGrid = swiper.slidesSizesGrid;\n var params = swiper.params.coverflowEffect;\n var isHorizontal = swiper.isHorizontal();\n var transform = swiper.translate;\n var center = isHorizontal ? -transform + (swiperWidth / 2) : -transform + (swiperHeight / 2);\n var rotate = isHorizontal ? params.rotate : -params.rotate;\n var translate = params.depth;\n // Each slide offset from center\n for (var i = 0, length = slides.length; i < length; i += 1) {\n var $slideEl = slides.eq(i);\n var slideSize = slidesSizesGrid[i];\n var slideOffset = $slideEl[0].swiperSlideOffset;\n var offsetMultiplier = ((center - slideOffset - (slideSize / 2)) / slideSize) * params.modifier;\n\n var rotateY = isHorizontal ? rotate * offsetMultiplier : 0;\n var rotateX = isHorizontal ? 0 : rotate * offsetMultiplier;\n // var rotateZ = 0\n var translateZ = -translate * Math.abs(offsetMultiplier);\n\n var translateY = isHorizontal ? 0 : params.stretch * (offsetMultiplier);\n var translateX = isHorizontal ? params.stretch * (offsetMultiplier) : 0;\n\n // Fix for ultra small values\n if (Math.abs(translateX) < 0.001) { translateX = 0; }\n if (Math.abs(translateY) < 0.001) { translateY = 0; }\n if (Math.abs(translateZ) < 0.001) { translateZ = 0; }\n if (Math.abs(rotateY) < 0.001) { rotateY = 0; }\n if (Math.abs(rotateX) < 0.001) { rotateX = 0; }\n\n var slideTransform = \"translate3d(\" + translateX + \"px,\" + translateY + \"px,\" + translateZ + \"px) rotateX(\" + rotateX + \"deg) rotateY(\" + rotateY + \"deg)\";\n\n $slideEl.transform(slideTransform);\n $slideEl[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;\n if (params.slideShadows) {\n // Set shadows\n var $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');\n var $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');\n if ($shadowBeforeEl.length === 0) {\n $shadowBeforeEl = $((\"
            \"));\n $slideEl.append($shadowBeforeEl);\n }\n if ($shadowAfterEl.length === 0) {\n $shadowAfterEl = $((\"
            \"));\n $slideEl.append($shadowAfterEl);\n }\n if ($shadowBeforeEl.length) { $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0; }\n if ($shadowAfterEl.length) { $shadowAfterEl[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0; }\n }\n }\n\n // Set correct perspective for IE10\n if (Support.pointerEvents || Support.prefixedPointerEvents) {\n var ws = $wrapperEl[0].style;\n ws.perspectiveOrigin = center + \"px 50%\";\n }\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n swiper.slides\n .transition(duration)\n .find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left')\n .transition(duration);\n },\n };\n\n var EffectCoverflow = {\n name: 'effect-coverflow',\n params: {\n coverflowEffect: {\n rotate: 50,\n stretch: 0,\n depth: 100,\n modifier: 1,\n slideShadows: true,\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n coverflowEffect: {\n setTranslate: Coverflow.setTranslate.bind(swiper),\n setTransition: Coverflow.setTransition.bind(swiper),\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n if (swiper.params.effect !== 'coverflow') { return; }\n\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"coverflow\"));\n swiper.classNames.push(((swiper.params.containerModifierClass) + \"3d\"));\n\n swiper.params.watchSlidesProgress = true;\n swiper.originalParams.watchSlidesProgress = true;\n },\n setTranslate: function setTranslate() {\n var swiper = this;\n if (swiper.params.effect !== 'coverflow') { return; }\n swiper.coverflowEffect.setTranslate();\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n if (swiper.params.effect !== 'coverflow') { return; }\n swiper.coverflowEffect.setTransition(duration);\n },\n },\n };\n\n var Thumbs = {\n init: function init() {\n var swiper = this;\n var ref = swiper.params;\n var thumbsParams = ref.thumbs;\n var SwiperClass = swiper.constructor;\n if (thumbsParams.swiper instanceof SwiperClass) {\n swiper.thumbs.swiper = thumbsParams.swiper;\n Utils.extend(swiper.thumbs.swiper.originalParams, {\n watchSlidesProgress: true,\n slideToClickedSlide: false,\n });\n Utils.extend(swiper.thumbs.swiper.params, {\n watchSlidesProgress: true,\n slideToClickedSlide: false,\n });\n } else if (Utils.isObject(thumbsParams.swiper)) {\n swiper.thumbs.swiper = new SwiperClass(Utils.extend({}, thumbsParams.swiper, {\n watchSlidesVisibility: true,\n watchSlidesProgress: true,\n slideToClickedSlide: false,\n }));\n swiper.thumbs.swiperCreated = true;\n }\n swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);\n swiper.thumbs.swiper.on('tap', swiper.thumbs.onThumbClick);\n },\n onThumbClick: function onThumbClick() {\n var swiper = this;\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) { return; }\n var clickedIndex = thumbsSwiper.clickedIndex;\n var clickedSlide = thumbsSwiper.clickedSlide;\n if (clickedSlide && $(clickedSlide).hasClass(swiper.params.thumbs.slideThumbActiveClass)) { return; }\n if (typeof clickedIndex === 'undefined' || clickedIndex === null) { return; }\n var slideToIndex;\n if (thumbsSwiper.params.loop) {\n slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);\n } else {\n slideToIndex = clickedIndex;\n }\n if (swiper.params.loop) {\n var currentIndex = swiper.activeIndex;\n if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {\n swiper.loopFix();\n // eslint-disable-next-line\n swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;\n currentIndex = swiper.activeIndex;\n }\n var prevIndex = swiper.slides.eq(currentIndex).prevAll((\"[data-swiper-slide-index=\\\"\" + slideToIndex + \"\\\"]\")).eq(0).index();\n var nextIndex = swiper.slides.eq(currentIndex).nextAll((\"[data-swiper-slide-index=\\\"\" + slideToIndex + \"\\\"]\")).eq(0).index();\n if (typeof prevIndex === 'undefined') { slideToIndex = nextIndex; }\n else if (typeof nextIndex === 'undefined') { slideToIndex = prevIndex; }\n else if (nextIndex - currentIndex < currentIndex - prevIndex) { slideToIndex = nextIndex; }\n else { slideToIndex = prevIndex; }\n }\n swiper.slideTo(slideToIndex);\n },\n update: function update(initial) {\n var swiper = this;\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) { return; }\n\n var slidesPerView = thumbsSwiper.params.slidesPerView === 'auto'\n ? thumbsSwiper.slidesPerViewDynamic()\n : thumbsSwiper.params.slidesPerView;\n\n if (swiper.realIndex !== thumbsSwiper.realIndex) {\n var currentThumbsIndex = thumbsSwiper.activeIndex;\n var newThumbsIndex;\n if (thumbsSwiper.params.loop) {\n if (thumbsSwiper.slides.eq(currentThumbsIndex).hasClass(thumbsSwiper.params.slideDuplicateClass)) {\n thumbsSwiper.loopFix();\n // eslint-disable-next-line\n thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;\n currentThumbsIndex = thumbsSwiper.activeIndex;\n }\n // Find actual thumbs index to slide to\n var prevThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).prevAll((\"[data-swiper-slide-index=\\\"\" + (swiper.realIndex) + \"\\\"]\")).eq(0).index();\n var nextThumbsIndex = thumbsSwiper.slides.eq(currentThumbsIndex).nextAll((\"[data-swiper-slide-index=\\\"\" + (swiper.realIndex) + \"\\\"]\")).eq(0).index();\n if (typeof prevThumbsIndex === 'undefined') { newThumbsIndex = nextThumbsIndex; }\n else if (typeof nextThumbsIndex === 'undefined') { newThumbsIndex = prevThumbsIndex; }\n else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) { newThumbsIndex = currentThumbsIndex; }\n else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) { newThumbsIndex = nextThumbsIndex; }\n else { newThumbsIndex = prevThumbsIndex; }\n } else {\n newThumbsIndex = swiper.realIndex;\n }\n if (thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0) {\n if (thumbsSwiper.params.centeredSlides) {\n if (newThumbsIndex > currentThumbsIndex) {\n newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;\n } else {\n newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;\n }\n } else if (newThumbsIndex > currentThumbsIndex) {\n newThumbsIndex = newThumbsIndex - slidesPerView + 1;\n }\n thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);\n }\n }\n\n // Activate thumbs\n var thumbsToActivate = 1;\n var thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;\n\n if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {\n thumbsToActivate = swiper.params.slidesPerView;\n }\n\n thumbsSwiper.slides.removeClass(thumbActiveClass);\n if (thumbsSwiper.params.loop) {\n for (var i = 0; i < thumbsToActivate; i += 1) {\n thumbsSwiper.$wrapperEl.children((\"[data-swiper-slide-index=\\\"\" + (swiper.realIndex + i) + \"\\\"]\")).addClass(thumbActiveClass);\n }\n } else {\n for (var i$1 = 0; i$1 < thumbsToActivate; i$1 += 1) {\n thumbsSwiper.slides.eq(swiper.realIndex + i$1).addClass(thumbActiveClass);\n }\n }\n },\n };\n var Thumbs$1 = {\n name: 'thumbs',\n params: {\n thumbs: {\n swiper: null,\n slideThumbActiveClass: 'swiper-slide-thumb-active',\n thumbsContainerClass: 'swiper-container-thumbs',\n },\n },\n create: function create() {\n var swiper = this;\n Utils.extend(swiper, {\n thumbs: {\n swiper: null,\n init: Thumbs.init.bind(swiper),\n update: Thumbs.update.bind(swiper),\n onThumbClick: Thumbs.onThumbClick.bind(swiper),\n },\n });\n },\n on: {\n beforeInit: function beforeInit() {\n var swiper = this;\n var ref = swiper.params;\n var thumbs = ref.thumbs;\n if (!thumbs || !thumbs.swiper) { return; }\n swiper.thumbs.init();\n swiper.thumbs.update(true);\n },\n slideChange: function slideChange() {\n var swiper = this;\n if (!swiper.thumbs.swiper) { return; }\n swiper.thumbs.update();\n },\n update: function update() {\n var swiper = this;\n if (!swiper.thumbs.swiper) { return; }\n swiper.thumbs.update();\n },\n resize: function resize() {\n var swiper = this;\n if (!swiper.thumbs.swiper) { return; }\n swiper.thumbs.update();\n },\n observerUpdate: function observerUpdate() {\n var swiper = this;\n if (!swiper.thumbs.swiper) { return; }\n swiper.thumbs.update();\n },\n setTransition: function setTransition(duration) {\n var swiper = this;\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) { return; }\n thumbsSwiper.setTransition(duration);\n },\n beforeDestroy: function beforeDestroy() {\n var swiper = this;\n var thumbsSwiper = swiper.thumbs.swiper;\n if (!thumbsSwiper) { return; }\n if (swiper.thumbs.swiperCreated && thumbsSwiper) {\n thumbsSwiper.destroy();\n }\n },\n },\n };\n\n // Swiper Class\n\n var components = [\n Device$1,\n Support$1,\n Browser$1,\n Resize,\n Observer$1,\n Virtual$1,\n Keyboard$1,\n Mousewheel$1,\n Navigation$1,\n Pagination$1,\n Scrollbar$1,\n Parallax$1,\n Zoom$1,\n Lazy$1,\n Controller$1,\n A11y,\n History$1,\n HashNavigation$1,\n Autoplay$1,\n EffectFade,\n EffectCube,\n EffectFlip,\n EffectCoverflow,\n Thumbs$1\n ];\n\n if (typeof Swiper.use === 'undefined') {\n Swiper.use = Swiper.Class.use;\n Swiper.installModule = Swiper.Class.installModule;\n }\n\n Swiper.use(components);\n\n return Swiper;\n\n}));\n"]} \ No newline at end of file diff --git a/assets/3rd/toast/jquery.toast.js b/assets/3rd/toast/jquery.toast.js new file mode 100755 index 00000000..77cdf45c --- /dev/null +++ b/assets/3rd/toast/jquery.toast.js @@ -0,0 +1,359 @@ +// jQuery toast plugin created by Kamran Ahmed copyright MIT license 2015 +if ( typeof Object.create !== 'function' ) { + Object.create = function( obj ) { + function F() {} + F.prototype = obj; + return new F(); + }; +} + +(function( $, window, document, undefined ) { + + "use strict"; + + var Toast = { + + _positionClasses : ['bottom-left', 'bottom-right', 'top-right', 'top-left', 'bottom-center', 'top-center', 'mid-center'], + _defaultIcons : ['success', 'error', 'info', 'warning'], + + init: function (options, elem) { + this.prepareOptions(options, $.toast.options); + this.process(); + }, + + prepareOptions: function(options, options_to_extend) { + var _options = {}; + if ( ( typeof options === 'string' ) || ( options instanceof Array ) ) { + _options.text = options; + } else { + _options = options; + } + this.options = $.extend( {}, options_to_extend, _options ); + }, + + process: function () { + this.setup(); + this.addToDom(); + this.position(); + this.bindToast(); + this.animate(); + }, + + setup: function () { + + var _toastContent = ''; + + this._toastEl = this._toastEl || $('
            ', { + class : 'jq-toast-single' + }); + + // For the loader on top + _toastContent += ''; + + if ( this.options.allowToastClose ) { + _toastContent += '×'; + }; + + if ( this.options.text instanceof Array ) { + + if ( this.options.heading ) { + _toastContent +='

            ' + this.options.heading + '

            '; + }; + + _toastContent += '
              '; + for (var i = 0; i < this.options.text.length; i++) { + _toastContent += '
            • ' + this.options.text[i] + '
            • '; + } + _toastContent += '
            '; + + } else { + if ( this.options.heading ) { + _toastContent +='

            ' + this.options.heading + '

            '; + }; + _toastContent += this.options.text; + } + + this._toastEl.html( _toastContent ); + + if ( this.options.bgColor !== false ) { + this._toastEl.css("background-color", this.options.bgColor); + }; + + if ( this.options.textColor !== false ) { + this._toastEl.css("color", this.options.textColor); + }; + + if ( this.options.textAlign ) { + this._toastEl.css('text-align', this.options.textAlign); + } + + if ( this.options.icon !== false ) { + this._toastEl.addClass('jq-has-icon'); + + if ( $.inArray(this.options.icon, this._defaultIcons) !== -1 ) { + this._toastEl.addClass('jq-icon-' + this.options.icon); + }; + }; + + if ( this.options.class !== false ){ + this._toastEl.addClass(this.options.class) + } + }, + + position: function () { + if ( ( typeof this.options.position === 'string' ) && ( $.inArray( this.options.position, this._positionClasses) !== -1 ) ) { + + if ( this.options.position === 'bottom-center' ) { + this._container.css({ + left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2, + bottom: 20 + }); + } else if ( this.options.position === 'top-center' ) { + this._container.css({ + left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2, + top: 20 + }); + } else if ( this.options.position === 'mid-center' ) { + this._container.css({ + left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2, + top: ( $(window).outerHeight() / 2 ) - this._container.outerHeight()/2 + }); + } else { + this._container.addClass( this.options.position ); + } + + } else if ( typeof this.options.position === 'object' ) { + this._container.css({ + top : this.options.position.top ? this.options.position.top : 'auto', + bottom : this.options.position.bottom ? this.options.position.bottom : 'auto', + left : this.options.position.left ? this.options.position.left : 'auto', + right : this.options.position.right ? this.options.position.right : 'auto' + }); + } else { + this._container.addClass( 'bottom-left' ); + } + }, + + bindToast: function () { + + var that = this; + + this._toastEl.on('afterShown', function () { + that.processLoader(); + }); + + this._toastEl.find('.close-jq-toast-single').on('click', function ( e ) { + + e.preventDefault(); + + if( that.options.showHideTransition === 'fade') { + that._toastEl.trigger('beforeHide'); + that._toastEl.fadeOut(function () { + that._toastEl.trigger('afterHidden'); + }); + } else if ( that.options.showHideTransition === 'slide' ) { + that._toastEl.trigger('beforeHide'); + that._toastEl.slideUp(function () { + that._toastEl.trigger('afterHidden'); + }); + } else { + that._toastEl.trigger('beforeHide'); + that._toastEl.hide(function () { + that._toastEl.trigger('afterHidden'); + }); + } + }); + + if ( typeof this.options.beforeShow == 'function' ) { + this._toastEl.on('beforeShow', function () { + that.options.beforeShow(); + }); + }; + + if ( typeof this.options.afterShown == 'function' ) { + this._toastEl.on('afterShown', function () { + that.options.afterShown(); + }); + }; + + if ( typeof this.options.beforeHide == 'function' ) { + this._toastEl.on('beforeHide', function () { + that.options.beforeHide(); + }); + }; + + if ( typeof this.options.afterHidden == 'function' ) { + this._toastEl.on('afterHidden', function () { + that.options.afterHidden(); + }); + }; + }, + + addToDom: function () { + + var _container = $('.jq-toast-wrap'); + + if ( _container.length === 0 ) { + + _container = $('
            ',{ + class: "jq-toast-wrap", + role: "alert", + "aria-live": "polite" + }); + + $('body').append( _container ); + + } else if ( !this.options.stack || isNaN( parseInt(this.options.stack, 10) ) ) { + _container.empty(); + } + + _container.find('.jq-toast-single:hidden').remove(); + + _container.append( this._toastEl ); + + if ( this.options.stack && !isNaN( parseInt( this.options.stack ), 10 ) ) { + + var _prevToastCount = _container.find('.jq-toast-single').length, + _extToastCount = _prevToastCount - this.options.stack; + + if ( _extToastCount > 0 ) { + $('.jq-toast-wrap').find('.jq-toast-single').slice(0, _extToastCount).remove(); + }; + + } + + this._container = _container; + }, + + canAutoHide: function () { + return ( this.options.hideAfter !== false ) && !isNaN( parseInt( this.options.hideAfter, 10 ) ); + }, + + processLoader: function () { + // Show the loader only, if auto-hide is on and loader is demanded + if (!this.canAutoHide() || this.options.loader === false) { + return false; + } + + var loader = this._toastEl.find('.jq-toast-loader'); + + // 400 is the default time that jquery uses for fade/slide + // Divide by 1000 for milliseconds to seconds conversion + var transitionTime = (this.options.hideAfter - 400) / 1000 + 's'; + var loaderBg = this.options.loaderBg; + + var style = loader.attr('style') || ''; + style = style.substring(0, style.indexOf('-webkit-transition')); // Remove the last transition definition + + style += '-webkit-transition: width ' + transitionTime + ' ease-in; \ + -o-transition: width ' + transitionTime + ' ease-in; \ + transition: width ' + transitionTime + ' ease-in; \ + background-color: ' + loaderBg + ';'; + + + loader.attr('style', style).addClass('jq-toast-loaded'); + }, + + animate: function () { + + var that = this; + + this._toastEl.hide(); + + this._toastEl.trigger('beforeShow'); + + if ( this.options.showHideTransition.toLowerCase() === 'fade' ) { + this._toastEl.fadeIn(function ( ){ + that._toastEl.trigger('afterShown'); + }); + } else if ( this.options.showHideTransition.toLowerCase() === 'slide' ) { + this._toastEl.slideDown(function ( ){ + that._toastEl.trigger('afterShown'); + }); + } else { + this._toastEl.show(function ( ){ + that._toastEl.trigger('afterShown'); + }); + } + + if (this.canAutoHide()) { + + var that = this; + + window.setTimeout(function(){ + + if ( that.options.showHideTransition.toLowerCase() === 'fade' ) { + that._toastEl.trigger('beforeHide'); + that._toastEl.fadeOut(function () { + that._toastEl.trigger('afterHidden'); + }); + } else if ( that.options.showHideTransition.toLowerCase() === 'slide' ) { + that._toastEl.trigger('beforeHide'); + that._toastEl.slideUp(function () { + that._toastEl.trigger('afterHidden'); + }); + } else { + that._toastEl.trigger('beforeHide'); + that._toastEl.hide(function () { + that._toastEl.trigger('afterHidden'); + }); + } + + }, this.options.hideAfter); + }; + }, + + reset: function ( resetWhat ) { + + if ( resetWhat === 'all' ) { + $('.jq-toast-wrap').remove(); + } else { + this._toastEl.remove(); + } + + }, + + update: function(options) { + this.prepareOptions(options, this.options); + this.setup(); + this.bindToast(); + } + }; + + $.toast = function(options) { + var toast = Object.create(Toast); + toast.init(options, this); + + return { + + reset: function ( what ) { + toast.reset( what ); + }, + + update: function( options ) { + toast.update( options ); + } + } + }; + + $.toast.options = { + text: '', + heading: '', + showHideTransition: 'fade', + allowToastClose: true, + hideAfter: 3000, + loader: true, + loaderBg: '#9EC600', + stack: 5, + position: 'bottom-left', + bgColor: false, + textColor: false, + textAlign: 'left', + icon: false, + beforeShow: function () {}, + afterShown: function () {}, + beforeHide: function () {}, + afterHidden: function () {} + }; + +})( jQuery, window, document ); diff --git a/assets/3rd/tooltipster/css/tooltipster.bundle.min.css b/assets/3rd/tooltipster/css/tooltipster.bundle.min.css new file mode 100755 index 00000000..d8f30fee --- /dev/null +++ b/assets/3rd/tooltipster/css/tooltipster.bundle.min.css @@ -0,0 +1 @@ +.tooltipster-fall,.tooltipster-grow.tooltipster-show{-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1);-moz-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-ms-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-o-transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-base{display:flex;pointer-events:none;position:absolute}.tooltipster-box{flex:1 1 auto}.tooltipster-content{box-sizing:border-box;max-height:100%;max-width:100%;overflow:auto}.tooltipster-ruler{bottom:0;left:0;overflow:hidden;position:fixed;right:0;top:0;visibility:hidden}.tooltipster-fade{opacity:0;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;-ms-transition-property:opacity;transition-property:opacity}.tooltipster-fade.tooltipster-show{opacity:1}.tooltipster-grow{-webkit-transform:scale(0,0);-moz-transform:scale(0,0);-o-transform:scale(0,0);-ms-transform:scale(0,0);transform:scale(0,0);-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-backface-visibility:hidden}.tooltipster-grow.tooltipster-show{-webkit-transform:scale(1,1);-moz-transform:scale(1,1);-o-transform:scale(1,1);-ms-transform:scale(1,1);transform:scale(1,1);-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-swing{opacity:0;-webkit-transform:rotateZ(4deg);-moz-transform:rotateZ(4deg);-o-transform:rotateZ(4deg);-ms-transform:rotateZ(4deg);transform:rotateZ(4deg);-webkit-transition-property:-webkit-transform,opacity;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform}.tooltipster-swing.tooltipster-show{opacity:1;-webkit-transform:rotateZ(0);-moz-transform:rotateZ(0);-o-transform:rotateZ(0);-ms-transform:rotateZ(0);transform:rotateZ(0);-webkit-transition-timing-function:cubic-bezier(.23,.635,.495,1);-webkit-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-moz-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-ms-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);-o-transition-timing-function:cubic-bezier(.23,.635,.495,2.4);transition-timing-function:cubic-bezier(.23,.635,.495,2.4)}.tooltipster-fall{-webkit-transition-property:top;-moz-transition-property:top;-o-transition-property:top;-ms-transition-property:top;transition-property:top;-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-fall.tooltipster-initial{top:0!important}.tooltipster-fall.tooltipster-dying{-webkit-transition-property:all;-moz-transition-property:all;-o-transition-property:all;-ms-transition-property:all;transition-property:all;top:0!important;opacity:0}.tooltipster-slide{-webkit-transition-property:left;-moz-transition-property:left;-o-transition-property:left;-ms-transition-property:left;transition-property:left;-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1);-webkit-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-moz-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-ms-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);-o-transition-timing-function:cubic-bezier(.175,.885,.32,1.15);transition-timing-function:cubic-bezier(.175,.885,.32,1.15)}.tooltipster-slide.tooltipster-initial{left:-40px!important}.tooltipster-slide.tooltipster-dying{-webkit-transition-property:all;-moz-transition-property:all;-o-transition-property:all;-ms-transition-property:all;transition-property:all;left:0!important;opacity:0}@keyframes tooltipster-fading{0%{opacity:0}100%{opacity:1}}.tooltipster-update-fade{animation:tooltipster-fading .4s}@keyframes tooltipster-rotating{25%{transform:rotate(-2deg)}75%{transform:rotate(2deg)}100%{transform:rotate(0)}}.tooltipster-update-rotate{animation:tooltipster-rotating .6s}@keyframes tooltipster-scaling{50%{transform:scale(1.1)}100%{transform:scale(1)}}.tooltipster-update-scale{animation:tooltipster-scaling .6s}.tooltipster-sidetip .tooltipster-box{background:#565656;border:2px solid #000;border-radius:4px}.tooltipster-sidetip.tooltipster-bottom .tooltipster-box{margin-top:8px}.tooltipster-sidetip.tooltipster-left .tooltipster-box{margin-right:8px}.tooltipster-sidetip.tooltipster-right .tooltipster-box{margin-left:8px}.tooltipster-sidetip.tooltipster-top .tooltipster-box{margin-bottom:8px}.tooltipster-sidetip .tooltipster-content{color:#fff;line-height:18px;padding:6px 14px}.tooltipster-sidetip .tooltipster-arrow{overflow:hidden;position:absolute}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow{height:10px;margin-left:-10px;top:0;width:20px}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow{height:20px;margin-top:-10px;right:0;top:0;width:10px}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow{height:20px;margin-top:-10px;left:0;top:0;width:10px}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow{bottom:0;height:10px;margin-left:-10px;width:20px}.tooltipster-sidetip .tooltipster-arrow-background,.tooltipster-sidetip .tooltipster-arrow-border{height:0;position:absolute;width:0}.tooltipster-sidetip .tooltipster-arrow-background{border:10px solid transparent}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-background{border-bottom-color:#565656;left:0;top:3px}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-background{border-left-color:#565656;left:-3px;top:0}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-background{border-right-color:#565656;left:3px;top:0}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-background{border-top-color:#565656;left:0;top:-3px}.tooltipster-sidetip .tooltipster-arrow-border{border:10px solid transparent;left:0;top:0}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#000}.tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border{border-left-color:#000}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border{border-right-color:#000}.tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border{border-top-color:#000}.tooltipster-sidetip .tooltipster-arrow-uncropped{position:relative}.tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped{top:-10px}.tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped{left:-10px} \ No newline at end of file diff --git a/assets/3rd/tooltipster/js/tooltipster.bundle.min.js b/assets/3rd/tooltipster/js/tooltipster.bundle.min.js new file mode 100755 index 00000000..0289853f --- /dev/null +++ b/assets/3rd/tooltipster/js/tooltipster.bundle.min.js @@ -0,0 +1,2 @@ +/*! tooltipster v4.2.6 */!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){function b(a){this.$container,this.constraints=null,this.__$tooltip,this.__init(a)}function c(b,c){var d=!0;return a.each(b,function(a,e){return void 0===c[a]||b[a]!==c[a]?(d=!1,!1):void 0}),d}function d(b){var c=b.attr("id"),d=c?h.window.document.getElementById(c):null;return d?d===b[0]:a.contains(h.window.document.body,b[0])}function e(){if(!g)return!1;var a=g.document.body||g.document.documentElement,b=a.style,c="transition",d=["Moz","Webkit","Khtml","O","ms"];if("string"==typeof b[c])return!0;c=c.charAt(0).toUpperCase()+c.substr(1);for(var e=0;e0?e=c.__plugins[d]:a.each(c.__plugins,function(a,b){return b.name.substring(b.name.length-d.length-1)=="."+d?(e=b,!1):void 0}),e}if(b.name.indexOf(".")<0)throw new Error("Plugins must be namespaced");return c.__plugins[b.name]=b,b.core&&c.__bridge(b.core,c,b.name),this},_trigger:function(){var a=Array.prototype.slice.apply(arguments);return"string"==typeof a[0]&&(a[0]={type:a[0]}),this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,a),this.__$emitterPublic.trigger.apply(this.__$emitterPublic,a),this},instances:function(b){var c=[],d=b||".tooltipstered";return a(d).each(function(){var b=a(this),d=b.data("tooltipster-ns");d&&a.each(d,function(a,d){c.push(b.data(d))})}),c},instancesLatest:function(){return this.__instancesLatestArr},off:function(){return this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},on:function(){return this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},one:function(){return this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},origins:function(b){var c=b?b+" ":"";return a(c+".tooltipstered").toArray()},setDefaults:function(b){return a.extend(f,b),this},triggerHandler:function(){return this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this}},a.tooltipster=new i,a.Tooltipster=function(b,c){this.__callbacks={close:[],open:[]},this.__closingTime,this.__Content,this.__contentBcr,this.__destroyed=!1,this.__$emitterPrivate=a({}),this.__$emitterPublic=a({}),this.__enabled=!0,this.__garbageCollector,this.__Geometry,this.__lastPosition,this.__namespace="tooltipster-"+Math.round(1e6*Math.random()),this.__options,this.__$originParents,this.__pointerIsOverOrigin=!1,this.__previousThemes=[],this.__state="closed",this.__timeouts={close:[],open:null},this.__touchEvents=[],this.__tracker=null,this._$origin,this._$tooltip,this.__init(b,c)},a.Tooltipster.prototype={__init:function(b,c){var d=this;if(d._$origin=a(b),d.__options=a.extend(!0,{},f,c),d.__optionsFormat(),!h.IE||h.IE>=d.__options.IEmin){var e=null;if(void 0===d._$origin.data("tooltipster-initialTitle")&&(e=d._$origin.attr("title"),void 0===e&&(e=null),d._$origin.data("tooltipster-initialTitle",e)),null!==d.__options.content)d.__contentSet(d.__options.content);else{var g,i=d._$origin.attr("data-tooltip-content");i&&(g=a(i)),g&&g[0]?d.__contentSet(g.first()):d.__contentSet(e)}d._$origin.removeAttr("title").addClass("tooltipstered"),d.__prepareOrigin(),d.__prepareGC(),a.each(d.__options.plugins,function(a,b){d._plug(b)}),h.hasTouchCapability&&a(h.window.document.body).on("touchmove."+d.__namespace+"-triggerOpen",function(a){d._touchRecordEvent(a)}),d._on("created",function(){d.__prepareTooltip()})._on("repositioned",function(a){d.__lastPosition=a.position})}else d.__options.disabled=!0},__contentInsert:function(){var a=this,b=a._$tooltip.find(".tooltipster-content"),c=a.__Content,d=function(a){c=a};return a._trigger({type:"format",content:a.__Content,format:d}),a.__options.functionFormat&&(c=a.__options.functionFormat.call(a,a,{origin:a._$origin[0]},a.__Content)),"string"!=typeof c||a.__options.contentAsHTML?b.empty().append(c):b.text(c),a},__contentSet:function(b){return b instanceof a&&this.__options.contentCloning&&(b=b.clone(!0)),this.__Content=b,this._trigger({type:"updated",content:b}),this},__destroyError:function(){throw new Error("This tooltip has been destroyed and cannot execute your method call.")},__geometry:function(){var b=this,c=b._$origin,d=b._$origin.is("area");if(d){var e=b._$origin.parent().attr("name");c=a('img[usemap="#'+e+'"]')}var f=c[0].getBoundingClientRect(),g=a(h.window.document),i=a(h.window),j=c,k={available:{document:null,window:null},document:{size:{height:g.height(),width:g.width()}},window:{scroll:{left:h.window.scrollX||h.window.document.documentElement.scrollLeft,top:h.window.scrollY||h.window.document.documentElement.scrollTop},size:{height:i.height(),width:i.width()}},origin:{fixedLineage:!1,offset:{},size:{height:f.bottom-f.top,width:f.right-f.left},usemapImage:d?c[0]:null,windowOffset:{bottom:f.bottom,left:f.left,right:f.right,top:f.top}}};if(d){var l=b._$origin.attr("shape"),m=b._$origin.attr("coords");if(m&&(m=m.split(","),a.map(m,function(a,b){m[b]=parseInt(a)})),"default"!=l)switch(l){case"circle":var n=m[0],o=m[1],p=m[2],q=o-p,r=n-p;k.origin.size.height=2*p,k.origin.size.width=k.origin.size.height,k.origin.windowOffset.left+=r,k.origin.windowOffset.top+=q;break;case"rect":var s=m[0],t=m[1],u=m[2],v=m[3];k.origin.size.height=v-t,k.origin.size.width=u-s,k.origin.windowOffset.left+=s,k.origin.windowOffset.top+=t;break;case"poly":for(var w=0,x=0,y=0,z=0,A="even",B=0;By&&(y=C,0===B&&(w=y)),w>C&&(w=C),A="odd"):(C>z&&(z=C,1==B&&(x=z)),x>C&&(x=C),A="even")}k.origin.size.height=z-x,k.origin.size.width=y-w,k.origin.windowOffset.left+=w,k.origin.windowOffset.top+=x}}var D=function(a){k.origin.size.height=a.height,k.origin.windowOffset.left=a.left,k.origin.windowOffset.top=a.top,k.origin.size.width=a.width};for(b._trigger({type:"geometry",edit:D,geometry:{height:k.origin.size.height,left:k.origin.windowOffset.left,top:k.origin.windowOffset.top,width:k.origin.size.width}}),k.origin.windowOffset.right=k.origin.windowOffset.left+k.origin.size.width,k.origin.windowOffset.bottom=k.origin.windowOffset.top+k.origin.size.height,k.origin.offset.left=k.origin.windowOffset.left+k.window.scroll.left,k.origin.offset.top=k.origin.windowOffset.top+k.window.scroll.top,k.origin.offset.bottom=k.origin.offset.top+k.origin.size.height,k.origin.offset.right=k.origin.offset.left+k.origin.size.width,k.available.document={bottom:{height:k.document.size.height-k.origin.offset.bottom,width:k.document.size.width},left:{height:k.document.size.height,width:k.origin.offset.left},right:{height:k.document.size.height,width:k.document.size.width-k.origin.offset.right},top:{height:k.origin.offset.top,width:k.document.size.width}},k.available.window={bottom:{height:Math.max(k.window.size.height-Math.max(k.origin.windowOffset.bottom,0),0),width:k.window.size.width},left:{height:k.window.size.height,width:Math.max(k.origin.windowOffset.left,0)},right:{height:k.window.size.height,width:Math.max(k.window.size.width-Math.max(k.origin.windowOffset.right,0),0)},top:{height:Math.max(k.origin.windowOffset.top,0),width:k.window.size.width}};"html"!=j[0].tagName.toLowerCase();){if("fixed"==j.css("position")){k.origin.fixedLineage=!0;break}j=j.parent()}return k},__optionsFormat:function(){return"number"==typeof this.__options.animationDuration&&(this.__options.animationDuration=[this.__options.animationDuration,this.__options.animationDuration]),"number"==typeof this.__options.delay&&(this.__options.delay=[this.__options.delay,this.__options.delay]),"number"==typeof this.__options.delayTouch&&(this.__options.delayTouch=[this.__options.delayTouch,this.__options.delayTouch]),"string"==typeof this.__options.theme&&(this.__options.theme=[this.__options.theme]),null===this.__options.parent?this.__options.parent=a(h.window.document.body):"string"==typeof this.__options.parent&&(this.__options.parent=a(this.__options.parent)),"hover"==this.__options.trigger?(this.__options.triggerOpen={mouseenter:!0,touchstart:!0},this.__options.triggerClose={mouseleave:!0,originClick:!0,touchleave:!0}):"click"==this.__options.trigger&&(this.__options.triggerOpen={click:!0,tap:!0},this.__options.triggerClose={click:!0,tap:!0}),this._trigger("options"),this},__prepareGC:function(){var b=this;return b.__options.selfDestruction?b.__garbageCollector=setInterval(function(){var c=(new Date).getTime();b.__touchEvents=a.grep(b.__touchEvents,function(a,b){return c-a.time>6e4}),d(b._$origin)||b.close(function(){b.destroy()})},2e4):clearInterval(b.__garbageCollector),b},__prepareOrigin:function(){var a=this;if(a._$origin.off("."+a.__namespace+"-triggerOpen"),h.hasTouchCapability&&a._$origin.on("touchstart."+a.__namespace+"-triggerOpen touchend."+a.__namespace+"-triggerOpen touchcancel."+a.__namespace+"-triggerOpen",function(b){a._touchRecordEvent(b)}),a.__options.triggerOpen.click||a.__options.triggerOpen.tap&&h.hasTouchCapability){var b="";a.__options.triggerOpen.click&&(b+="click."+a.__namespace+"-triggerOpen "),a.__options.triggerOpen.tap&&h.hasTouchCapability&&(b+="touchend."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){a._touchIsMeaningfulEvent(b)&&a._open(b)})}if(a.__options.triggerOpen.mouseenter||a.__options.triggerOpen.touchstart&&h.hasTouchCapability){var b="";a.__options.triggerOpen.mouseenter&&(b+="mouseenter."+a.__namespace+"-triggerOpen "),a.__options.triggerOpen.touchstart&&h.hasTouchCapability&&(b+="touchstart."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){!a._touchIsTouchEvent(b)&&a._touchIsEmulatedEvent(b)||(a.__pointerIsOverOrigin=!0,a._openShortly(b))})}if(a.__options.triggerClose.mouseleave||a.__options.triggerClose.touchleave&&h.hasTouchCapability){var b="";a.__options.triggerClose.mouseleave&&(b+="mouseleave."+a.__namespace+"-triggerOpen "),a.__options.triggerClose.touchleave&&h.hasTouchCapability&&(b+="touchend."+a.__namespace+"-triggerOpen touchcancel."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){a._touchIsMeaningfulEvent(b)&&(a.__pointerIsOverOrigin=!1)})}return a},__prepareTooltip:function(){var b=this,c=b.__options.interactive?"auto":"";return b._$tooltip.attr("id",b.__namespace).css({"pointer-events":c,zIndex:b.__options.zIndex}),a.each(b.__previousThemes,function(a,c){b._$tooltip.removeClass(c)}),a.each(b.__options.theme,function(a,c){b._$tooltip.addClass(c)}),b.__previousThemes=a.merge([],b.__options.theme),b},__scrollHandler:function(b){var c=this;if(c.__options.triggerClose.scroll)c._close(b);else if(d(c._$origin)&&d(c._$tooltip)){var e=null;if(b.target===h.window.document)c.__Geometry.origin.fixedLineage||c.__options.repositionOnScroll&&c.reposition(b);else{e=c.__geometry();var f=!1;if("fixed"!=c._$origin.css("position")&&c.__$originParents.each(function(b,c){var d=a(c),g=d.css("overflow-x"),h=d.css("overflow-y");if("visible"!=g||"visible"!=h){var i=c.getBoundingClientRect();if("visible"!=g&&(e.origin.windowOffset.lefti.right))return f=!0,!1;if("visible"!=h&&(e.origin.windowOffset.topi.bottom))return f=!0,!1}return"fixed"==d.css("position")?!1:void 0}),f)c._$tooltip.css("visibility","hidden");else if(c._$tooltip.css("visibility","visible"),c.__options.repositionOnScroll)c.reposition(b);else{var g=e.origin.offset.left-c.__Geometry.origin.offset.left,i=e.origin.offset.top-c.__Geometry.origin.offset.top;c._$tooltip.css({left:c.__lastPosition.coord.left+g,top:c.__lastPosition.coord.top+i})}}c._trigger({type:"scroll",event:b,geo:e})}return c},__stateSet:function(a){return this.__state=a,this._trigger({type:"state",state:a}),this},__timeoutsClear:function(){return clearTimeout(this.__timeouts.open),this.__timeouts.open=null,a.each(this.__timeouts.close,function(a,b){clearTimeout(b)}),this.__timeouts.close=[],this},__trackerStart:function(){var a=this,b=a._$tooltip.find(".tooltipster-content");return a.__options.trackTooltip&&(a.__contentBcr=b[0].getBoundingClientRect()),a.__tracker=setInterval(function(){if(d(a._$origin)&&d(a._$tooltip)){if(a.__options.trackOrigin){var e=a.__geometry(),f=!1;c(e.origin.size,a.__Geometry.origin.size)&&(a.__Geometry.origin.fixedLineage?c(e.origin.windowOffset,a.__Geometry.origin.windowOffset)&&(f=!0):c(e.origin.offset,a.__Geometry.origin.offset)&&(f=!0)),f||(a.__options.triggerClose.mouseleave?a._close():a.reposition())}if(a.__options.trackTooltip){var g=b[0].getBoundingClientRect();g.height===a.__contentBcr.height&&g.width===a.__contentBcr.width||(a.reposition(),a.__contentBcr=g)}}else a._close()},a.__options.trackerInterval),a},_close:function(b,c,d){var e=this,f=!0;if(e._trigger({type:"close",event:b,stop:function(){f=!1}}),f||d){c&&e.__callbacks.close.push(c),e.__callbacks.open=[],e.__timeoutsClear();var g=function(){a.each(e.__callbacks.close,function(a,c){c.call(e,e,{event:b,origin:e._$origin[0]})}),e.__callbacks.close=[]};if("closed"!=e.__state){var i=!0,j=new Date,k=j.getTime(),l=k+e.__options.animationDuration[1];if("disappearing"==e.__state&&l>e.__closingTime&&e.__options.animationDuration[1]>0&&(i=!1),i){e.__closingTime=l,"disappearing"!=e.__state&&e.__stateSet("disappearing");var m=function(){clearInterval(e.__tracker),e._trigger({type:"closing",event:b}),e._$tooltip.off("."+e.__namespace+"-triggerClose").removeClass("tooltipster-dying"),a(h.window).off("."+e.__namespace+"-triggerClose"),e.__$originParents.each(function(b,c){a(c).off("scroll."+e.__namespace+"-triggerClose")}),e.__$originParents=null,a(h.window.document.body).off("."+e.__namespace+"-triggerClose"),e._$origin.off("."+e.__namespace+"-triggerClose"),e._off("dismissable"),e.__stateSet("closed"),e._trigger({type:"after",event:b}),e.__options.functionAfter&&e.__options.functionAfter.call(e,e,{event:b,origin:e._$origin[0]}),g()};h.hasTransitions?(e._$tooltip.css({"-moz-animation-duration":e.__options.animationDuration[1]+"ms","-ms-animation-duration":e.__options.animationDuration[1]+"ms","-o-animation-duration":e.__options.animationDuration[1]+"ms","-webkit-animation-duration":e.__options.animationDuration[1]+"ms","animation-duration":e.__options.animationDuration[1]+"ms","transition-duration":e.__options.animationDuration[1]+"ms"}),e._$tooltip.clearQueue().removeClass("tooltipster-show").addClass("tooltipster-dying"),e.__options.animationDuration[1]>0&&e._$tooltip.delay(e.__options.animationDuration[1]),e._$tooltip.queue(m)):e._$tooltip.stop().fadeOut(e.__options.animationDuration[1],m)}}else g()}return e},_off:function(){return this.__$emitterPrivate.off.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_on:function(){return this.__$emitterPrivate.on.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_one:function(){return this.__$emitterPrivate.one.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_open:function(b,c){var e=this;if(!e.__destroying&&d(e._$origin)&&e.__enabled){var f=!0;if("closed"==e.__state&&(e._trigger({type:"before",event:b,stop:function(){f=!1}}),f&&e.__options.functionBefore&&(f=e.__options.functionBefore.call(e,e,{event:b,origin:e._$origin[0]}))),f!==!1&&null!==e.__Content){c&&e.__callbacks.open.push(c),e.__callbacks.close=[],e.__timeoutsClear();var g,i=function(){"stable"!=e.__state&&e.__stateSet("stable"),a.each(e.__callbacks.open,function(a,b){b.call(e,e,{origin:e._$origin[0],tooltip:e._$tooltip[0]})}),e.__callbacks.open=[]};if("closed"!==e.__state)g=0,"disappearing"===e.__state?(e.__stateSet("appearing"),h.hasTransitions?(e._$tooltip.clearQueue().removeClass("tooltipster-dying").addClass("tooltipster-show"),e.__options.animationDuration[0]>0&&e._$tooltip.delay(e.__options.animationDuration[0]),e._$tooltip.queue(i)):e._$tooltip.stop().fadeIn(i)):"stable"==e.__state&&i();else{if(e.__stateSet("appearing"),g=e.__options.animationDuration[0],e.__contentInsert(),e.reposition(b,!0),h.hasTransitions?(e._$tooltip.addClass("tooltipster-"+e.__options.animation).addClass("tooltipster-initial").css({"-moz-animation-duration":e.__options.animationDuration[0]+"ms","-ms-animation-duration":e.__options.animationDuration[0]+"ms","-o-animation-duration":e.__options.animationDuration[0]+"ms","-webkit-animation-duration":e.__options.animationDuration[0]+"ms","animation-duration":e.__options.animationDuration[0]+"ms","transition-duration":e.__options.animationDuration[0]+"ms"}),setTimeout(function(){"closed"!=e.__state&&(e._$tooltip.addClass("tooltipster-show").removeClass("tooltipster-initial"),e.__options.animationDuration[0]>0&&e._$tooltip.delay(e.__options.animationDuration[0]),e._$tooltip.queue(i))},0)):e._$tooltip.css("display","none").fadeIn(e.__options.animationDuration[0],i),e.__trackerStart(),a(h.window).on("resize."+e.__namespace+"-triggerClose",function(b){var c=a(document.activeElement);(c.is("input")||c.is("textarea"))&&a.contains(e._$tooltip[0],c[0])||e.reposition(b)}).on("scroll."+e.__namespace+"-triggerClose",function(a){e.__scrollHandler(a)}),e.__$originParents=e._$origin.parents(),e.__$originParents.each(function(b,c){a(c).on("scroll."+e.__namespace+"-triggerClose",function(a){e.__scrollHandler(a)})}),e.__options.triggerClose.mouseleave||e.__options.triggerClose.touchleave&&h.hasTouchCapability){e._on("dismissable",function(a){a.dismissable?a.delay?(m=setTimeout(function(){e._close(a.event)},a.delay),e.__timeouts.close.push(m)):e._close(a):clearTimeout(m)});var j=e._$origin,k="",l="",m=null;e.__options.interactive&&(j=j.add(e._$tooltip)),e.__options.triggerClose.mouseleave&&(k+="mouseenter."+e.__namespace+"-triggerClose ",l+="mouseleave."+e.__namespace+"-triggerClose "),e.__options.triggerClose.touchleave&&h.hasTouchCapability&&(k+="touchstart."+e.__namespace+"-triggerClose",l+="touchend."+e.__namespace+"-triggerClose touchcancel."+e.__namespace+"-triggerClose"),j.on(l,function(a){if(e._touchIsTouchEvent(a)||!e._touchIsEmulatedEvent(a)){var b="mouseleave"==a.type?e.__options.delay:e.__options.delayTouch;e._trigger({delay:b[1],dismissable:!0,event:a,type:"dismissable"})}}).on(k,function(a){!e._touchIsTouchEvent(a)&&e._touchIsEmulatedEvent(a)||e._trigger({dismissable:!1,event:a,type:"dismissable"})})}e.__options.triggerClose.originClick&&e._$origin.on("click."+e.__namespace+"-triggerClose",function(a){e._touchIsTouchEvent(a)||e._touchIsEmulatedEvent(a)||e._close(a)}),(e.__options.triggerClose.click||e.__options.triggerClose.tap&&h.hasTouchCapability)&&setTimeout(function(){if("closed"!=e.__state){var b="",c=a(h.window.document.body);e.__options.triggerClose.click&&(b+="click."+e.__namespace+"-triggerClose "),e.__options.triggerClose.tap&&h.hasTouchCapability&&(b+="touchend."+e.__namespace+"-triggerClose"),c.on(b,function(b){e._touchIsMeaningfulEvent(b)&&(e._touchRecordEvent(b),e.__options.interactive&&a.contains(e._$tooltip[0],b.target)||e._close(b))}),e.__options.triggerClose.tap&&h.hasTouchCapability&&c.on("touchstart."+e.__namespace+"-triggerClose",function(a){e._touchRecordEvent(a)})}},0),e._trigger("ready"),e.__options.functionReady&&e.__options.functionReady.call(e,e,{origin:e._$origin[0],tooltip:e._$tooltip[0]})}if(e.__options.timer>0){var m=setTimeout(function(){e._close()},e.__options.timer+g);e.__timeouts.close.push(m)}}}return e},_openShortly:function(a){var b=this,c=!0;if("stable"!=b.__state&&"appearing"!=b.__state&&!b.__timeouts.open&&(b._trigger({type:"start",event:a,stop:function(){c=!1}}),c)){var d=0==a.type.indexOf("touch")?b.__options.delayTouch:b.__options.delay;d[0]?b.__timeouts.open=setTimeout(function(){b.__timeouts.open=null,b.__pointerIsOverOrigin&&b._touchIsMeaningfulEvent(a)?(b._trigger("startend"),b._open(a)):b._trigger("startcancel")},d[0]):(b._trigger("startend"),b._open(a))}return b},_optionsExtract:function(b,c){var d=this,e=a.extend(!0,{},c),f=d.__options[b];return f||(f={},a.each(c,function(a,b){var c=d.__options[a];void 0!==c&&(f[a]=c)})),a.each(e,function(b,c){void 0!==f[b]&&("object"!=typeof c||c instanceof Array||null==c||"object"!=typeof f[b]||f[b]instanceof Array||null==f[b]?e[b]=f[b]:a.extend(e[b],f[b]))}),e},_plug:function(b){var c=a.tooltipster._plugin(b);if(!c)throw new Error('The "'+b+'" plugin is not defined');return c.instance&&a.tooltipster.__bridge(c.instance,this,c.name),this},_touchIsEmulatedEvent:function(a){for(var b=!1,c=(new Date).getTime(),d=this.__touchEvents.length-1;d>=0;d--){var e=this.__touchEvents[d];if(!(c-e.time<500))break;e.target===a.target&&(b=!0)}return b},_touchIsMeaningfulEvent:function(a){return this._touchIsTouchEvent(a)&&!this._touchSwiped(a.target)||!this._touchIsTouchEvent(a)&&!this._touchIsEmulatedEvent(a)},_touchIsTouchEvent:function(a){return 0==a.type.indexOf("touch")},_touchRecordEvent:function(a){return this._touchIsTouchEvent(a)&&(a.time=(new Date).getTime(),this.__touchEvents.push(a)),this},_touchSwiped:function(a){for(var b=!1,c=this.__touchEvents.length-1;c>=0;c--){var d=this.__touchEvents[c];if("touchmove"==d.type){b=!0;break}if("touchstart"==d.type&&a===d.target)break}return b},_trigger:function(){var b=Array.prototype.slice.apply(arguments);return"string"==typeof b[0]&&(b[0]={type:b[0]}),b[0].instance=this,b[0].origin=this._$origin?this._$origin[0]:null,b[0].tooltip=this._$tooltip?this._$tooltip[0]:null,this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,b),a.tooltipster._trigger.apply(a.tooltipster,b),this.__$emitterPublic.trigger.apply(this.__$emitterPublic,b),this},_unplug:function(b){var c=this;if(c[b]){var d=a.tooltipster._plugin(b);d.instance&&a.each(d.instance,function(a,d){c[a]&&c[a].bridged===c[b]&&delete c[a]}),c[b].__destroy&&c[b].__destroy(),delete c[b]}return c},close:function(a){return this.__destroyed?this.__destroyError():this._close(null,a),this},content:function(a){var b=this;if(void 0===a)return b.__Content;if(b.__destroyed)b.__destroyError();else if(b.__contentSet(a),null!==b.__Content){if("closed"!==b.__state&&(b.__contentInsert(),b.reposition(),b.__options.updateAnimation))if(h.hasTransitions){var c=b.__options.updateAnimation;b._$tooltip.addClass("tooltipster-update-"+c),setTimeout(function(){"closed"!=b.__state&&b._$tooltip.removeClass("tooltipster-update-"+c)},1e3)}else b._$tooltip.fadeTo(200,.5,function(){"closed"!=b.__state&&b._$tooltip.fadeTo(200,1)})}else b._close();return b},destroy:function(){var b=this;if(b.__destroyed)b.__destroyError();else{"closed"!=b.__state?b.option("animationDuration",0)._close(null,null,!0):b.__timeoutsClear(),b._trigger("destroy"),b.__destroyed=!0,b._$origin.removeData(b.__namespace).off("."+b.__namespace+"-triggerOpen"),a(h.window.document.body).off("."+b.__namespace+"-triggerOpen");var c=b._$origin.data("tooltipster-ns");if(c)if(1===c.length){var d=null;"previous"==b.__options.restoration?d=b._$origin.data("tooltipster-initialTitle"):"current"==b.__options.restoration&&(d="string"==typeof b.__Content?b.__Content:a("
            ").append(b.__Content).html()),d&&b._$origin.attr("title",d),b._$origin.removeClass("tooltipstered"),b._$origin.removeData("tooltipster-ns").removeData("tooltipster-initialTitle")}else c=a.grep(c,function(a,c){return a!==b.__namespace}),b._$origin.data("tooltipster-ns",c);b._trigger("destroyed"),b._off(),b.off(),b.__Content=null,b.__$emitterPrivate=null,b.__$emitterPublic=null,b.__options.parent=null,b._$origin=null,b._$tooltip=null,a.tooltipster.__instancesLatestArr=a.grep(a.tooltipster.__instancesLatestArr,function(a,c){return b!==a}),clearInterval(b.__garbageCollector)}return b},disable:function(){return this.__destroyed?(this.__destroyError(),this):(this._close(),this.__enabled=!1,this)},elementOrigin:function(){return this.__destroyed?void this.__destroyError():this._$origin[0]},elementTooltip:function(){return this._$tooltip?this._$tooltip[0]:null},enable:function(){return this.__enabled=!0,this},hide:function(a){return this.close(a)},instance:function(){return this},off:function(){return this.__destroyed||this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},on:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},one:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},open:function(a){return this.__destroyed?this.__destroyError():this._open(null,a),this},option:function(b,c){return void 0===c?this.__options[b]:(this.__destroyed?this.__destroyError():(this.__options[b]=c,this.__optionsFormat(),a.inArray(b,["trigger","triggerClose","triggerOpen"])>=0&&this.__prepareOrigin(),"selfDestruction"===b&&this.__prepareGC()),this)},reposition:function(a,b){var c=this;return c.__destroyed?c.__destroyError():"closed"!=c.__state&&d(c._$origin)&&(b||d(c._$tooltip))&&(b||c._$tooltip.detach(),c.__Geometry=c.__geometry(),c._trigger({type:"reposition",event:a,helper:{geo:c.__Geometry}})),c},show:function(a){return this.open(a)},status:function(){return{destroyed:this.__destroyed,enabled:this.__enabled,open:"closed"!==this.__state,state:this.__state}},triggerHandler:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this}},a.fn.tooltipster=function(){var b=Array.prototype.slice.apply(arguments),c="You are using a single HTML element as content for several tooltips. You probably want to set the contentCloning option to TRUE.";if(0===this.length)return this;if("string"==typeof b[0]){var d="#*$~&";return this.each(function(){var e=a(this).data("tooltipster-ns"),f=e?a(this).data(e[0]):null;if(!f)throw new Error("You called Tooltipster's \""+b[0]+'" method on an uninitialized element');if("function"!=typeof f[b[0]])throw new Error('Unknown method "'+b[0]+'"');this.length>1&&"content"==b[0]&&(b[1]instanceof a||"object"==typeof b[1]&&null!=b[1]&&b[1].tagName)&&!f.__options.contentCloning&&f.__options.debug&&console.log(c);var g=f[b[0]](b[1],b[2]);return g!==f||"instance"===b[0]?(d=g,!1):void 0}),"#*$~&"!==d?d:this}a.tooltipster.__instancesLatestArr=[];var e=b[0]&&void 0!==b[0].multiple,g=e&&b[0].multiple||!e&&f.multiple,h=b[0]&&void 0!==b[0].content,i=h&&b[0].content||!h&&f.content,j=b[0]&&void 0!==b[0].contentCloning,k=j&&b[0].contentCloning||!j&&f.contentCloning,l=b[0]&&void 0!==b[0].debug,m=l&&b[0].debug||!l&&f.debug;return this.length>1&&(i instanceof a||"object"==typeof i&&null!=i&&i.tagName)&&!k&&m&&console.log(c),this.each(function(){var c=!1,d=a(this),e=d.data("tooltipster-ns"),f=null;e?g?c=!0:m&&(console.log("Tooltipster: one or more tooltips are already attached to the element below. Ignoring."),console.log(this)):c=!0,c&&(f=new a.Tooltipster(this,b[0]),e||(e=[]),e.push(f.__namespace),d.data("tooltipster-ns",e),d.data(f.__namespace,f),f.__options.functionInit&&f.__options.functionInit.call(f,f,{origin:this}),f._trigger("init")),a.tooltipster.__instancesLatestArr.push(f)}),this},b.prototype={__init:function(b){this.__$tooltip=b,this.__$tooltip.css({left:0,overflow:"hidden",position:"absolute",top:0}).find(".tooltipster-content").css("overflow","auto"),this.$container=a('
            ').append(this.__$tooltip).appendTo(h.window.document.body)},__forceRedraw:function(){var a=this.__$tooltip.parent();this.__$tooltip.detach(),this.__$tooltip.appendTo(a)},constrain:function(a,b){return this.constraints={width:a,height:b},this.__$tooltip.css({display:"block",height:"",overflow:"auto",width:a}),this},destroy:function(){this.__$tooltip.detach().find(".tooltipster-content").css({display:"",overflow:""}),this.$container.remove()},free:function(){return this.constraints=null,this.__$tooltip.css({display:"",height:"",overflow:"visible",width:""}),this},measure:function(){this.__forceRedraw();var a=this.__$tooltip[0].getBoundingClientRect(),b={size:{height:a.height||a.bottom-a.top,width:a.width||a.right-a.left}};if(this.constraints){var c=this.__$tooltip.find(".tooltipster-content"),d=this.__$tooltip.outerHeight(),e=c[0].getBoundingClientRect(),f={height:d<=this.constraints.height,width:a.width<=this.constraints.width&&e.width>=c[0].scrollWidth-1};b.fits=f.height&&f.width}return h.IE&&h.IE<=11&&b.size.width!==h.window.document.documentElement.clientWidth&&(b.size.width=Math.ceil(b.size.width)+1),b}};var j=navigator.userAgent.toLowerCase();-1!=j.indexOf("msie")?h.IE=parseInt(j.split("msie")[1]):-1!==j.toLowerCase().indexOf("trident")&&-1!==j.indexOf(" rv:11")?h.IE=11:-1!=j.toLowerCase().indexOf("edge/")&&(h.IE=parseInt(j.toLowerCase().split("edge/")[1]));var k="tooltipster.sideTip";return a.tooltipster._plugin({name:k,instance:{__defaults:function(){return{arrow:!0,distance:6,functionPosition:null,maxWidth:null,minIntersection:16,minWidth:0,position:null,side:"top",viewportAware:!0}},__init:function(a){var b=this;b.__instance=a,b.__namespace="tooltipster-sideTip-"+Math.round(1e6*Math.random()),b.__previousState="closed",b.__options,b.__optionsFormat(),b.__instance._on("state."+b.__namespace,function(a){"closed"==a.state?b.__close():"appearing"==a.state&&"closed"==b.__previousState&&b.__create(),b.__previousState=a.state}),b.__instance._on("options."+b.__namespace,function(){b.__optionsFormat()}),b.__instance._on("reposition."+b.__namespace,function(a){b.__reposition(a.event,a.helper)})},__close:function(){this.__instance.content()instanceof a&&this.__instance.content().detach(),this.__instance._$tooltip.remove(),this.__instance._$tooltip=null},__create:function(){var b=a('
            ');this.__options.arrow||b.find(".tooltipster-box").css("margin",0).end().find(".tooltipster-arrow").hide(),this.__options.minWidth&&b.css("min-width",this.__options.minWidth+"px"),this.__options.maxWidth&&b.css("max-width",this.__options.maxWidth+"px"), +this.__instance._$tooltip=b,this.__instance._trigger("created")},__destroy:function(){this.__instance._off("."+self.__namespace)},__optionsFormat:function(){var b=this;if(b.__options=b.__instance._optionsExtract(k,b.__defaults()),b.__options.position&&(b.__options.side=b.__options.position),"object"!=typeof b.__options.distance&&(b.__options.distance=[b.__options.distance]),b.__options.distance.length<4&&(void 0===b.__options.distance[1]&&(b.__options.distance[1]=b.__options.distance[0]),void 0===b.__options.distance[2]&&(b.__options.distance[2]=b.__options.distance[0]),void 0===b.__options.distance[3]&&(b.__options.distance[3]=b.__options.distance[1]),b.__options.distance={top:b.__options.distance[0],right:b.__options.distance[1],bottom:b.__options.distance[2],left:b.__options.distance[3]}),"string"==typeof b.__options.side){var c={top:"bottom",right:"left",bottom:"top",left:"right"};b.__options.side=[b.__options.side,c[b.__options.side]],"left"==b.__options.side[0]||"right"==b.__options.side[0]?b.__options.side.push("top","bottom"):b.__options.side.push("right","left")}6===a.tooltipster._env.IE&&b.__options.arrow!==!0&&(b.__options.arrow=!1)},__reposition:function(b,c){var d,e=this,f=e.__targetFind(c),g=[];e.__instance._$tooltip.detach();var h=e.__instance._$tooltip.clone(),i=a.tooltipster._getRuler(h),j=!1,k=e.__instance.option("animation");switch(k&&h.removeClass("tooltipster-"+k),a.each(["window","document"],function(d,k){var l=null;if(e.__instance._trigger({container:k,helper:c,satisfied:j,takeTest:function(a){l=a},results:g,type:"positionTest"}),1==l||0!=l&&0==j&&("window"!=k||e.__options.viewportAware))for(var d=0;d=h.outerSize.width&&c.geo.available[k][n].height>=h.outerSize.height?h.fits=!0:h.fits=!1:h.fits=p.fits,"window"==k&&(h.fits?"top"==n||"bottom"==n?h.whole=c.geo.origin.windowOffset.right>=e.__options.minIntersection&&c.geo.window.size.width-c.geo.origin.windowOffset.left>=e.__options.minIntersection:h.whole=c.geo.origin.windowOffset.bottom>=e.__options.minIntersection&&c.geo.window.size.height-c.geo.origin.windowOffset.top>=e.__options.minIntersection:h.whole=!1),g.push(h),h.whole)j=!0;else if("natural"==h.mode&&(h.fits||h.size.width<=c.geo.available[k][n].width))return!1}})}}),e.__instance._trigger({edit:function(a){g=a},event:b,helper:c,results:g,type:"positionTested"}),g.sort(function(a,b){if(a.whole&&!b.whole)return-1;if(!a.whole&&b.whole)return 1;if(a.whole&&b.whole){var c=e.__options.side.indexOf(a.side),d=e.__options.side.indexOf(b.side);return d>c?-1:c>d?1:"natural"==a.mode?-1:1}if(a.fits&&!b.fits)return-1;if(!a.fits&&b.fits)return 1;if(a.fits&&b.fits){var c=e.__options.side.indexOf(a.side),d=e.__options.side.indexOf(b.side);return d>c?-1:c>d?1:"natural"==a.mode?-1:1}return"document"==a.container&&"bottom"==a.side&&"natural"==a.mode?-1:1}),d=g[0],d.coord={},d.side){case"left":case"right":d.coord.top=Math.floor(d.target-d.size.height/2);break;case"bottom":case"top":d.coord.left=Math.floor(d.target-d.size.width/2)}switch(d.side){case"left":d.coord.left=c.geo.origin.windowOffset.left-d.outerSize.width;break;case"right":d.coord.left=c.geo.origin.windowOffset.right+d.distance.horizontal;break;case"top":d.coord.top=c.geo.origin.windowOffset.top-d.outerSize.height;break;case"bottom":d.coord.top=c.geo.origin.windowOffset.bottom+d.distance.vertical}"window"==d.container?"top"==d.side||"bottom"==d.side?d.coord.left<0?c.geo.origin.windowOffset.right-this.__options.minIntersection>=0?d.coord.left=0:d.coord.left=c.geo.origin.windowOffset.right-this.__options.minIntersection-1:d.coord.left>c.geo.window.size.width-d.size.width&&(c.geo.origin.windowOffset.left+this.__options.minIntersection<=c.geo.window.size.width?d.coord.left=c.geo.window.size.width-d.size.width:d.coord.left=c.geo.origin.windowOffset.left+this.__options.minIntersection+1-d.size.width):d.coord.top<0?c.geo.origin.windowOffset.bottom-this.__options.minIntersection>=0?d.coord.top=0:d.coord.top=c.geo.origin.windowOffset.bottom-this.__options.minIntersection-1:d.coord.top>c.geo.window.size.height-d.size.height&&(c.geo.origin.windowOffset.top+this.__options.minIntersection<=c.geo.window.size.height?d.coord.top=c.geo.window.size.height-d.size.height:d.coord.top=c.geo.origin.windowOffset.top+this.__options.minIntersection+1-d.size.height):(d.coord.left>c.geo.window.size.width-d.size.width&&(d.coord.left=c.geo.window.size.width-d.size.width),d.coord.left<0&&(d.coord.left=0)),e.__sideChange(h,d.side),c.tooltipClone=h[0],c.tooltipParent=e.__instance.option("parent").parent[0],c.mode=d.mode,c.whole=d.whole,c.origin=e.__instance._$origin[0],c.tooltip=e.__instance._$tooltip[0],delete d.container,delete d.fits,delete d.mode,delete d.outerSize,delete d.whole,d.distance=d.distance.horizontal||d.distance.vertical;var l=a.extend(!0,{},d);if(e.__instance._trigger({edit:function(a){d=a},event:b,helper:c,position:l,type:"position"}),e.__options.functionPosition){var m=e.__options.functionPosition.call(e,e.__instance,c,l);m&&(d=m)}i.destroy();var n,o;"top"==d.side||"bottom"==d.side?(n={prop:"left",val:d.target-d.coord.left},o=d.size.width-this.__options.minIntersection):(n={prop:"top",val:d.target-d.coord.top},o=d.size.height-this.__options.minIntersection),n.valo&&(n.val=o);var p;p=c.geo.origin.fixedLineage?c.geo.origin.windowOffset:{left:c.geo.origin.windowOffset.left+c.geo.window.scroll.left,top:c.geo.origin.windowOffset.top+c.geo.window.scroll.top},d.coord={left:p.left+(d.coord.left-c.geo.origin.windowOffset.left),top:p.top+(d.coord.top-c.geo.origin.windowOffset.top)},e.__sideChange(e.__instance._$tooltip,d.side),c.geo.origin.fixedLineage?e.__instance._$tooltip.css("position","fixed"):e.__instance._$tooltip.css("position",""),e.__instance._$tooltip.css({left:d.coord.left,top:d.coord.top,height:d.size.height,width:d.size.width}).find(".tooltipster-arrow").css({left:"",top:""}).css(n.prop,n.val),e.__instance._$tooltip.appendTo(e.__instance.option("parent")),e.__instance._trigger({type:"repositioned",event:b,position:d})},__sideChange:function(a,b){a.removeClass("tooltipster-bottom").removeClass("tooltipster-left").removeClass("tooltipster-right").removeClass("tooltipster-top").addClass("tooltipster-"+b)},__targetFind:function(a){var b={},c=this.__instance._$origin[0].getClientRects();if(c.length>1){var d=this.__instance._$origin.css("opacity");1==d&&(this.__instance._$origin.css("opacity",.99),c=this.__instance._$origin[0].getClientRects(),this.__instance._$origin.css("opacity",1))}if(c.length<2)b.top=Math.floor(a.geo.origin.windowOffset.left+a.geo.origin.size.width/2),b.bottom=b.top,b.left=Math.floor(a.geo.origin.windowOffset.top+a.geo.origin.size.height/2),b.right=b.left;else{var e=c[0];b.top=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil(c.length/2)-1]:c[0],b.right=Math.floor(e.top+(e.bottom-e.top)/2),e=c[c.length-1],b.bottom=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil((c.length+1)/2)-1]:c[c.length-1],b.left=Math.floor(e.top+(e.bottom-e.top)/2)}return b}}}),a}); \ No newline at end of file diff --git a/assets/admin.css b/assets/admin.css new file mode 100755 index 00000000..22a19285 --- /dev/null +++ b/assets/admin.css @@ -0,0 +1,209 @@ +.post-type-opalestate_property .post-state { + background: #ef114c; + font-size: 10px; + font-weight: normal; + padding: 3px 6px; + color: #FFF; + border-radius: 5px 5px 5px; +} + +.fixed .column-featured, +.fixed .column-sku { + width: 10%; +} + +.fixed .column-address { + width: 20%; +} + +.type-download { + float: left; + margin: 0 1em 1em 0 !important; + padding: 0; + vertical-align: top; + width: 280px; + text-decoration: none; + color: inherit; + border: 2px solid #ddd; + display: block; + overflow: hidden; + background: #f5f5f5; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + -webkit-transition-property: border, background, color; + transition-property: border, background, color; + -webkit-transition-duration: .05s; + transition-duration: .05s; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + position: relative; + background: #FFF; +} + +.type-download:hover { + border-color: #0073aa; +} + +.type-download h4 { + margin: 6px 0px; +} + +.type-download a { + font-size: 18px; + font-weight: bold; + outline: 0 none; + text-decoration: none; +} + +.type-download .feed-content { + color: #72777c; +} + +.type-download img { + max-width: 100%; +} + +.type-download .feed-content { + padding: 15px 20px; +} + +.type-download .feed-bottom { + background: #ddd; + padding: 15px 8px; +} + +.type-download:hover .feed-bottom { + background: #0073aa; +} + +.vc_element-icon.icon-wpb-estates-1 { + background-image: url(images/1.png); +} + +.vc_element-icon.icon-wpb-estates-2 { + background-image: url(images/2.png); +} + +.vc_element-icon.icon-wpb-estates-3 { + background-image: url(images/3.png); +} + +.vc_element-icon.icon-wpb-estates-4 { + background-image: url(images/4.png); +} + +.vc_element-icon.icon-wpb-estates-5 { + background-image: url(images/5.png); +} + +.vc_element-icon.icon-wpb-estates-6 { + background-image: url(images/6.png); +} + +.vc_element-icon.icon-wpb-estates-7 { + background-image: url(images/7.png); +} + +.vc_element-icon.icon-wpb-estates-8 { + background-image: url(images/8.png); +} + +.vc_element-icon.icon-wpb-estates-9 { + background-image: url(images/9.png); +} + +.vc_element-icon.icon-wpb-estates-10 { + background-image: url(images/10.png); +} + +.vc_element-icon.icon-wpb-estates-11 { + background-image: url(images/11.png); +} + +.vc_element-icon.icon-wpb-estates-12 { + background-image: url(images/12.png); +} + +.vc_element-icon.icon-wpb-estates-13 { + background-image: url(images/13.png); +} + +.vc_element-icon.icon-wpb-estates-14 { + background-image: url(images/14.png); +} + +.vc_element-icon.icon-wpb-estates-15 { + background-image: url(images/15.png); +} + +.vc_element-icon.icon-wpb-estates-16 { + background-image: url(images/16.png); +} + +.vc_element-icon.icon-wpb-estates-17 { + background-image: url(images/17.png); +} + +.vc_element-icon.icon-wpb-estates-18 { + background-image: url(images/18.png); +} + +.vc_element-icon.icon-wpb-estates-19 { + background-image: url(images/19.png); +} + +/** CMD BOX 2 */ +.cmb2-wrap .field-row-2 .cmb-row { + display: inline-block; + width: 50%; +} + +.cmb2-wrap .field-row-2 .cmb-row:nth-child(even) > div { + padding-left: 12px; +} + +.cmb2-wrap .cmb-td { + padding: 4px 0; +} + +.cmb2-wrap .cmb-th { + padding: 0px 10px 10px 0; +} + +/***/ +.form-settings-wrap { + display: flex; +} +.form-settings-wrap .cmb2-wrap { + min-height: 300px; +} +.form-settings-wrap .subtab-settings-navs { + width: 220px; + background: #2f73e9; + min-height: 300px; +} +.form-settings-wrap .subtab-settings-navs ul { + padding: 0; + margin: 0; +} +.form-settings-wrap .subtab-settings-navs ul li { + padding: 0; + margin: 0; +} +.form-settings-wrap .subtab-settings-navs ul li a { + display: block; + padding: 12px 6px; + background: #2f73e9; + text-align: right; + text-decoration: none; + color: #FFF; + font-weight: bold; +} +.form-settings-wrap .subtab-settings-navs ul li a.active { + background-color: #f1f1f1; + color: #000; +} +.form-settings-wrap .form-settings-form { + padding-left: 20px; + padding-right: 20px; +} diff --git a/assets/cluster-icon.png b/assets/cluster-icon.png new file mode 100755 index 00000000..e99e5ec9 Binary files /dev/null and b/assets/cluster-icon.png differ diff --git a/assets/cmb2-front.css b/assets/cmb2-front.css new file mode 100755 index 00000000..87ac3bc6 --- /dev/null +++ b/assets/cmb2-front.css @@ -0,0 +1,1303 @@ +@charset "UTF-8"; +.cmb2-uploader-files { + display: flex; + flex-wrap: wrap; +} +.cmb2-uploader-files > div { + width: 180px; + height: 130px; + overflow: hidden; +} +.cmb2-uploader-files .preview-image { + height: 100%; +} +.cmb2-uploader-files .preview-image img { + height: 100%; +} +.cmb2-uploader-files .button-placehold { + border: dashed 1px #ebebeb; + cursor: pointer; + text-align: center; +} +.cmb2-uploader-files .button-placehold i { + display: block; + font-size: 24px; + margin-bottom: 8px; +} +.cmb2-uploader-files .button-placehold .button-placehold-content { + position: relative; + top: 50%; + transform: translateY(-50%); +} +.cmb2-uploader-files input.select-file { + display: none; +} + +.uploader-item-preview { + position: relative; +} +.uploader-item-preview .btn-close { + position: absolute; + top: 4px; + right: 5px; + width: 15px; + height: 15px; + cursor: pointer; +} +.uploader-item-preview .btn-close:hover::before { + color: red; +} +.uploader-item-preview .btn-close::before { + content: '\f00d'; + font-family: Fontawesome; + transition: all .3s ease-in-out; +} +.uploader-item-preview .preview-icon { + padding-top: 4px; +} + +/*-------------------------------------------------------------- + * Main Wrap +--------------------------------------------------------------*/ +.cmb2-wrap { + margin: 0; +} +.cmb2-wrap input, +.cmb2-wrap textarea { + font-size: 14px; + max-width: 100%; + padding: 5px; +} +.cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +.cmb2-wrap textarea { + width: 500px; +} +.cmb2-wrap textarea.cmb2-textarea-code { + font-family: "Courier 10 Pitch", Courier, monospace; + line-height: 16px; +} +.cmb2-wrap input.cmb2-text-small, .cmb2-wrap input.cmb2-timepicker { + width: 100px; +} +.cmb2-wrap input.cmb2-text-money { + width: 90px; +} +.cmb2-wrap input.cmb2-text-medium { + width: 230px; +} +.cmb2-wrap input.cmb2-upload-file { + width: 65%; +} +.cmb2-wrap input.ed_button { + padding: 2px 4px; +} +.cmb2-wrap input:not([type="hidden"]) + input, +.cmb2-wrap input:not([type="hidden"]) + .button-secondary, +.cmb2-wrap input:not([type="hidden"]) + select { + margin-left: 20px; +} +.cmb2-wrap ul { + margin: 0; +} +.cmb2-wrap li { + font-size: 14px; + line-height: 16px; + margin: 1px 0 5px 0; +} +.cmb2-wrap select { + font-size: 14px; + margin-top: 3px; +} +.cmb2-wrap input:focus, +.cmb2-wrap textarea:focus { + background: #fffff8; +} +.cmb2-wrap input[type="radio"] { + margin: 0 5px 0 0; + padding: 0; +} +.cmb2-wrap input[type="checkbox"] { + margin: 0 5px 0 0; + padding: 0; +} +.cmb2-wrap .button-secondary { + color: #555; + border-color: #cccccc; + background: #f7f7f7; + box-shadow: 0 1px 0 #cccccc; + display: inline-block; + text-decoration: none; + font-size: 13px; + line-height: 26px; + height: 28px; + margin: 0; + padding: 0 10px 1px; + cursor: pointer; + border-width: 1px; + border-style: solid; + -webkit-appearance: none; + border-radius: 3px; + white-space: nowrap; + box-sizing: border-box; +} +.cmb2-wrap .button-secondary:hover { + background: #fafafa; + border-color: #999; + color: #23282d; +} +.cmb2-wrap .mceLayout { + border: 1px solid #e9e9e9 !important; +} +.cmb2-wrap .mceIframeContainer { + background: #ffffff; +} +.cmb2-wrap .meta_mce { + width: 97%; +} +.cmb2-wrap .meta_mce textarea { + width: 100%; +} +.cmb2-wrap .field-row-2 { + margin: 0 -15px; +} +.cmb2-wrap .field-row-2::after { + content: ""; + display: block; + clear: both; +} +.cmb2-wrap .field-row-2 .cmb-row { + display: block; + float: left; + width: 100%; + padding-left: 15px; + padding-right: 15px; +} +@media screen and (min-width: 768px) { + .cmb2-wrap .field-row-2 .cmb-row { + width: 50%; + } +} +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-input-wrap { + vertical-align: middle; +} +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-container { + margin: 0 10px 0 0; +} +.cmb2-wrap .cmb-row { + margin: 0; +} +.cmb2-wrap .cmb-row:after { + content: ''; + clear: both; + display: block; + width: 100%; +} +.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description { + padding-top: 0; + padding-bottom: 1em; +} + +.cmb2-metabox { + clear: both; + margin: 0; +} +.cmb2-metabox > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox > .cmb-row:first-of-type > .cmb-th, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-th { + border: 0; +} + +.cmb-add-row { + margin: 1.8em 0 0; +} + +.cmb-nested .cmb-td, +.cmb-repeatable-group .cmb-th, +.cmb-repeatable-group:first-of-type { + border: 0; +} + +.cmb-row:last-of-type, +.cmb2-wrap .cmb-row:last-of-type, +.cmb-repeatable-group:last-of-type { + border-bottom: 0; +} + +.cmb-repeatable-grouping { + border: 1px solid #e9e9e9; + padding: 0 1em; +} +.cmb-repeatable-grouping.cmb-row { + margin: 0 0 0.8em; +} + +.cmb-th { + color: #0a1938; + float: left; + font-weight: 500; + line-height: 1.2; + padding: 20px 10px 20px 0; + vertical-align: top; + width: 200px; +} +@media (max-width: 450px) { + .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; + } + .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; + } +} + +.cmb-td { + line-height: 1.3; + max-width: 100%; + padding: 15px 10px; + vertical-align: middle; +} + +.cmb-type-title .cmb-td { + padding: 0; +} + +.cmb-th label { + display: block; + padding: 5px 0; +} + +.cmb-th + .cmb-td { + float: left; +} + +.cmb-td .cmb-td { + padding-bottom: 1em; +} + +.cmb-remove-row { + text-align: right; +} + +.empty-row.hidden { + display: none; +} + +.cmb-repeat-table { + background-color: #fafafa; + border: 1px solid #e1e1e1; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row { + position: relative; + counter-increment: el; + margin: 0; + padding: 10px 10px 10px 50px; + border-bottom: none !important; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row + .cmb-repeat-row { + border-top: solid 1px #e9e9e9; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper { + outline: dashed 2px #e9e9e9 !important; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row:before { + content: counter(el); + display: block; + top: 0; + left: 0; + position: absolute; + width: 35px; + height: 100%; + line-height: 35px; + cursor: move; + color: #757575; + text-align: center; + border-right: solid 1px #e9e9e9; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td { + margin: 0; + padding: 0; +} +.cmb-repeat-table + .cmb-add-row { + margin: 0; +} +.cmb-repeat-table + .cmb-add-row:before { + content: ''; + width: 1px; + height: 1.6em; + display: block; + margin-left: 17px; + background-color: gainsboro; +} +.cmb-repeat-table .cmb-remove-row { + top: 7px; + right: 7px; + position: absolute; + width: auto; + margin-left: 0; + padding: 0 !important; + display: none; +} +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button { + font-size: 20px; + text-indent: -1000px; + overflow: hidden; + position: relative; + height: auto; + line-height: 1; + padding: 0 10px 0; +} +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button:before { + content: ""; + font-family: 'Dashicons'; + speak: none; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + margin: 0; + text-indent: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; +} +.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row { + display: block; +} + +.cmb-repeatable-group .cmb-th { + padding: 5px; +} +.cmb-repeatable-group .cmb-group-title { + background-color: #e9e9e9; + padding: 8px 12px 8px 2.2em; + margin: 0 -1em; + min-height: 1.5em; + font-size: 14px; + line-height: 1.4; +} +.cmb-repeatable-group .cmb-group-title h4 { + border: 0; + margin: 0; + font-size: 1.2em; + font-weight: 500; + padding: 0.5em 0.75em; +} +.cmb-repeatable-group .cmb-group-title .cmb-th { + display: block; + width: 100%; +} +.cmb-repeatable-group .cmb-group-description .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; +} +.cmb-repeatable-group .cmb-group-description .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} +.cmb-repeatable-group .cmb-shift-rows { + font-size: 1em; + margin-right: 1em; + text-decoration: none; +} +.cmb-repeatable-group .cmb-shift-rows .dashicons { + font-size: 1.5em; + height: 1.5em; + line-height: 1.2em; + width: 1em; +} +.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2 { + line-height: 1.3em; +} +.cmb-repeatable-group .cmb2-upload-button { + float: right; +} + +p.cmb2-metabox-description { + color: #757575; + font-style: italic; + margin: 0; + padding-top: .5em; +} + +span.cmb2-metabox-description { + color: #757575; + font-style: italic; +} + +.cmb2-metabox-title { + margin: 0 0 5px 0; + padding: 5px 0 0 0; + font-size: 14px; +} + +.cmb-inline ul { + padding: 4px 0 0 0; +} + +.cmb-inline li { + display: inline-block; + padding-right: 18px; +} + +.cmb-type-textarea-code pre { + margin: 0; +} + +.cmb2-media-status .img-status { + clear: none; + display: inline-block; + vertical-align: middle; + margin-right: 10px; + width: auto; +} +.cmb2-media-status .img-status img { + max-width: 350px; + height: auto; +} +.cmb2-media-status .img-status img, +.cmb2-media-status .embed-status { + background: #eee; + border: 5px solid #ffffff; + outline: 1px solid #e9e9e9; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.05); + background-image: linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0), linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; + border-radius: 2px; + -moz-border-radius: 2px; + margin: 15px 0 0 0; +} +.cmb2-media-status .embed-status { + float: left; + max-width: 800px; +} +.cmb2-media-status .img-status, .cmb2-media-status .embed-status { + position: relative; +} +.cmb2-media-status .img-status .cmb2-remove-file-button, .cmb2-media-status .embed-status .cmb2-remove-file-button { + background: url(../images/ico-delete.png); + height: 16px; + left: -5px; + position: absolute; + text-indent: -9999px; + top: -5px; + width: 16px; +} +.cmb2-media-status .img-status .cmb2-remove-file-button { + top: 10px; +} +.cmb2-media-status .img-status img, .cmb2-media-status .file-status > span { + cursor: pointer; +} +.cmb2-media-status.cmb-attach-list .img-status img, .cmb2-media-status.cmb-attach-list .file-status > span { + cursor: move; +} + +.cmb-type-file-list .cmb2-media-status .img-status { + clear: none; + vertical-align: middle; + width: auto; + margin-right: 10px; + margin-bottom: 10px; + margin-top: 0; +} + +.cmb-attach-list li { + clear: both; + display: inline-block; + width: 100%; + margin-top: 5px; + margin-bottom: 10px; +} +.cmb-attach-list li img { + float: left; + margin-right: 10px; +} + +.cmb2-remove-wrapper { + margin: 0; +} + +.child-cmb2 .cmb-th { + text-align: left; +} + +.cmb2-indented-hierarchy { + padding-left: 1.5em; +} + +@media (max-width: 450px) { + .cmb-th, + .cmb-td, + .cmb-th + .cmb-td { + display: block; + float: none; + width: 100%; + } +} +.opalestate-submission-form { + position: relative; +} +.opalestate-submission-form .cmb-td { + width: 100%; + padding: 15px 0; +} +.opalestate-submission-form .cmb-th { + width: 100%; + padding-bottom: 0; + padding-top: 15px; +} +.opalestate-submission-form .cmb-th label { + margin: 0; + padding: 0; +} +.opalestate-submission-form span.cmb2-metabox-description { + padding-top: .5em; + display: block; +} +.opalestate-submission-form .cmb2-wrap input.cmb2-text-medium, .opalestate-submission-form .cmb2-wrap input.cmb2-text-small { + width: 100%; +} +.opalestate-submission-form .opalestate-tab-content::after { + content: ''; + display: block; + clear: both; +} +@media screen and (min-width: 768px) { + .opalestate-submission-form .submission-next-btn { + float: right; + } +} +.opalestate-submission-form .btn-submit-cmb { + position: absolute; + bottom: 0px; + right: 0px; + padding: 19px 25px 17px 20px; +} +@media screen and (max-width: 767px) { + .opalestate-submission-form .btn-submit-cmb { + position: relative; + bottom: 0; + right: 0; + margin-top: 15px; + } +} +.opalestate-submission-form .btn-submit-cmb::before { + content: "\f138"; + font-family: Fontawesome; + margin-right: 18px; + padding-right: 20px; +} +.opalestate-submission-form .btn-submit-cmb::after { + content: ""; + width: 52px; + position: absolute; + top: 0; + left: 0; + height: 100%; + background-color: transparent; + -webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15); + box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15); +} +.opalestate-submission-form .submission-back-btn, .opalestate-submission-form .submission-next-btn, .opalestate-submission-form .submission-next-btn { + margin-top: 15px; +} +.opalestate-submission-form .cmb-repeatable-group .cmb-group-title { + font-size: 15px; +} +.opalestate-submission-form .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + top: .4em; +} +.opalestate-submission-form .cmb-type-group .field-row-2 .cmb-row { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; +} +.opalestate-submission-form .cmb-type-group .cmb-row { + padding-top: 15px; + padding-bottom: 15px; + margin-bottom: 15px; +} +.opalestate-submission-form .cmb-type-group .cmb-row.postbox { + padding-top: 0; + border-bottom: 1px solid #e9e9e9; +} +.opalestate-submission-form .cmb-type-group .cmb-th { + width: 100%; + padding: 0; + float: none; +} +.opalestate-submission-form .cmb-type-group .cmb-th + .cmb-td { + width: 100%; + float: none; + padding: 15px 0; +} + +/*-------------------------------------------------------------- + * Post Metaboxes +--------------------------------------------------------------*/ +#poststuff .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} + +#poststuff .repeatable .cmb-group-title { + padding-left: 2.2em; +} + +.cmb2-postbox .cmb2-wrap, .cmb-type-group .cmb2-wrap { + margin: 0; +} +.cmb2-postbox .cmb2-wrap > .cmb-field-list > .cmb-row, .cmb-type-group .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.8em 0; +} +.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed, .cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +.cmb2-postbox .cmb-row, .cmb-type-group .cmb-row { + padding: 0 0 1.8em; + margin: 0 0 0.8em; +} +.cmb2-postbox .cmb-row .cmbhandle, .cmb-type-group .cmb-row .cmbhandle { + right: -1em; + position: relative; + color: #222222; +} +.cmb2-postbox .cmb-repeatable-grouping, .cmb-type-group .cmb-repeatable-grouping { + padding: 0 1em; + max-width: 100%; + min-width: 1px !important; +} +.cmb2-postbox .cmb-repeatable-group > .cmb-row, .cmb-type-group .cmb-repeatable-group > .cmb-row { + padding-bottom: 0; +} +.cmb2-postbox .cmb-th, .cmb-type-group .cmb-th { + width: 18%; + padding: 0 2% 0 0; +} +.cmb2-postbox .cmb-td, .cmb-type-group .cmb-td { + margin-bottom: 0; + padding: 0; + line-height: 1.3; +} +.cmb2-postbox .cmb-th + .cmb-td, .cmb-type-group .cmb-th + .cmb-td { + width: 80%; + float: right; +} +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 1px solid #e9e9e9; +} +@media (max-width: 450px) { + .cmb2-postbox .cmb-row:not(:last-of-type), + .cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), + .cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 0; + } +} +.cmb2-postbox .cmb-repeat-group-field, +.cmb2-postbox .cmb-remove-field-row, .cmb-type-group .cmb-repeat-group-field, +.cmb-type-group .cmb-remove-field-row { + padding-top: 1.8em; +} + +/*-------------------------------------------------------------- + * Context Metaboxes +--------------------------------------------------------------*/ +/* Metabox collapse arrow indicators */ +.js .cmb2-postbox.context-box .toggle-indicator:before { + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.js .cmb2-postbox.context-box.closed .toggle-indicator:before { + content: "\f140"; +} + +.cmb2-postbox.context-box { + margin-bottom: 10px; +} +.cmb2-postbox.context-box.context-before_permalink-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-after_title-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-after_editor-box { + margin-top: 20px; + margin-bottom: 0; +} +.cmb2-postbox.context-box.context-form_top-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-form_top-box .hndle { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} +.cmb2-postbox.context-box .hndle { + cursor: auto; +} + +.cmb2-context-wrap { + margin-top: 10px; +} +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 300px; + width: auto; +} +.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox { + padding: 10px; +} +.cmb2-context-wrap .cmb-th { + padding: 0 2% 0 0; + width: 18%; +} +.cmb2-context-wrap .cmb-td { + width: 80%; + padding: 0; +} +.cmb2-context-wrap .cmb-row { + margin-bottom: 10px; +} +.cmb2-context-wrap .cmb-row:last-of-type { + margin-bottom: 0; +} + +/* one column on the post write/edit screen */ +@media only screen and (max-width: 850px) { + .cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 0; + } +} +/*-------------------------------------------------------------- + * Misc. +--------------------------------------------------------------*/ +#poststuff .cmb-repeatable-group h2 { + margin: 0; +} + +.edit-tags-php .cmb2-metabox-title, +.profile-php .cmb2-metabox-title, +.user-edit-php .cmb2-metabox-title { + font-size: 1.4em; +} + +.cmb2-postbox .cmb-spinner, .cmb2-no-box-wrap .cmb-spinner { + float: left; + display: none; +} + +.cmb-spinner { + display: none; +} +.cmb-spinner.is-active { + display: block; +} + +/*-------------------------------------------------------------- + * Collapsible UI +--------------------------------------------------------------*/ +.cmb2-metabox .cmbhandle { + color: #757575; + float: right; + width: 27px; + height: 30px; + cursor: pointer; + right: -1em; + position: relative; +} +.cmb2-metabox .cmbhandle:before { + content: '\f142'; + right: 12px; + font: normal 20px/1 'dashicons'; + speak: none; + display: inline-block; + padding: 8px 10px; + top: 0; + position: relative; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.cmb2-metabox .postbox.closed .cmbhandle:before { + content: '\f140'; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + -webkit-appearance: none !important; + background: none !important; + border: none !important; + position: absolute; + left: 0; + top: .5em; + line-height: 1em; + padding: 2px 6px 3px; + opacity: .5; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]) { + cursor: pointer; + color: #a00; + opacity: 1; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover { + color: #f00; +} + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress" + * https://github.com/stuttter/wp-datepicker-styling + * + */ +* html .cmb2-element.ui-helper-clearfix { + height: 1%; +} + +.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + /* Default Color Scheme */ +} +.cmb2-element.ui-datepicker *, .cmb2-element .ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.cmb2-element.ui-datepicker table, .cmb2-element .ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} +.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} +.cmb2-element.ui-datepicker .ui-datepicker-title, .cmb2-element .ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} +.cmb2-element.ui-datepicker .ui-datepicker-title select, .cmb2-element .ui-datepicker .ui-datepicker-title select { + margin-top: -8px; + margin-bottom: -8px; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-next { + position: relative; + top: 8px; + height: 34px; + width: 34px; +} +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next, .cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover { + left: 0; +} +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover, .cmb2-element .ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover { + right: 0; +} +.cmb2-element.ui-datepicker .ui-datepicker-next span, +.cmb2-element.ui-datepicker .ui-datepicker-prev span, .cmb2-element .ui-datepicker .ui-datepicker-next span, +.cmb2-element .ui-datepicker .ui-datepicker-prev span { + display: none; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, .cmb2-element .ui-datepicker .ui-datepicker-prev { + float: left; +} +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-next { + float: right; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-left: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before, .cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} +.cmb2-element.ui-datepicker select.ui-datepicker-month, +.cmb2-element.ui-datepicker select.ui-datepicker-year, .cmb2-element .ui-datepicker select.ui-datepicker-month, +.cmb2-element .ui-datepicker select.ui-datepicker-year { + width: 33%; + background: transparent; + border-color: transparent; + box-shadow: none; + color: #fff; + display: inline-block; +} +.cmb2-element.ui-datepicker select.ui-datepicker-month option, +.cmb2-element.ui-datepicker select.ui-datepicker-year option, .cmb2-element .ui-datepicker select.ui-datepicker-month option, +.cmb2-element .ui-datepicker select.ui-datepicker-year option { + color: #333; +} +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + color: #fff; + font-weight: 600; +} +.cmb2-element.ui-datepicker thead th, .cmb2-element .ui-datepicker thead th { + font-weight: normal; +} +.cmb2-element.ui-datepicker th, .cmb2-element .ui-datepicker th { + padding: 10px; +} +.cmb2-element.ui-datepicker td, .cmb2-element .ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} +.cmb2-element.ui-datepicker td.ui-datepicker-other-month, .cmb2-element .ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} +.cmb2-element.ui-datepicker td.ui-datepicker-week-end, .cmb2-element .ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} +.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today { + -webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); +} +.cmb2-element.ui-datepicker td.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} +.cmb2-element.ui-datepicker td.ui-datepicker-current-day, .cmb2-element .ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} +.cmb2-element.ui-datepicker td .ui-state-default, .cmb2-element .ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} +.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default, .cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + background: #32373c; +} +.cmb2-element.ui-datepicker td .ui-state-hover, .cmb2-element.ui-datepicker td .ui-state-active, .cmb2-element .ui-datepicker td .ui-state-hover, .cmb2-element .ui-datepicker td .ui-state-active { + background: #0073aa; + color: #fff; +} +.cmb2-element.ui-datepicker .ui-timepicker-div, .cmb2-element .ui-datepicker .ui-timepicker-div { + font-size: 14px; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl, .cmb2-element .ui-datepicker .ui-timepicker-div dl { + text-align: left; + padding: 0 .6em; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dt, .cmb2-element .ui-datepicker .ui-timepicker-div dl dt { + float: left; + clear: left; + padding: 0 0 0 5px; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd { + margin: 0 10px 10px 40%; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd select { + width: 100%; +} +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane { + padding: .6em; + text-align: left; +} +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary { + padding: 0 10px 1px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + margin: 0 .6em .4em .4em; +} + +.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +.admin-color-fresh .cmb2-element.ui-datepicker thead, .admin-color-fresh .cmb2-element .ui-datepicker thead { + background: #32373c; +} +.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #52accc; +} +.admin-color-blue .cmb2-element.ui-datepicker thead, .admin-color-blue .cmb2-element .ui-datepicker thead { + background: #4796b3; +} +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active { + background: #096484; + color: #fff; +} +.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #59524c; +} +.admin-color-coffee .cmb2-element.ui-datepicker thead, .admin-color-coffee .cmb2-element .ui-datepicker thead { + background: #46403c; +} +.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} +.admin-color-ectoplasm .cmb2-element.ui-datepicker thead, .admin-color-ectoplasm .cmb2-element .ui-datepicker thead { + background: #413256; +} +.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} +.admin-color-midnight .cmb2-element.ui-datepicker thead, .admin-color-midnight .cmb2-element .ui-datepicker thead { + background: #26292c; +} +.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #738e96; +} +.admin-color-ocean .cmb2-element.ui-datepicker thead, .admin-color-ocean .cmb2-element .ui-datepicker thead { + background: #627c83; +} +.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} +.admin-color-sunrise .cmb2-element.ui-datepicker th, .admin-color-sunrise .cmb2-element .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} +.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-light .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year, .admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year { + color: #555; +} +.admin-color-light .cmb2-element.ui-datepicker thead, .admin-color-light .cmb2-element .ui-datepicker thead { + background: #888; +} +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before, .admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before { + color: #555; +} +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-active { + background: #ccc; +} +.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #56b274; +} +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead { + background: #36533f; +} +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} +.admin-color-bbp-mint .cmb2-element.ui-datepicker thead, .admin-color-bbp-mint .cmb2-element .ui-datepicker thead { + background: #4f6d59; +} +.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} + +/** + * CMB2 Frontend + */ +/*-------------------------------------------------------------- + * CMB2 Frontend +--------------------------------------------------------------*/ +.closed .inside { + display: none; +} + +.cmb-repeatable-grouping { + position: relative; +} +.cmb-repeatable-grouping .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} +.cmb-repeatable-grouping h3 { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} + +.cmb-repeatable-group.repeatable .cmb-group-title { + padding-left: 2.2em; +} +.cmb-repeatable-group.non-repeatable .cmb-group-title { + padding-left: 12px; +} + +.cmb-type-group .cmb-row .cmbhandle { + right: 0; + position: absolute; +} + +.cmb-spinner { + background: url(images/spinner.gif) no-repeat; + -webkit-background-size: 20px 20px; + background-size: 20px 20px; + display: none; + float: right; + vertical-align: middle; + opacity: 0.7; + filter: alpha(opacity=70); + width: 20px; + height: 20px; + margin: 4px 10px 0; +} diff --git a/assets/cmb2/cmb2-display.css b/assets/cmb2/cmb2-display.css new file mode 100755 index 00000000..eafd9fd3 --- /dev/null +++ b/assets/cmb2/cmb2-display.css @@ -0,0 +1,31 @@ +/*-------------------------------------------------------------- + * CMB2 Display Styling +--------------------------------------------------------------*/ +.cmb2-colorpicker-swatch span { + display: inline-block; + width: 1em; + height: 1em; + border-radius: 1em; + float: left; + margin-top: 3px; + margin-right: 2px; +} + +.cmb2-code { + overflow: scroll; +} + +.cmb-image-display { + max-width: 100%; + height: auto; +} + +.cmb2-display-file-list li { + display: inline; + margin: 0 .5em .5em 0; +} + +.cmb2-oembed * { + max-width: 100%; + height: auto; +} diff --git a/assets/cmb2/cmb2-front.css b/assets/cmb2/cmb2-front.css new file mode 100755 index 00000000..87ac3bc6 --- /dev/null +++ b/assets/cmb2/cmb2-front.css @@ -0,0 +1,1303 @@ +@charset "UTF-8"; +.cmb2-uploader-files { + display: flex; + flex-wrap: wrap; +} +.cmb2-uploader-files > div { + width: 180px; + height: 130px; + overflow: hidden; +} +.cmb2-uploader-files .preview-image { + height: 100%; +} +.cmb2-uploader-files .preview-image img { + height: 100%; +} +.cmb2-uploader-files .button-placehold { + border: dashed 1px #ebebeb; + cursor: pointer; + text-align: center; +} +.cmb2-uploader-files .button-placehold i { + display: block; + font-size: 24px; + margin-bottom: 8px; +} +.cmb2-uploader-files .button-placehold .button-placehold-content { + position: relative; + top: 50%; + transform: translateY(-50%); +} +.cmb2-uploader-files input.select-file { + display: none; +} + +.uploader-item-preview { + position: relative; +} +.uploader-item-preview .btn-close { + position: absolute; + top: 4px; + right: 5px; + width: 15px; + height: 15px; + cursor: pointer; +} +.uploader-item-preview .btn-close:hover::before { + color: red; +} +.uploader-item-preview .btn-close::before { + content: '\f00d'; + font-family: Fontawesome; + transition: all .3s ease-in-out; +} +.uploader-item-preview .preview-icon { + padding-top: 4px; +} + +/*-------------------------------------------------------------- + * Main Wrap +--------------------------------------------------------------*/ +.cmb2-wrap { + margin: 0; +} +.cmb2-wrap input, +.cmb2-wrap textarea { + font-size: 14px; + max-width: 100%; + padding: 5px; +} +.cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +.cmb2-wrap textarea { + width: 500px; +} +.cmb2-wrap textarea.cmb2-textarea-code { + font-family: "Courier 10 Pitch", Courier, monospace; + line-height: 16px; +} +.cmb2-wrap input.cmb2-text-small, .cmb2-wrap input.cmb2-timepicker { + width: 100px; +} +.cmb2-wrap input.cmb2-text-money { + width: 90px; +} +.cmb2-wrap input.cmb2-text-medium { + width: 230px; +} +.cmb2-wrap input.cmb2-upload-file { + width: 65%; +} +.cmb2-wrap input.ed_button { + padding: 2px 4px; +} +.cmb2-wrap input:not([type="hidden"]) + input, +.cmb2-wrap input:not([type="hidden"]) + .button-secondary, +.cmb2-wrap input:not([type="hidden"]) + select { + margin-left: 20px; +} +.cmb2-wrap ul { + margin: 0; +} +.cmb2-wrap li { + font-size: 14px; + line-height: 16px; + margin: 1px 0 5px 0; +} +.cmb2-wrap select { + font-size: 14px; + margin-top: 3px; +} +.cmb2-wrap input:focus, +.cmb2-wrap textarea:focus { + background: #fffff8; +} +.cmb2-wrap input[type="radio"] { + margin: 0 5px 0 0; + padding: 0; +} +.cmb2-wrap input[type="checkbox"] { + margin: 0 5px 0 0; + padding: 0; +} +.cmb2-wrap .button-secondary { + color: #555; + border-color: #cccccc; + background: #f7f7f7; + box-shadow: 0 1px 0 #cccccc; + display: inline-block; + text-decoration: none; + font-size: 13px; + line-height: 26px; + height: 28px; + margin: 0; + padding: 0 10px 1px; + cursor: pointer; + border-width: 1px; + border-style: solid; + -webkit-appearance: none; + border-radius: 3px; + white-space: nowrap; + box-sizing: border-box; +} +.cmb2-wrap .button-secondary:hover { + background: #fafafa; + border-color: #999; + color: #23282d; +} +.cmb2-wrap .mceLayout { + border: 1px solid #e9e9e9 !important; +} +.cmb2-wrap .mceIframeContainer { + background: #ffffff; +} +.cmb2-wrap .meta_mce { + width: 97%; +} +.cmb2-wrap .meta_mce textarea { + width: 100%; +} +.cmb2-wrap .field-row-2 { + margin: 0 -15px; +} +.cmb2-wrap .field-row-2::after { + content: ""; + display: block; + clear: both; +} +.cmb2-wrap .field-row-2 .cmb-row { + display: block; + float: left; + width: 100%; + padding-left: 15px; + padding-right: 15px; +} +@media screen and (min-width: 768px) { + .cmb2-wrap .field-row-2 .cmb-row { + width: 50%; + } +} +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-input-wrap { + vertical-align: middle; +} +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-container { + margin: 0 10px 0 0; +} +.cmb2-wrap .cmb-row { + margin: 0; +} +.cmb2-wrap .cmb-row:after { + content: ''; + clear: both; + display: block; + width: 100%; +} +.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description { + padding-top: 0; + padding-bottom: 1em; +} + +.cmb2-metabox { + clear: both; + margin: 0; +} +.cmb2-metabox > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox > .cmb-row:first-of-type > .cmb-th, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-th { + border: 0; +} + +.cmb-add-row { + margin: 1.8em 0 0; +} + +.cmb-nested .cmb-td, +.cmb-repeatable-group .cmb-th, +.cmb-repeatable-group:first-of-type { + border: 0; +} + +.cmb-row:last-of-type, +.cmb2-wrap .cmb-row:last-of-type, +.cmb-repeatable-group:last-of-type { + border-bottom: 0; +} + +.cmb-repeatable-grouping { + border: 1px solid #e9e9e9; + padding: 0 1em; +} +.cmb-repeatable-grouping.cmb-row { + margin: 0 0 0.8em; +} + +.cmb-th { + color: #0a1938; + float: left; + font-weight: 500; + line-height: 1.2; + padding: 20px 10px 20px 0; + vertical-align: top; + width: 200px; +} +@media (max-width: 450px) { + .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; + } + .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; + } +} + +.cmb-td { + line-height: 1.3; + max-width: 100%; + padding: 15px 10px; + vertical-align: middle; +} + +.cmb-type-title .cmb-td { + padding: 0; +} + +.cmb-th label { + display: block; + padding: 5px 0; +} + +.cmb-th + .cmb-td { + float: left; +} + +.cmb-td .cmb-td { + padding-bottom: 1em; +} + +.cmb-remove-row { + text-align: right; +} + +.empty-row.hidden { + display: none; +} + +.cmb-repeat-table { + background-color: #fafafa; + border: 1px solid #e1e1e1; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row { + position: relative; + counter-increment: el; + margin: 0; + padding: 10px 10px 10px 50px; + border-bottom: none !important; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row + .cmb-repeat-row { + border-top: solid 1px #e9e9e9; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper { + outline: dashed 2px #e9e9e9 !important; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row:before { + content: counter(el); + display: block; + top: 0; + left: 0; + position: absolute; + width: 35px; + height: 100%; + line-height: 35px; + cursor: move; + color: #757575; + text-align: center; + border-right: solid 1px #e9e9e9; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td { + margin: 0; + padding: 0; +} +.cmb-repeat-table + .cmb-add-row { + margin: 0; +} +.cmb-repeat-table + .cmb-add-row:before { + content: ''; + width: 1px; + height: 1.6em; + display: block; + margin-left: 17px; + background-color: gainsboro; +} +.cmb-repeat-table .cmb-remove-row { + top: 7px; + right: 7px; + position: absolute; + width: auto; + margin-left: 0; + padding: 0 !important; + display: none; +} +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button { + font-size: 20px; + text-indent: -1000px; + overflow: hidden; + position: relative; + height: auto; + line-height: 1; + padding: 0 10px 0; +} +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button:before { + content: ""; + font-family: 'Dashicons'; + speak: none; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + margin: 0; + text-indent: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; +} +.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row { + display: block; +} + +.cmb-repeatable-group .cmb-th { + padding: 5px; +} +.cmb-repeatable-group .cmb-group-title { + background-color: #e9e9e9; + padding: 8px 12px 8px 2.2em; + margin: 0 -1em; + min-height: 1.5em; + font-size: 14px; + line-height: 1.4; +} +.cmb-repeatable-group .cmb-group-title h4 { + border: 0; + margin: 0; + font-size: 1.2em; + font-weight: 500; + padding: 0.5em 0.75em; +} +.cmb-repeatable-group .cmb-group-title .cmb-th { + display: block; + width: 100%; +} +.cmb-repeatable-group .cmb-group-description .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; +} +.cmb-repeatable-group .cmb-group-description .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} +.cmb-repeatable-group .cmb-shift-rows { + font-size: 1em; + margin-right: 1em; + text-decoration: none; +} +.cmb-repeatable-group .cmb-shift-rows .dashicons { + font-size: 1.5em; + height: 1.5em; + line-height: 1.2em; + width: 1em; +} +.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2 { + line-height: 1.3em; +} +.cmb-repeatable-group .cmb2-upload-button { + float: right; +} + +p.cmb2-metabox-description { + color: #757575; + font-style: italic; + margin: 0; + padding-top: .5em; +} + +span.cmb2-metabox-description { + color: #757575; + font-style: italic; +} + +.cmb2-metabox-title { + margin: 0 0 5px 0; + padding: 5px 0 0 0; + font-size: 14px; +} + +.cmb-inline ul { + padding: 4px 0 0 0; +} + +.cmb-inline li { + display: inline-block; + padding-right: 18px; +} + +.cmb-type-textarea-code pre { + margin: 0; +} + +.cmb2-media-status .img-status { + clear: none; + display: inline-block; + vertical-align: middle; + margin-right: 10px; + width: auto; +} +.cmb2-media-status .img-status img { + max-width: 350px; + height: auto; +} +.cmb2-media-status .img-status img, +.cmb2-media-status .embed-status { + background: #eee; + border: 5px solid #ffffff; + outline: 1px solid #e9e9e9; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.05); + background-image: linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0), linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; + border-radius: 2px; + -moz-border-radius: 2px; + margin: 15px 0 0 0; +} +.cmb2-media-status .embed-status { + float: left; + max-width: 800px; +} +.cmb2-media-status .img-status, .cmb2-media-status .embed-status { + position: relative; +} +.cmb2-media-status .img-status .cmb2-remove-file-button, .cmb2-media-status .embed-status .cmb2-remove-file-button { + background: url(../images/ico-delete.png); + height: 16px; + left: -5px; + position: absolute; + text-indent: -9999px; + top: -5px; + width: 16px; +} +.cmb2-media-status .img-status .cmb2-remove-file-button { + top: 10px; +} +.cmb2-media-status .img-status img, .cmb2-media-status .file-status > span { + cursor: pointer; +} +.cmb2-media-status.cmb-attach-list .img-status img, .cmb2-media-status.cmb-attach-list .file-status > span { + cursor: move; +} + +.cmb-type-file-list .cmb2-media-status .img-status { + clear: none; + vertical-align: middle; + width: auto; + margin-right: 10px; + margin-bottom: 10px; + margin-top: 0; +} + +.cmb-attach-list li { + clear: both; + display: inline-block; + width: 100%; + margin-top: 5px; + margin-bottom: 10px; +} +.cmb-attach-list li img { + float: left; + margin-right: 10px; +} + +.cmb2-remove-wrapper { + margin: 0; +} + +.child-cmb2 .cmb-th { + text-align: left; +} + +.cmb2-indented-hierarchy { + padding-left: 1.5em; +} + +@media (max-width: 450px) { + .cmb-th, + .cmb-td, + .cmb-th + .cmb-td { + display: block; + float: none; + width: 100%; + } +} +.opalestate-submission-form { + position: relative; +} +.opalestate-submission-form .cmb-td { + width: 100%; + padding: 15px 0; +} +.opalestate-submission-form .cmb-th { + width: 100%; + padding-bottom: 0; + padding-top: 15px; +} +.opalestate-submission-form .cmb-th label { + margin: 0; + padding: 0; +} +.opalestate-submission-form span.cmb2-metabox-description { + padding-top: .5em; + display: block; +} +.opalestate-submission-form .cmb2-wrap input.cmb2-text-medium, .opalestate-submission-form .cmb2-wrap input.cmb2-text-small { + width: 100%; +} +.opalestate-submission-form .opalestate-tab-content::after { + content: ''; + display: block; + clear: both; +} +@media screen and (min-width: 768px) { + .opalestate-submission-form .submission-next-btn { + float: right; + } +} +.opalestate-submission-form .btn-submit-cmb { + position: absolute; + bottom: 0px; + right: 0px; + padding: 19px 25px 17px 20px; +} +@media screen and (max-width: 767px) { + .opalestate-submission-form .btn-submit-cmb { + position: relative; + bottom: 0; + right: 0; + margin-top: 15px; + } +} +.opalestate-submission-form .btn-submit-cmb::before { + content: "\f138"; + font-family: Fontawesome; + margin-right: 18px; + padding-right: 20px; +} +.opalestate-submission-form .btn-submit-cmb::after { + content: ""; + width: 52px; + position: absolute; + top: 0; + left: 0; + height: 100%; + background-color: transparent; + -webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15); + box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15); +} +.opalestate-submission-form .submission-back-btn, .opalestate-submission-form .submission-next-btn, .opalestate-submission-form .submission-next-btn { + margin-top: 15px; +} +.opalestate-submission-form .cmb-repeatable-group .cmb-group-title { + font-size: 15px; +} +.opalestate-submission-form .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + top: .4em; +} +.opalestate-submission-form .cmb-type-group .field-row-2 .cmb-row { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; +} +.opalestate-submission-form .cmb-type-group .cmb-row { + padding-top: 15px; + padding-bottom: 15px; + margin-bottom: 15px; +} +.opalestate-submission-form .cmb-type-group .cmb-row.postbox { + padding-top: 0; + border-bottom: 1px solid #e9e9e9; +} +.opalestate-submission-form .cmb-type-group .cmb-th { + width: 100%; + padding: 0; + float: none; +} +.opalestate-submission-form .cmb-type-group .cmb-th + .cmb-td { + width: 100%; + float: none; + padding: 15px 0; +} + +/*-------------------------------------------------------------- + * Post Metaboxes +--------------------------------------------------------------*/ +#poststuff .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} + +#poststuff .repeatable .cmb-group-title { + padding-left: 2.2em; +} + +.cmb2-postbox .cmb2-wrap, .cmb-type-group .cmb2-wrap { + margin: 0; +} +.cmb2-postbox .cmb2-wrap > .cmb-field-list > .cmb-row, .cmb-type-group .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.8em 0; +} +.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed, .cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +.cmb2-postbox .cmb-row, .cmb-type-group .cmb-row { + padding: 0 0 1.8em; + margin: 0 0 0.8em; +} +.cmb2-postbox .cmb-row .cmbhandle, .cmb-type-group .cmb-row .cmbhandle { + right: -1em; + position: relative; + color: #222222; +} +.cmb2-postbox .cmb-repeatable-grouping, .cmb-type-group .cmb-repeatable-grouping { + padding: 0 1em; + max-width: 100%; + min-width: 1px !important; +} +.cmb2-postbox .cmb-repeatable-group > .cmb-row, .cmb-type-group .cmb-repeatable-group > .cmb-row { + padding-bottom: 0; +} +.cmb2-postbox .cmb-th, .cmb-type-group .cmb-th { + width: 18%; + padding: 0 2% 0 0; +} +.cmb2-postbox .cmb-td, .cmb-type-group .cmb-td { + margin-bottom: 0; + padding: 0; + line-height: 1.3; +} +.cmb2-postbox .cmb-th + .cmb-td, .cmb-type-group .cmb-th + .cmb-td { + width: 80%; + float: right; +} +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 1px solid #e9e9e9; +} +@media (max-width: 450px) { + .cmb2-postbox .cmb-row:not(:last-of-type), + .cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), + .cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 0; + } +} +.cmb2-postbox .cmb-repeat-group-field, +.cmb2-postbox .cmb-remove-field-row, .cmb-type-group .cmb-repeat-group-field, +.cmb-type-group .cmb-remove-field-row { + padding-top: 1.8em; +} + +/*-------------------------------------------------------------- + * Context Metaboxes +--------------------------------------------------------------*/ +/* Metabox collapse arrow indicators */ +.js .cmb2-postbox.context-box .toggle-indicator:before { + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.js .cmb2-postbox.context-box.closed .toggle-indicator:before { + content: "\f140"; +} + +.cmb2-postbox.context-box { + margin-bottom: 10px; +} +.cmb2-postbox.context-box.context-before_permalink-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-after_title-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-after_editor-box { + margin-top: 20px; + margin-bottom: 0; +} +.cmb2-postbox.context-box.context-form_top-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-form_top-box .hndle { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} +.cmb2-postbox.context-box .hndle { + cursor: auto; +} + +.cmb2-context-wrap { + margin-top: 10px; +} +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 300px; + width: auto; +} +.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox { + padding: 10px; +} +.cmb2-context-wrap .cmb-th { + padding: 0 2% 0 0; + width: 18%; +} +.cmb2-context-wrap .cmb-td { + width: 80%; + padding: 0; +} +.cmb2-context-wrap .cmb-row { + margin-bottom: 10px; +} +.cmb2-context-wrap .cmb-row:last-of-type { + margin-bottom: 0; +} + +/* one column on the post write/edit screen */ +@media only screen and (max-width: 850px) { + .cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 0; + } +} +/*-------------------------------------------------------------- + * Misc. +--------------------------------------------------------------*/ +#poststuff .cmb-repeatable-group h2 { + margin: 0; +} + +.edit-tags-php .cmb2-metabox-title, +.profile-php .cmb2-metabox-title, +.user-edit-php .cmb2-metabox-title { + font-size: 1.4em; +} + +.cmb2-postbox .cmb-spinner, .cmb2-no-box-wrap .cmb-spinner { + float: left; + display: none; +} + +.cmb-spinner { + display: none; +} +.cmb-spinner.is-active { + display: block; +} + +/*-------------------------------------------------------------- + * Collapsible UI +--------------------------------------------------------------*/ +.cmb2-metabox .cmbhandle { + color: #757575; + float: right; + width: 27px; + height: 30px; + cursor: pointer; + right: -1em; + position: relative; +} +.cmb2-metabox .cmbhandle:before { + content: '\f142'; + right: 12px; + font: normal 20px/1 'dashicons'; + speak: none; + display: inline-block; + padding: 8px 10px; + top: 0; + position: relative; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.cmb2-metabox .postbox.closed .cmbhandle:before { + content: '\f140'; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + -webkit-appearance: none !important; + background: none !important; + border: none !important; + position: absolute; + left: 0; + top: .5em; + line-height: 1em; + padding: 2px 6px 3px; + opacity: .5; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]) { + cursor: pointer; + color: #a00; + opacity: 1; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover { + color: #f00; +} + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress" + * https://github.com/stuttter/wp-datepicker-styling + * + */ +* html .cmb2-element.ui-helper-clearfix { + height: 1%; +} + +.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + /* Default Color Scheme */ +} +.cmb2-element.ui-datepicker *, .cmb2-element .ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.cmb2-element.ui-datepicker table, .cmb2-element .ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} +.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} +.cmb2-element.ui-datepicker .ui-datepicker-title, .cmb2-element .ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} +.cmb2-element.ui-datepicker .ui-datepicker-title select, .cmb2-element .ui-datepicker .ui-datepicker-title select { + margin-top: -8px; + margin-bottom: -8px; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-next { + position: relative; + top: 8px; + height: 34px; + width: 34px; +} +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next, .cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover { + left: 0; +} +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover, .cmb2-element .ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover { + right: 0; +} +.cmb2-element.ui-datepicker .ui-datepicker-next span, +.cmb2-element.ui-datepicker .ui-datepicker-prev span, .cmb2-element .ui-datepicker .ui-datepicker-next span, +.cmb2-element .ui-datepicker .ui-datepicker-prev span { + display: none; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, .cmb2-element .ui-datepicker .ui-datepicker-prev { + float: left; +} +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-next { + float: right; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-left: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before, .cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} +.cmb2-element.ui-datepicker select.ui-datepicker-month, +.cmb2-element.ui-datepicker select.ui-datepicker-year, .cmb2-element .ui-datepicker select.ui-datepicker-month, +.cmb2-element .ui-datepicker select.ui-datepicker-year { + width: 33%; + background: transparent; + border-color: transparent; + box-shadow: none; + color: #fff; + display: inline-block; +} +.cmb2-element.ui-datepicker select.ui-datepicker-month option, +.cmb2-element.ui-datepicker select.ui-datepicker-year option, .cmb2-element .ui-datepicker select.ui-datepicker-month option, +.cmb2-element .ui-datepicker select.ui-datepicker-year option { + color: #333; +} +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + color: #fff; + font-weight: 600; +} +.cmb2-element.ui-datepicker thead th, .cmb2-element .ui-datepicker thead th { + font-weight: normal; +} +.cmb2-element.ui-datepicker th, .cmb2-element .ui-datepicker th { + padding: 10px; +} +.cmb2-element.ui-datepicker td, .cmb2-element .ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} +.cmb2-element.ui-datepicker td.ui-datepicker-other-month, .cmb2-element .ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} +.cmb2-element.ui-datepicker td.ui-datepicker-week-end, .cmb2-element .ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} +.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today { + -webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); +} +.cmb2-element.ui-datepicker td.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} +.cmb2-element.ui-datepicker td.ui-datepicker-current-day, .cmb2-element .ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} +.cmb2-element.ui-datepicker td .ui-state-default, .cmb2-element .ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} +.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default, .cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + background: #32373c; +} +.cmb2-element.ui-datepicker td .ui-state-hover, .cmb2-element.ui-datepicker td .ui-state-active, .cmb2-element .ui-datepicker td .ui-state-hover, .cmb2-element .ui-datepicker td .ui-state-active { + background: #0073aa; + color: #fff; +} +.cmb2-element.ui-datepicker .ui-timepicker-div, .cmb2-element .ui-datepicker .ui-timepicker-div { + font-size: 14px; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl, .cmb2-element .ui-datepicker .ui-timepicker-div dl { + text-align: left; + padding: 0 .6em; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dt, .cmb2-element .ui-datepicker .ui-timepicker-div dl dt { + float: left; + clear: left; + padding: 0 0 0 5px; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd { + margin: 0 10px 10px 40%; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd select { + width: 100%; +} +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane { + padding: .6em; + text-align: left; +} +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary { + padding: 0 10px 1px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + margin: 0 .6em .4em .4em; +} + +.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +.admin-color-fresh .cmb2-element.ui-datepicker thead, .admin-color-fresh .cmb2-element .ui-datepicker thead { + background: #32373c; +} +.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #52accc; +} +.admin-color-blue .cmb2-element.ui-datepicker thead, .admin-color-blue .cmb2-element .ui-datepicker thead { + background: #4796b3; +} +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active { + background: #096484; + color: #fff; +} +.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #59524c; +} +.admin-color-coffee .cmb2-element.ui-datepicker thead, .admin-color-coffee .cmb2-element .ui-datepicker thead { + background: #46403c; +} +.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} +.admin-color-ectoplasm .cmb2-element.ui-datepicker thead, .admin-color-ectoplasm .cmb2-element .ui-datepicker thead { + background: #413256; +} +.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} +.admin-color-midnight .cmb2-element.ui-datepicker thead, .admin-color-midnight .cmb2-element .ui-datepicker thead { + background: #26292c; +} +.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #738e96; +} +.admin-color-ocean .cmb2-element.ui-datepicker thead, .admin-color-ocean .cmb2-element .ui-datepicker thead { + background: #627c83; +} +.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} +.admin-color-sunrise .cmb2-element.ui-datepicker th, .admin-color-sunrise .cmb2-element .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} +.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-light .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year, .admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year { + color: #555; +} +.admin-color-light .cmb2-element.ui-datepicker thead, .admin-color-light .cmb2-element .ui-datepicker thead { + background: #888; +} +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before, .admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before { + color: #555; +} +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-active { + background: #ccc; +} +.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #56b274; +} +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead { + background: #36533f; +} +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} +.admin-color-bbp-mint .cmb2-element.ui-datepicker thead, .admin-color-bbp-mint .cmb2-element .ui-datepicker thead { + background: #4f6d59; +} +.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} + +/** + * CMB2 Frontend + */ +/*-------------------------------------------------------------- + * CMB2 Frontend +--------------------------------------------------------------*/ +.closed .inside { + display: none; +} + +.cmb-repeatable-grouping { + position: relative; +} +.cmb-repeatable-grouping .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} +.cmb-repeatable-grouping h3 { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} + +.cmb-repeatable-group.repeatable .cmb-group-title { + padding-left: 2.2em; +} +.cmb-repeatable-group.non-repeatable .cmb-group-title { + padding-left: 12px; +} + +.cmb-type-group .cmb-row .cmbhandle { + right: 0; + position: absolute; +} + +.cmb-spinner { + background: url(images/spinner.gif) no-repeat; + -webkit-background-size: 20px 20px; + background-size: 20px 20px; + display: none; + float: right; + vertical-align: middle; + opacity: 0.7; + filter: alpha(opacity=70); + width: 20px; + height: 20px; + margin: 4px 10px 0; +} diff --git a/assets/cmb2/cmb2.css b/assets/cmb2/cmb2.css new file mode 100755 index 00000000..8c542993 --- /dev/null +++ b/assets/cmb2/cmb2.css @@ -0,0 +1,1277 @@ +@charset "UTF-8"; +/*-------------------------------------------------------------- + * Main Wrap +--------------------------------------------------------------*/ +.cmb2-wrap { + margin: 0; +} +.cmb2-wrap input, +.cmb2-wrap textarea { + font-size: 14px; + max-width: 100%; + padding: 5px; +} +.cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +.cmb2-wrap textarea { + width: 500px; +} +.cmb2-wrap textarea.cmb2-textarea-code { + font-family: "Courier 10 Pitch", Courier, monospace; + line-height: 16px; +} +.cmb2-wrap input.cmb2-text-small, .cmb2-wrap input.cmb2-timepicker { + width: 100px; +} +.cmb2-wrap input.cmb2-text-money { + width: 90px; +} +.cmb2-wrap input.cmb2-text-medium { + width: 230px; +} +.cmb2-wrap input.cmb2-upload-file { + width: 65%; +} +.cmb2-wrap input.ed_button { + padding: 2px 4px; +} +.cmb2-wrap input:not([type="hidden"]) + input, +.cmb2-wrap input:not([type="hidden"]) + .button-secondary, +.cmb2-wrap input:not([type="hidden"]) + select { + margin-left: 20px; +} +.cmb2-wrap ul { + margin: 0; +} +.cmb2-wrap li { + font-size: 14px; + line-height: 16px; + margin: 1px 0 5px 0; +} +.cmb2-wrap select { + font-size: 14px; + margin-top: 3px; +} +.cmb2-wrap input:focus, +.cmb2-wrap textarea:focus { + background: #fffff8; +} +.cmb2-wrap input[type="radio"] { + margin: 0 5px 0 0; + padding: 0; +} +.cmb2-wrap input[type="checkbox"] { + margin: 0 5px 0 0; + padding: 0; +} +.cmb2-wrap .button-secondary { + color: #555; + border-color: #cccccc; + background: #f7f7f7; + box-shadow: 0 1px 0 #cccccc; + display: inline-block; + text-decoration: none; + font-size: 13px; + line-height: 26px; + height: 28px; + margin: 0; + padding: 0 10px 1px; + cursor: pointer; + border-width: 1px; + border-style: solid; + -webkit-appearance: none; + border-radius: 3px; + white-space: nowrap; + box-sizing: border-box; +} +.cmb2-wrap .button-secondary:hover { + background: #fafafa; + border-color: #999; + color: #23282d; +} +.cmb2-wrap .mceLayout { + border: 1px solid #e9e9e9 !important; +} +.cmb2-wrap .mceIframeContainer { + background: #ffffff; +} +.cmb2-wrap .meta_mce { + width: 97%; +} +.cmb2-wrap .meta_mce textarea { + width: 100%; +} +.cmb2-wrap .field-row-2 { + margin: 0 -15px; +} +.cmb2-wrap .field-row-2::after { + content: ""; + display: block; + clear: both; +} +.cmb2-wrap .field-row-2 .cmb-row { + display: block; + float: left; + width: 100%; + padding-left: 15px; + padding-right: 15px; +} +@media screen and (min-width: 768px) { + .cmb2-wrap .field-row-2 .cmb-row { + width: 50%; + } +} +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-input-wrap { + vertical-align: middle; +} +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-container { + margin: 0 10px 0 0; +} +.cmb2-wrap .cmb-row { + margin: 0; +} +.cmb2-wrap .cmb-row:after { + content: ''; + clear: both; + display: block; + width: 100%; +} +.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description { + padding-top: 0; + padding-bottom: 1em; +} + +.cmb2-metabox { + clear: both; + margin: 0; +} +.cmb2-metabox > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox > .cmb-row:first-of-type > .cmb-th, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-th { + border: 0; +} + +.cmb-add-row { + margin: 1.8em 0 0; +} + +.cmb-nested .cmb-td, +.cmb-repeatable-group .cmb-th, +.cmb-repeatable-group:first-of-type { + border: 0; +} + +.cmb-row:last-of-type, +.cmb2-wrap .cmb-row:last-of-type, +.cmb-repeatable-group:last-of-type { + border-bottom: 0; +} + +.cmb-repeatable-grouping { + border: 1px solid #e9e9e9; + padding: 0 1em; +} +.cmb-repeatable-grouping.cmb-row { + margin: 0 0 0.8em; +} + +.cmb-th { + color: #0a1938; + float: left; + font-weight: 500; + line-height: 1.2; + padding: 20px 10px 20px 0; + vertical-align: top; + width: 200px; +} +@media (max-width: 450px) { + .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; + } + .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; + } +} + +.cmb-td { + line-height: 1.3; + max-width: 100%; + padding: 15px 10px; + vertical-align: middle; +} + +.cmb-type-title .cmb-td { + padding: 0; +} + +.cmb-th label { + display: block; + padding: 5px 0; +} + +.cmb-th + .cmb-td { + float: left; +} + +.cmb-td .cmb-td { + padding-bottom: 1em; +} + +.cmb-remove-row { + text-align: right; +} + +.empty-row.hidden { + display: none; +} + +.cmb-repeat-table { + background-color: #fafafa; + border: 1px solid #e1e1e1; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row { + position: relative; + counter-increment: el; + margin: 0; + padding: 10px 10px 10px 50px; + border-bottom: none !important; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row + .cmb-repeat-row { + border-top: solid 1px #e9e9e9; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper { + outline: dashed 2px #e9e9e9 !important; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row:before { + content: counter(el); + display: block; + top: 0; + left: 0; + position: absolute; + width: 35px; + height: 100%; + line-height: 35px; + cursor: move; + color: #757575; + text-align: center; + border-right: solid 1px #e9e9e9; +} +.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td { + margin: 0; + padding: 0; +} +.cmb-repeat-table + .cmb-add-row { + margin: 0; +} +.cmb-repeat-table + .cmb-add-row:before { + content: ''; + width: 1px; + height: 1.6em; + display: block; + margin-left: 17px; + background-color: gainsboro; +} +.cmb-repeat-table .cmb-remove-row { + top: 7px; + right: 7px; + position: absolute; + width: auto; + margin-left: 0; + padding: 0 !important; + display: none; +} +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button { + font-size: 20px; + text-indent: -1000px; + overflow: hidden; + position: relative; + height: auto; + line-height: 1; + padding: 0 10px 0; +} +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button:before { + content: ""; + font-family: 'Dashicons'; + speak: none; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + margin: 0; + text-indent: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; +} +.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row { + display: block; +} + +.cmb-repeatable-group .cmb-th { + padding: 5px; +} +.cmb-repeatable-group .cmb-group-title { + background-color: #e9e9e9; + padding: 8px 12px 8px 2.2em; + margin: 0 -1em; + min-height: 1.5em; + font-size: 14px; + line-height: 1.4; +} +.cmb-repeatable-group .cmb-group-title h4 { + border: 0; + margin: 0; + font-size: 1.2em; + font-weight: 500; + padding: 0.5em 0.75em; +} +.cmb-repeatable-group .cmb-group-title .cmb-th { + display: block; + width: 100%; +} +.cmb-repeatable-group .cmb-group-description .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; +} +.cmb-repeatable-group .cmb-group-description .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} +.cmb-repeatable-group .cmb-shift-rows { + font-size: 1em; + margin-right: 1em; + text-decoration: none; +} +.cmb-repeatable-group .cmb-shift-rows .dashicons { + font-size: 1.5em; + height: 1.5em; + line-height: 1.2em; + width: 1em; +} +.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2 { + line-height: 1.3em; +} +.cmb-repeatable-group .cmb2-upload-button { + float: right; +} + +p.cmb2-metabox-description { + color: #757575; + font-style: italic; + margin: 0; + padding-top: .5em; +} + +span.cmb2-metabox-description { + color: #757575; + font-style: italic; +} + +.cmb2-metabox-title { + margin: 0 0 5px 0; + padding: 5px 0 0 0; + font-size: 14px; +} + +.cmb-inline ul { + padding: 4px 0 0 0; +} + +.cmb-inline li { + display: inline-block; + padding-right: 18px; +} + +.cmb-type-textarea-code pre { + margin: 0; +} + +.cmb2-media-status .img-status { + clear: none; + display: inline-block; + vertical-align: middle; + margin-right: 10px; + width: auto; +} +.cmb2-media-status .img-status img { + max-width: 350px; + height: auto; +} +.cmb2-media-status .img-status img, +.cmb2-media-status .embed-status { + background: #eee; + border: 5px solid #ffffff; + outline: 1px solid #e9e9e9; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.05); + background-image: linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0), linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; + border-radius: 2px; + -moz-border-radius: 2px; + margin: 15px 0 0 0; +} +.cmb2-media-status .embed-status { + float: left; + max-width: 800px; +} +.cmb2-media-status .img-status, .cmb2-media-status .embed-status { + position: relative; +} +.cmb2-media-status .img-status .cmb2-remove-file-button, .cmb2-media-status .embed-status .cmb2-remove-file-button { + background: url(../images/ico-delete.png); + height: 16px; + left: -5px; + position: absolute; + text-indent: -9999px; + top: -5px; + width: 16px; +} +.cmb2-media-status .img-status .cmb2-remove-file-button { + top: 10px; +} +.cmb2-media-status .img-status img, .cmb2-media-status .file-status > span { + cursor: pointer; +} +.cmb2-media-status.cmb-attach-list .img-status img, .cmb2-media-status.cmb-attach-list .file-status > span { + cursor: move; +} + +.cmb-type-file-list .cmb2-media-status .img-status { + clear: none; + vertical-align: middle; + width: auto; + margin-right: 10px; + margin-bottom: 10px; + margin-top: 0; +} + +.cmb-attach-list li { + clear: both; + display: inline-block; + width: 100%; + margin-top: 5px; + margin-bottom: 10px; +} +.cmb-attach-list li img { + float: left; + margin-right: 10px; +} + +.cmb2-remove-wrapper { + margin: 0; +} + +.child-cmb2 .cmb-th { + text-align: left; +} + +.cmb2-indented-hierarchy { + padding-left: 1.5em; +} + +@media (max-width: 450px) { + .cmb-th, + .cmb-td, + .cmb-th + .cmb-td { + display: block; + float: none; + width: 100%; + } +} +.opalestate-submission-form { + position: relative; +} +.opalestate-submission-form .cmb-td { + width: 100%; + padding: 15px 0; +} +.opalestate-submission-form .cmb-th { + width: 100%; + padding-bottom: 0; + padding-top: 15px; +} +.opalestate-submission-form .cmb-th label { + margin: 0; + padding: 0; +} +.opalestate-submission-form span.cmb2-metabox-description { + padding-top: .5em; + display: block; +} +.opalestate-submission-form .cmb2-wrap input.cmb2-text-medium, .opalestate-submission-form .cmb2-wrap input.cmb2-text-small { + width: 100%; +} +.opalestate-submission-form .opalestate-tab-content::after { + content: ''; + display: block; + clear: both; +} +@media screen and (min-width: 768px) { + .opalestate-submission-form .submission-next-btn { + float: right; + } +} +.opalestate-submission-form .btn-submit-cmb { + position: absolute; + bottom: 0px; + right: 0px; + padding: 19px 25px 17px 20px; +} +@media screen and (max-width: 767px) { + .opalestate-submission-form .btn-submit-cmb { + position: relative; + bottom: 0; + right: 0; + margin-top: 15px; + } +} +.opalestate-submission-form .btn-submit-cmb::before { + content: "\f138"; + font-family: Fontawesome; + margin-right: 18px; + padding-right: 20px; +} +.opalestate-submission-form .btn-submit-cmb::after { + content: ""; + width: 52px; + position: absolute; + top: 0; + left: 0; + height: 100%; + background-color: transparent; + -webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15); + box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15); +} +.opalestate-submission-form .submission-back-btn, .opalestate-submission-form .submission-next-btn, .opalestate-submission-form .submission-next-btn { + margin-top: 15px; +} +.opalestate-submission-form .cmb-repeatable-group .cmb-group-title { + font-size: 15px; +} +.opalestate-submission-form .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + top: .4em; +} +.opalestate-submission-form .cmb-type-group .field-row-2 .cmb-row { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; +} +.opalestate-submission-form .cmb-type-group .cmb-row { + padding-top: 15px; + padding-bottom: 15px; + margin-bottom: 15px; +} +.opalestate-submission-form .cmb-type-group .cmb-row.postbox { + padding-top: 0; + border-bottom: 1px solid #e9e9e9; +} +.opalestate-submission-form .cmb-type-group .cmb-th { + width: 100%; + padding: 0; + float: none; +} +.opalestate-submission-form .cmb-type-group .cmb-th + .cmb-td { + width: 100%; + float: none; + padding: 15px 0; +} + +/*-------------------------------------------------------------- + * Post Metaboxes +--------------------------------------------------------------*/ +#poststuff .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} + +#poststuff .repeatable .cmb-group-title { + padding-left: 2.2em; +} + +.cmb2-postbox .cmb2-wrap, .cmb-type-group .cmb2-wrap { + margin: 0; +} +.cmb2-postbox .cmb2-wrap > .cmb-field-list > .cmb-row, .cmb-type-group .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.8em 0; +} +.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed, .cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +.cmb2-postbox .cmb-row, .cmb-type-group .cmb-row { + padding: 0 0 1.8em; + margin: 0 0 0.8em; +} +.cmb2-postbox .cmb-row .cmbhandle, .cmb-type-group .cmb-row .cmbhandle { + right: -1em; + position: relative; + color: #222222; +} +.cmb2-postbox .cmb-repeatable-grouping, .cmb-type-group .cmb-repeatable-grouping { + padding: 0 1em; + max-width: 100%; + min-width: 1px !important; +} +.cmb2-postbox .cmb-repeatable-group > .cmb-row, .cmb-type-group .cmb-repeatable-group > .cmb-row { + padding-bottom: 0; +} +.cmb2-postbox .cmb-th, .cmb-type-group .cmb-th { + width: 18%; + padding: 0 2% 0 0; +} +.cmb2-postbox .cmb-td, .cmb-type-group .cmb-td { + margin-bottom: 0; + padding: 0; + line-height: 1.3; +} +.cmb2-postbox .cmb-th + .cmb-td, .cmb-type-group .cmb-th + .cmb-td { + width: 80%; + float: right; +} +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 1px solid #e9e9e9; +} +@media (max-width: 450px) { + .cmb2-postbox .cmb-row:not(:last-of-type), + .cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), + .cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 0; + } +} +.cmb2-postbox .cmb-repeat-group-field, +.cmb2-postbox .cmb-remove-field-row, .cmb-type-group .cmb-repeat-group-field, +.cmb-type-group .cmb-remove-field-row { + padding-top: 1.8em; +} + +/*-------------------------------------------------------------- + * Context Metaboxes +--------------------------------------------------------------*/ +/* Metabox collapse arrow indicators */ +.js .cmb2-postbox.context-box .toggle-indicator:before { + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.js .cmb2-postbox.context-box.closed .toggle-indicator:before { + content: "\f140"; +} + +.cmb2-postbox.context-box { + margin-bottom: 10px; +} +.cmb2-postbox.context-box.context-before_permalink-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-after_title-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-after_editor-box { + margin-top: 20px; + margin-bottom: 0; +} +.cmb2-postbox.context-box.context-form_top-box { + margin-top: 10px; +} +.cmb2-postbox.context-box.context-form_top-box .hndle { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} +.cmb2-postbox.context-box .hndle { + cursor: auto; +} + +.cmb2-context-wrap { + margin-top: 10px; +} +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 300px; + width: auto; +} +.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox { + padding: 10px; +} +.cmb2-context-wrap .cmb-th { + padding: 0 2% 0 0; + width: 18%; +} +.cmb2-context-wrap .cmb-td { + width: 80%; + padding: 0; +} +.cmb2-context-wrap .cmb-row { + margin-bottom: 10px; +} +.cmb2-context-wrap .cmb-row:last-of-type { + margin-bottom: 0; +} + +/* one column on the post write/edit screen */ +@media only screen and (max-width: 850px) { + .cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 0; + } +} +/*-------------------------------------------------------------- + * Options page +--------------------------------------------------------------*/ +.cmb2-options-page { + max-width: 1200px; +} +.cmb2-options-page.wrap > h2 { + margin-bottom: 1em; +} +.cmb2-options-page .cmb2-metabox > .cmb-row { + padding: 1em; + margin-top: -1px; + background: #ffffff; + border: 1px solid #e9e9e9; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th { + padding: 0; + font-weight: initial; +} +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th + .cmb-td { + float: none; + padding: 0 0 0 1em; + margin-left: 200px; +} +@media (max-width: 450px) { + .cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th + .cmb-td { + padding: 0; + margin-left: 0; + } +} +.cmb2-options-page .cmb2-wrap .cmb-type-title { + margin-top: 1em; + padding: 0.6em 1em; + background-color: #fafafa; +} +.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-title { + font-size: 12px; + margin-top: 0; + margin-bottom: 0; + text-transform: uppercase; +} +.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-description { + padding-top: 0.25em; +} +.cmb2-options-page .cmb-repeatable-group .cmb-group-description .cmb-th { + padding: 0 0 0.8em 0; +} +.cmb2-options-page .cmb-repeatable-group .cmb-group-name { + font-size: 16px; + margin-top: 0; + margin-bottom: 0; +} +.cmb2-options-page .cmb-repeatable-group .cmb-th > .cmb2-metabox-description { + font-weight: 400; + padding-bottom: 0 !important; +} + +/*-------------------------------------------------------------- + * New-Term Page +--------------------------------------------------------------*/ +#addtag .cmb-th { + float: none; + width: auto; + padding: 20px 0 0; +} +#addtag .cmb-td { + padding: 0; +} +#addtag .cmb-th + .cmb-td { + float: none; +} +#addtag select { + max-width: 100%; +} +#addtag .cmb2-metabox { + padding-bottom: 20px; +} +#addtag .cmb-row li label { + display: inline; +} + +/*-------------------------------------------------------------- + * Misc. +--------------------------------------------------------------*/ +#poststuff .cmb-repeatable-group h2 { + margin: 0; +} + +.edit-tags-php .cmb2-metabox-title, +.profile-php .cmb2-metabox-title, +.user-edit-php .cmb2-metabox-title { + font-size: 1.4em; +} + +.cmb2-postbox .cmb-spinner, .cmb2-no-box-wrap .cmb-spinner { + float: left; + display: none; +} + +.cmb-spinner { + display: none; +} +.cmb-spinner.is-active { + display: block; +} + +/*-------------------------------------------------------------- + * Collapsible UI +--------------------------------------------------------------*/ +.cmb2-metabox .cmbhandle { + color: #757575; + float: right; + width: 27px; + height: 30px; + cursor: pointer; + right: -1em; + position: relative; +} +.cmb2-metabox .cmbhandle:before { + content: '\f142'; + right: 12px; + font: normal 20px/1 'dashicons'; + speak: none; + display: inline-block; + padding: 8px 10px; + top: 0; + position: relative; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.cmb2-metabox .postbox.closed .cmbhandle:before { + content: '\f140'; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + -webkit-appearance: none !important; + background: none !important; + border: none !important; + position: absolute; + left: 0; + top: .5em; + line-height: 1em; + padding: 2px 6px 3px; + opacity: .5; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]) { + cursor: pointer; + color: #a00; + opacity: 1; +} +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover { + color: #f00; +} + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress" + * https://github.com/stuttter/wp-datepicker-styling + * + */ +* html .cmb2-element.ui-helper-clearfix { + height: 1%; +} + +.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + /* Default Color Scheme */ +} +.cmb2-element.ui-datepicker *, .cmb2-element .ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.cmb2-element.ui-datepicker table, .cmb2-element .ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} +.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} +.cmb2-element.ui-datepicker .ui-datepicker-title, .cmb2-element .ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} +.cmb2-element.ui-datepicker .ui-datepicker-title select, .cmb2-element .ui-datepicker .ui-datepicker-title select { + margin-top: -8px; + margin-bottom: -8px; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-next { + position: relative; + top: 8px; + height: 34px; + width: 34px; +} +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next, .cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover { + left: 0; +} +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover, .cmb2-element .ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover { + right: 0; +} +.cmb2-element.ui-datepicker .ui-datepicker-next span, +.cmb2-element.ui-datepicker .ui-datepicker-prev span, .cmb2-element .ui-datepicker .ui-datepicker-next span, +.cmb2-element .ui-datepicker .ui-datepicker-prev span { + display: none; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev, .cmb2-element .ui-datepicker .ui-datepicker-prev { + float: left; +} +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-next { + float: right; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-left: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before, .cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} +.cmb2-element.ui-datepicker select.ui-datepicker-month, +.cmb2-element.ui-datepicker select.ui-datepicker-year, .cmb2-element .ui-datepicker select.ui-datepicker-month, +.cmb2-element .ui-datepicker select.ui-datepicker-year { + width: 33%; + background: transparent; + border-color: transparent; + box-shadow: none; + color: #fff; + display: inline-block; +} +.cmb2-element.ui-datepicker select.ui-datepicker-month option, +.cmb2-element.ui-datepicker select.ui-datepicker-year option, .cmb2-element .ui-datepicker select.ui-datepicker-month option, +.cmb2-element .ui-datepicker select.ui-datepicker-year option { + color: #333; +} +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + color: #fff; + font-weight: 600; +} +.cmb2-element.ui-datepicker thead th, .cmb2-element .ui-datepicker thead th { + font-weight: normal; +} +.cmb2-element.ui-datepicker th, .cmb2-element .ui-datepicker th { + padding: 10px; +} +.cmb2-element.ui-datepicker td, .cmb2-element .ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} +.cmb2-element.ui-datepicker td.ui-datepicker-other-month, .cmb2-element .ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} +.cmb2-element.ui-datepicker td.ui-datepicker-week-end, .cmb2-element .ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} +.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today { + -webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); +} +.cmb2-element.ui-datepicker td.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} +.cmb2-element.ui-datepicker td.ui-datepicker-current-day, .cmb2-element .ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} +.cmb2-element.ui-datepicker td .ui-state-default, .cmb2-element .ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} +.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default, .cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + background: #32373c; +} +.cmb2-element.ui-datepicker td .ui-state-hover, .cmb2-element.ui-datepicker td .ui-state-active, .cmb2-element .ui-datepicker td .ui-state-hover, .cmb2-element .ui-datepicker td .ui-state-active { + background: #0073aa; + color: #fff; +} +.cmb2-element.ui-datepicker .ui-timepicker-div, .cmb2-element .ui-datepicker .ui-timepicker-div { + font-size: 14px; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl, .cmb2-element .ui-datepicker .ui-timepicker-div dl { + text-align: left; + padding: 0 .6em; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dt, .cmb2-element .ui-datepicker .ui-timepicker-div dl dt { + float: left; + clear: left; + padding: 0 0 0 5px; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd { + margin: 0 10px 10px 40%; +} +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd select { + width: 100%; +} +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane { + padding: .6em; + text-align: left; +} +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary { + padding: 0 10px 1px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + margin: 0 .6em .4em .4em; +} + +.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +.admin-color-fresh .cmb2-element.ui-datepicker thead, .admin-color-fresh .cmb2-element .ui-datepicker thead { + background: #32373c; +} +.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #52accc; +} +.admin-color-blue .cmb2-element.ui-datepicker thead, .admin-color-blue .cmb2-element .ui-datepicker thead { + background: #4796b3; +} +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active { + background: #096484; + color: #fff; +} +.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #59524c; +} +.admin-color-coffee .cmb2-element.ui-datepicker thead, .admin-color-coffee .cmb2-element .ui-datepicker thead { + background: #46403c; +} +.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} +.admin-color-ectoplasm .cmb2-element.ui-datepicker thead, .admin-color-ectoplasm .cmb2-element .ui-datepicker thead { + background: #413256; +} +.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} +.admin-color-midnight .cmb2-element.ui-datepicker thead, .admin-color-midnight .cmb2-element .ui-datepicker thead { + background: #26292c; +} +.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #738e96; +} +.admin-color-ocean .cmb2-element.ui-datepicker thead, .admin-color-ocean .cmb2-element .ui-datepicker thead { + background: #627c83; +} +.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} +.admin-color-sunrise .cmb2-element.ui-datepicker th, .admin-color-sunrise .cmb2-element .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} +.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-light .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year, .admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year { + color: #555; +} +.admin-color-light .cmb2-element.ui-datepicker thead, .admin-color-light .cmb2-element .ui-datepicker thead { + background: #888; +} +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before, .admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before { + color: #555; +} +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-active { + background: #ccc; +} +.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #56b274; +} +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead { + background: #36533f; +} +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} +.admin-color-bbp-mint .cmb2-element.ui-datepicker thead, .admin-color-bbp-mint .cmb2-element .ui-datepicker thead { + background: #4f6d59; +} +.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} diff --git a/assets/font-awesome.min.css b/assets/font-awesome.min.css new file mode 100755 index 00000000..640a2fde --- /dev/null +++ b/assets/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('fonts/fontawesome-webfont.eot?v=4.6.3');src:url('fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'),url('fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'),url('fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'),url('fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'),url('fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/assets/hint.min.css b/assets/hint.min.css new file mode 100755 index 00000000..76edc4e8 --- /dev/null +++ b/assets/hint.min.css @@ -0,0 +1,5 @@ +/*! Hint.css - v2.6.0 - 2019-04-27 +* http://kushagragour.in/lab/hint/ +* Copyright (c) 2019 Kushagra Gour */ + +[class*=hint--]{position:relative;display:inline-block}[class*=hint--]:after,[class*=hint--]:before{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translate3d(0,0,0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0s;-moz-transition-delay:0s;transition-delay:0s}[class*=hint--]:hover:after,[class*=hint--]:hover:before{visibility:visible;opacity:1;-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}[class*=hint--]:before{content:'';position:absolute;background:0 0;border:6px solid transparent;z-index:1000001}[class*=hint--]:after{background:#383838;color:#fff;padding:8px 10px;font-size:12px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap;text-shadow:0 -1px 0 #000;box-shadow:4px 4px 8px rgba(0,0,0,.3)}[class*=hint--][aria-label]:after{content:attr(aria-label)}[class*=hint--][data-hint]:after{content:attr(data-hint)}[aria-label='']:after,[aria-label='']:before,[data-hint='']:after,[data-hint='']:before{display:none!important}.hint--top-left:before,.hint--top-right:before,.hint--top:before{border-top-color:#383838}.hint--bottom-left:before,.hint--bottom-right:before,.hint--bottom:before{border-bottom-color:#383838}.hint--top:after,.hint--top:before{bottom:100%;left:50%}.hint--top:before{margin-bottom:-11px;left:calc(50% - 6px)}.hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translateX(-50%)}.hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}.hint--bottom:after,.hint--bottom:before{top:100%;left:50%}.hint--bottom:before{margin-top:-11px;left:calc(50% - 6px)}.hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translateX(-50%)}.hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}.hint--right:before{border-right-color:#383838;margin-left:-11px;margin-bottom:-6px}.hint--right:after{margin-bottom:-14px}.hint--right:after,.hint--right:before{left:100%;bottom:50%}.hint--right:hover:after,.hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--left:before{border-left-color:#383838;margin-right:-11px;margin-bottom:-6px}.hint--left:after{margin-bottom:-14px}.hint--left:after,.hint--left:before{right:100%;bottom:50%}.hint--left:hover:after,.hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--top-left:after,.hint--top-left:before{bottom:100%;left:50%}.hint--top-left:before{margin-bottom:-11px;left:calc(50% - 6px)}.hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translateX(-100%);margin-left:12px}.hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translateX(-100%) translateY(-8px)}.hint--top-right:after,.hint--top-right:before{bottom:100%;left:50%}.hint--top-right:before{margin-bottom:-11px;left:calc(50% - 6px)}.hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0);margin-left:-12px}.hint--top-right:hover:after,.hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--bottom-left:after,.hint--bottom-left:before{top:100%;left:50%}.hint--bottom-left:before{margin-top:-11px;left:calc(50% - 6px)}.hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translateX(-100%);margin-left:12px}.hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translateX(-100%) translateY(8px)}.hint--bottom-right:after,.hint--bottom-right:before{top:100%;left:50%}.hint--bottom-right:before{margin-top:-11px;left:calc(50% - 6px)}.hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0);margin-left:-12px}.hint--bottom-right:hover:after,.hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--large:after,.hint--medium:after,.hint--small:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.hint--small:after{width:80px}.hint--medium:after{width:150px}.hint--large:after{width:300px}.hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0 #592726}.hint--error.hint--top-left:before,.hint--error.hint--top-right:before,.hint--error.hint--top:before{border-top-color:#b34e4d}.hint--error.hint--bottom-left:before,.hint--error.hint--bottom-right:before,.hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.hint--error.hint--left:before{border-left-color:#b34e4d}.hint--error.hint--right:before{border-right-color:#b34e4d}.hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0 #6c5328}.hint--warning.hint--top-left:before,.hint--warning.hint--top-right:before,.hint--warning.hint--top:before{border-top-color:#c09854}.hint--warning.hint--bottom-left:before,.hint--warning.hint--bottom-right:before,.hint--warning.hint--bottom:before{border-bottom-color:#c09854}.hint--warning.hint--left:before{border-left-color:#c09854}.hint--warning.hint--right:before{border-right-color:#c09854}.hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0 #1a3c4d}.hint--info.hint--top-left:before,.hint--info.hint--top-right:before,.hint--info.hint--top:before{border-top-color:#3986ac}.hint--info.hint--bottom-left:before,.hint--info.hint--bottom-right:before,.hint--info.hint--bottom:before{border-bottom-color:#3986ac}.hint--info.hint--left:before{border-left-color:#3986ac}.hint--info.hint--right:before{border-right-color:#3986ac}.hint--success:after{background-color:#458746;text-shadow:0 -1px 0 #1a321a}.hint--success.hint--top-left:before,.hint--success.hint--top-right:before,.hint--success.hint--top:before{border-top-color:#458746}.hint--success.hint--bottom-left:before,.hint--success.hint--bottom-right:before,.hint--success.hint--bottom:before{border-bottom-color:#458746}.hint--success.hint--left:before{border-left-color:#458746}.hint--success.hint--right:before{border-right-color:#458746}.hint--always:after,.hint--always:before{opacity:1;visibility:visible}.hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}.hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translateX(-100%) translateY(-8px)}.hint--always.hint--top-right:after,.hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}.hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translateX(-100%) translateY(8px)}.hint--always.hint--bottom-right:after,.hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--left:after,.hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--always.hint--right:after,.hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--rounded:after{border-radius:4px}.hint--no-animate:after,.hint--no-animate:before{-webkit-transition-duration:0s;-moz-transition-duration:0s;transition-duration:0s}.hint--bounce:after,.hint--bounce:before{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.hint--no-shadow:after,.hint--no-shadow:before{text-shadow:initial;box-shadow:initial} \ No newline at end of file diff --git a/assets/images/1.png b/assets/images/1.png new file mode 100755 index 00000000..fe0b9591 Binary files /dev/null and b/assets/images/1.png differ diff --git a/assets/images/10.png b/assets/images/10.png new file mode 100755 index 00000000..db5b9aa2 Binary files /dev/null and b/assets/images/10.png differ diff --git a/assets/images/11.png b/assets/images/11.png new file mode 100755 index 00000000..80e5c123 Binary files /dev/null and b/assets/images/11.png differ diff --git a/assets/images/12.png b/assets/images/12.png new file mode 100755 index 00000000..f64c581d Binary files /dev/null and b/assets/images/12.png differ diff --git a/assets/images/13.png b/assets/images/13.png new file mode 100755 index 00000000..6792b775 Binary files /dev/null and b/assets/images/13.png differ diff --git a/assets/images/14.png b/assets/images/14.png new file mode 100755 index 00000000..2e809f03 Binary files /dev/null and b/assets/images/14.png differ diff --git a/assets/images/15.png b/assets/images/15.png new file mode 100755 index 00000000..b8684092 Binary files /dev/null and b/assets/images/15.png differ diff --git a/assets/images/16.png b/assets/images/16.png new file mode 100755 index 00000000..128cd55a Binary files /dev/null and b/assets/images/16.png differ diff --git a/assets/images/17.png b/assets/images/17.png new file mode 100755 index 00000000..f6ff60b1 Binary files /dev/null and b/assets/images/17.png differ diff --git a/assets/images/18.png b/assets/images/18.png new file mode 100755 index 00000000..defbb7b9 Binary files /dev/null and b/assets/images/18.png differ diff --git a/assets/images/19.png b/assets/images/19.png new file mode 100755 index 00000000..a6182320 Binary files /dev/null and b/assets/images/19.png differ diff --git a/assets/images/2.png b/assets/images/2.png new file mode 100755 index 00000000..9551de86 Binary files /dev/null and b/assets/images/2.png differ diff --git a/assets/images/3.png b/assets/images/3.png new file mode 100755 index 00000000..6eeb89bb Binary files /dev/null and b/assets/images/3.png differ diff --git a/assets/images/4.png b/assets/images/4.png new file mode 100755 index 00000000..870f66b7 Binary files /dev/null and b/assets/images/4.png differ diff --git a/assets/images/5.png b/assets/images/5.png new file mode 100755 index 00000000..109d0731 Binary files /dev/null and b/assets/images/5.png differ diff --git a/assets/images/6.png b/assets/images/6.png new file mode 100755 index 00000000..5c69843b Binary files /dev/null and b/assets/images/6.png differ diff --git a/assets/images/7.png b/assets/images/7.png new file mode 100755 index 00000000..48c6ae0f Binary files /dev/null and b/assets/images/7.png differ diff --git a/assets/images/8.png b/assets/images/8.png new file mode 100755 index 00000000..8ba6e15e Binary files /dev/null and b/assets/images/8.png differ diff --git a/assets/images/9.png b/assets/images/9.png new file mode 100755 index 00000000..0d69dfda Binary files /dev/null and b/assets/images/9.png differ diff --git a/assets/images/avatar-placeholder.jpg b/assets/images/avatar-placeholder.jpg new file mode 100644 index 00000000..8a23176c Binary files /dev/null and b/assets/images/avatar-placeholder.jpg differ diff --git a/assets/images/placeholder.png b/assets/images/placeholder.png new file mode 100644 index 00000000..65285249 Binary files /dev/null and b/assets/images/placeholder.png differ diff --git a/assets/images/spinner.gif b/assets/images/spinner.gif new file mode 100755 index 00000000..88e8a939 Binary files /dev/null and b/assets/images/spinner.gif differ diff --git a/assets/images/walk-score.png b/assets/images/walk-score.png new file mode 100644 index 00000000..88fca7d8 Binary files /dev/null and b/assets/images/walk-score.png differ diff --git a/assets/js/admin.js b/assets/js/admin.js new file mode 100755 index 00000000..afd1e589 --- /dev/null +++ b/assets/js/admin.js @@ -0,0 +1,157 @@ +jQuery(document).ready(function($){ + + /// apply select2 style + $('select.cmb2_select').select2( { + + } ); + + function load_select2_member ( id, action ) { + $( id ).select2({ + width: '100%', + ajax: { + url: ajaxurl+"?action="+action, + dataType: 'json', + delay: 250, + data: function (params) { + return { + q: params.term, // search term + page: params.page + }; + }, + processResults: function (data, params) { + params.page = params.page || 1; + + return { + results: data.items, + pagination: { + more: (params.page * 30) < data.total_count + } + }; + }, + cache: true + }, + placeholder: 'Search for a repository', + escapeMarkup: function (markup) { return markup; }, // let our custom formatter work + minimumInputLength: 1, + templateResult: formatRepo, + templateSelection: formatRepoSelection + }); + } + load_select2_member( '#opalestate_ppt_agent', 'opalestate_search_agents' ); + load_select2_member( '#opalestate_ppt_agency', 'opalestate_search_agencies' ); + load_select2_member( '#p-assignment #post_author_override', 'opalestate_search_property_users' ); + + function formatRepo (repo) { + if ( repo.loading ) { + return repo.text; + } + var markup = "
            " + + "
            " + + "
            " + + "
            " + repo.full_name + "
            "; + markup += "
            "; + return markup; + } + + function formatRepoSelection (repo) { + return repo.full_name || repo.text; + } + + // Ajax user search + $('.opalestate-ajax-user-search').on('keyup', function () { + var user_search = $(this).val(); + var exclude = ''; + + if ($(this).data('exclude')) { + exclude = $(this).data('exclude'); + } + + $('.opalestate-ajax').show(); + data = { + action: 'opalestate_search_users', + user_name: user_search, + exclude: exclude + }; + + document.body.style.cursor = 'wait'; + + $.ajax({ + type: "POST", + data: data, + dataType: "json", + url: ajaxurl, + success: function (search_response) { + $('.opalestate-ajax').hide(); + $('.opalestate_user_search_results').removeClass('hidden'); + $('.opalestate_user_search_results span').html(''); + $(search_response.results).appendTo('.opalestate_user_search_results span'); + document.body.style.cursor = 'default'; + } + }); + }); + + $('body').on('click.opalestateSelectUser', '.opalestate_user_search_results span a', function (e) { + e.preventDefault(); + var login = $(this).data('login'); + $('.opalestate-ajax-user-search').val(login); + $('.opalestate_user_search_results').addClass('hidden'); + $('.opalestate_user_search_results span').html(''); + }); + + $('body').on('click.opalestateCancelUserSearch', '.opalestate_user_search_results a.opalestate-ajax-user-cancel', function (e) { + e.preventDefault(); + $('.opalestate-ajax-user-search').val(''); + $('.opalestate_user_search_results').addClass('hidden'); + $('.opalestate_user_search_results span').html(''); + }); + + /** + * + */ + function open_media( field ){ + + var media = wp.media({ + title: 'Choose an image', + button: { + text: 'Select' + }, + multiple: false + }); + + media.open(); + + media.on( 'select', function(){ + var selection = media.state().get('selection'); + + var attachment = selection.first().toJSON(); + + //var attach = wp.media.attachment( cmb.attach_id ); + // attach.fetch(); + // selection.set( attach ? [ attach ] : [] ); + $( 'input', field).val( attachment.id ); + + if( $(field.data('related')).length > 0 ){ + $(field.data('related')).attr('src', attachment.url ); + }else if( $( 'img' , field ).length > 0 ){ + $( 'img', field).attr('src', attachment.url ); + } + } ) + .on( 'open', function(){ + + } ); + + } + $( '.media-view-upload-button' ).click( function () { + var field = $( this ).parent(); + open_media( field ); + } ); + + $( '.media-view-remove-button' ).click( function () { + var field = $( this ).parent(); + $( 'input', field).val( '' ); + $( 'img', field).attr('src', $( 'img', field).data('placeholder') ); + } ); + /** + * + */ +}); diff --git a/assets/js/chart.min.js b/assets/js/chart.min.js new file mode 100755 index 00000000..c74a7914 --- /dev/null +++ b/assets/js/chart.min.js @@ -0,0 +1,7 @@ +/*! + * Chart.js v2.8.0 + * https://www.chartjs.org + * (c) 2019 Chart.js Contributors + * Released under the MIT License + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],function(t){return e(function(){try{return t("moment")}catch(t){}}())}):t.Chart=e(t.moment)}(this,function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={rgb2hsl:i,rgb2hsv:n,rgb2hwb:a,rgb2cmyk:o,rgb2keyword:s,rgb2xyz:l,rgb2lab:d,rgb2lch:function(t){return x(d(t))},hsl2rgb:u,hsl2hsv:function(t){var e=t[0],i=t[1]/100,n=t[2]/100;if(0===n)return[0,0,0];return[e,100*(2*(i*=(n*=2)<=1?n:2-n)/(n+i)),100*((n+i)/2)]},hsl2hwb:function(t){return a(u(t))},hsl2cmyk:function(t){return o(u(t))},hsl2keyword:function(t){return s(u(t))},hsv2rgb:h,hsv2hsl:function(t){var e,i,n=t[0],a=t[1]/100,o=t[2]/100;return e=a*o,[n,100*(e=(e/=(i=(2-a)*o)<=1?i:2-i)||0),100*(i/=2)]},hsv2hwb:function(t){return a(h(t))},hsv2cmyk:function(t){return o(h(t))},hsv2keyword:function(t){return s(h(t))},hwb2rgb:c,hwb2hsl:function(t){return i(c(t))},hwb2hsv:function(t){return n(c(t))},hwb2cmyk:function(t){return o(c(t))},hwb2keyword:function(t){return s(c(t))},cmyk2rgb:f,cmyk2hsl:function(t){return i(f(t))},cmyk2hsv:function(t){return n(f(t))},cmyk2hwb:function(t){return a(f(t))},cmyk2keyword:function(t){return s(f(t))},keyword2rgb:w,keyword2hsl:function(t){return i(w(t))},keyword2hsv:function(t){return n(w(t))},keyword2hwb:function(t){return a(w(t))},keyword2cmyk:function(t){return o(w(t))},keyword2lab:function(t){return d(w(t))},keyword2xyz:function(t){return l(w(t))},xyz2rgb:p,xyz2lab:m,xyz2lch:function(t){return x(m(t))},lab2xyz:v,lab2rgb:y,lab2lch:x,lch2lab:k,lch2xyz:function(t){return v(k(t))},lch2rgb:function(t){return y(k(t))}};function i(t){var e,i,n=t[0]/255,a=t[1]/255,o=t[2]/255,r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),i=(r+s)/2,[e,100*(s==r?0:i<=.5?l/(s+r):l/(2-s-r)),100*i]}function n(t){var e,i,n=t[0],a=t[1],o=t[2],r=Math.min(n,a,o),s=Math.max(n,a,o),l=s-r;return i=0==s?0:l/s*1e3/10,s==r?e=0:n==s?e=(a-o)/l:a==s?e=2+(o-n)/l:o==s&&(e=4+(n-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),[e,i,s/255*1e3/10]}function a(t){var e=t[0],n=t[1],a=t[2];return[i(t)[0],100*(1/255*Math.min(e,Math.min(n,a))),100*(a=1-1/255*Math.max(e,Math.max(n,a)))]}function o(t){var e,i=t[0]/255,n=t[1]/255,a=t[2]/255;return[100*((1-i-(e=Math.min(1-i,1-n,1-a)))/(1-e)||0),100*((1-n-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]}function s(t){return _[JSON.stringify(t)]}function l(t){var e=t[0]/255,i=t[1]/255,n=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)+.1805*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)),100*(.2126*e+.7152*i+.0722*n),100*(.0193*e+.1192*i+.9505*n)]}function d(t){var e=l(t),i=e[0],n=e[1],a=e[2];return n/=100,a/=108.883,i=(i/=95.047)>.008856?Math.pow(i,1/3):7.787*i+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(i-n),200*(n-(a=a>.008856?Math.pow(a,1/3):7.787*a+16/116))]}function u(t){var e,i,n,a,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return[o=255*l,o,o];e=2*l-(i=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var d=0;d<3;d++)(n=r+1/3*-(d-1))<0&&n++,n>1&&n--,o=6*n<1?e+6*(i-e)*n:2*n<1?i:3*n<2?e+(i-e)*(2/3-n)*6:e,a[d]=255*o;return a}function h(t){var e=t[0]/60,i=t[1]/100,n=t[2]/100,a=Math.floor(e)%6,o=e-Math.floor(e),r=255*n*(1-i),s=255*n*(1-i*o),l=255*n*(1-i*(1-o));n*=255;switch(a){case 0:return[n,l,r];case 1:return[s,n,r];case 2:return[r,n,l];case 3:return[r,s,n];case 4:return[l,r,n];case 5:return[n,r,s]}}function c(t){var e,i,n,a,o=t[0]/360,s=t[1]/100,l=t[2]/100,d=s+l;switch(d>1&&(s/=d,l/=d),n=6*o-(e=Math.floor(6*o)),0!=(1&e)&&(n=1-n),a=s+n*((i=1-l)-s),e){default:case 6:case 0:r=i,g=a,b=s;break;case 1:r=a,g=i,b=s;break;case 2:r=s,g=i,b=a;break;case 3:r=s,g=a,b=i;break;case 4:r=a,g=s,b=i;break;case 5:r=i,g=s,b=a}return[255*r,255*g,255*b]}function f(t){var e=t[0]/100,i=t[1]/100,n=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a))]}function p(t){var e,i,n,a=t[0]/100,o=t[1]/100,r=t[2]/100;return i=-.9689*a+1.8758*o+.0415*r,n=.0557*a+-.204*o+1.057*r,e=(e=3.2406*a+-1.5372*o+-.4986*r)>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:n*=12.92,[255*(e=Math.min(Math.max(0,e),1)),255*(i=Math.min(Math.max(0,i),1)),255*(n=Math.min(Math.max(0,n),1))]}function m(t){var e=t[0],i=t[1],n=t[2];return i/=100,n/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(e-i),200*(i-(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116))]}function v(t){var e,i,n,a,o=t[0],r=t[1],s=t[2];return o<=8?a=(i=100*o/903.3)/100*7.787+16/116:(i=100*Math.pow((o+16)/116,3),a=Math.pow(i/100,1/3)),[e=e/95.047<=.008856?e=95.047*(r/500+a-16/116)/7.787:95.047*Math.pow(r/500+a,3),i,n=n/108.883<=.008859?n=108.883*(a-s/200-16/116)/7.787:108.883*Math.pow(a-s/200,3)]}function x(t){var e,i=t[0],n=t[1],a=t[2];return(e=360*Math.atan2(a,n)/2/Math.PI)<0&&(e+=360),[i,Math.sqrt(n*n+a*a),e]}function y(t){return p(v(t))}function k(t){var e,i=t[0],n=t[1];return e=t[2]/360*2*Math.PI,[i,n*Math.cos(e),n*Math.sin(e)]}function w(t){return M[t]}var M={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},_={};for(var C in M)_[JSON.stringify(M[C])]=C;var S=function(){return new T};for(var P in e){S[P+"Raw"]=function(t){return function(i){return"number"==typeof i&&(i=Array.prototype.slice.call(arguments)),e[t](i)}}(P);var I=/(\w+)2(\w+)/.exec(P),A=I[1],D=I[2];(S[A]=S[A]||{})[D]=S[P]=function(t){return function(i){"number"==typeof i&&(i=Array.prototype.slice.call(arguments));var n=e[t](i);if("string"==typeof n||void 0===n)return n;for(var a=0;a=0&&e<1?H(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return N(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:N,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return W(t,e);var i=Math.round(t[0]/255*100),n=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+i+"%, "+n+"%, "+a+"%)"},percentaString:W,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return V(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:V,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return j[t.slice(0,3)]}};function O(t){if(t){var e=[0,0,0],i=1,n=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(n){a=(n=n[1])[3];for(var o=0;oi?(e+.05)/(i+.05):(i+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,i=(e[0]+t)%360;return e[0]=i<0?360+i:i,this.setValues("hsl",e),this},mix:function(t,e){var i=t,n=void 0===e?.5:e,a=2*n-1,o=this.alpha()-i.alpha(),r=((a*o==-1?a:(a+o)/(1+a*o))+1)/2,s=1-r;return this.rgb(r*this.red()+s*i.red(),r*this.green()+s*i.green(),r*this.blue()+s*i.blue()).alpha(this.alpha()*n+i.alpha()*(1-n))},toJSON:function(){return this.rgb()},clone:function(){var t,e,i=new Y,n=this.values,a=i.values;for(var o in n)n.hasOwnProperty(o)&&(t=n[o],"[object Array]"===(e={}.toString.call(t))?a[o]=t.slice(0):"[object Number]"===e?a[o]=t:console.error("unexpected color value:",t));return i}},Y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},Y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},Y.prototype.getValues=function(t){for(var e=this.values,i={},n=0;n=0;a--)e.call(i,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i))},easeOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:1===t?1:(i||(i=.3),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/i)+1)},easeInOutElastic:function(t){var e=1.70158,i=0,n=1;return 0===t?0:2==(t/=.5)?1:(i||(i=.45),n<1?(n=1,e=i/4):e=i/(2*Math.PI)*Math.asin(1/n),t<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-Z.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*Z.easeInBounce(2*t):.5*Z.easeOutBounce(2*t-1)+.5}},$={effects:Z};G.easingEffects=Z;var J=Math.PI,Q=J/180,tt=2*J,et=J/2,it=J/4,nt=2*J/3,at={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,i,n,a,o){if(o){var r=Math.min(o,a/2,n/2),s=e+r,l=i+r,d=e+n-r,u=i+a-r;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,i,n,a=this.animations,o=0;o=i?(ut.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(o,1)):++o}},xt=ut.options.resolve,yt=["push","pop","shift","splice","unshift"];function kt(t,e){var i=t._chartjs;if(i){var n=i.listeners,a=n.indexOf(e);-1!==a&&n.splice(a,1),n.length>0||(yt.forEach(function(e){delete t[e]}),delete t._chartjs)}}var wt=function(t,e){this.initialize(t,e)};ut.extend(wt.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){this.chart=t,this.index=e,this.linkScales(),this.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),i=t.getDataset();null!==e.xAxisID&&e.xAxisID in t.chart.scales||(e.xAxisID=i.xAxisID||t.chart.options.scales.xAxes[0].id),null!==e.yAxisID&&e.yAxisID in t.chart.scales||(e.yAxisID=i.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this.update(!0)},destroy:function(){this._data&&kt(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,i=this.getMeta(),n=this.getDataset().data||[],a=i.data;for(t=0,e=n.length;ti&&this.insertElements(i,n-i)},insertElements:function(t,e){for(var i=0;is;)a-=2*Math.PI;for(;a=r&&a<=s,d=o>=i.innerRadius&&o<=i.outerRadius;return l&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,i=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,i=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*i,y:t.y+Math.sin(e)*i}},draw:function(){var t,e=this._chart.ctx,i=this._view,n=i.startAngle,a=i.endAngle,o="inner"===i.borderAlign?.33:0;e.save(),e.beginPath(),e.arc(i.x,i.y,Math.max(i.outerRadius-o,0),n,a),e.arc(i.x,i.y,i.innerRadius,a,n,!0),e.closePath(),e.fillStyle=i.backgroundColor,e.fill(),i.borderWidth&&("inner"===i.borderAlign?(e.beginPath(),t=o/i.outerRadius,e.arc(i.x,i.y,i.outerRadius,n-t,a+t),i.innerRadius>o?(t=o/i.innerRadius,e.arc(i.x,i.y,i.innerRadius-o,a+t,n-t,!0)):e.arc(i.x,i.y,o,a+Math.PI/2,n-Math.PI/2),e.closePath(),e.clip(),e.beginPath(),e.arc(i.x,i.y,i.outerRadius,n,a),e.arc(i.x,i.y,i.innerRadius,a,n,!0),e.closePath(),e.lineWidth=2*i.borderWidth,e.lineJoin="round"):(e.lineWidth=i.borderWidth,e.lineJoin="bevel"),e.strokeStyle=i.borderColor,e.stroke()),e.restore()}}),Ct=ut.valueOrDefault,St=st.global.defaultColor;st._set("global",{elements:{line:{tension:.4,backgroundColor:St,borderWidth:3,borderColor:St,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}});var Pt=pt.extend({draw:function(){var t,e,i,n,a=this._view,o=this._chart.ctx,r=a.spanGaps,s=this._children.slice(),l=st.global,d=l.elements.line,u=-1;for(this._loop&&s.length&&s.push(s[0]),o.save(),o.lineCap=a.borderCapStyle||d.borderCapStyle,o.setLineDash&&o.setLineDash(a.borderDash||d.borderDash),o.lineDashOffset=Ct(a.borderDashOffset,d.borderDashOffset),o.lineJoin=a.borderJoinStyle||d.borderJoinStyle,o.lineWidth=Ct(a.borderWidth,d.borderWidth),o.strokeStyle=a.borderColor||l.defaultColor,o.beginPath(),u=-1,t=0;tt.x&&(e=Ot(e,"left","right")):t.basei?i:n,r:l.right||a<0?0:a>e?e:a,b:l.bottom||o<0?0:o>i?i:o,l:l.left||r<0?0:r>e?e:r}}function Bt(t,e,i){var n=null===e,a=null===i,o=!(!t||n&&a)&&Rt(t);return o&&(n||e>=o.left&&e<=o.right)&&(a||i>=o.top&&i<=o.bottom)}st._set("global",{elements:{rectangle:{backgroundColor:Ft,borderColor:Ft,borderSkipped:"bottom",borderWidth:0}}});var Nt=pt.extend({draw:function(){var t=this._chart.ctx,e=this._view,i=function(t){var e=Rt(t),i=e.right-e.left,n=e.bottom-e.top,a=zt(t,i/2,n/2);return{outer:{x:e.left,y:e.top,w:i,h:n},inner:{x:e.left+a.l,y:e.top+a.t,w:i-a.l-a.r,h:n-a.t-a.b}}}(e),n=i.outer,a=i.inner;t.fillStyle=e.backgroundColor,t.fillRect(n.x,n.y,n.w,n.h),n.w===a.w&&n.h===a.h||(t.save(),t.beginPath(),t.rect(n.x,n.y,n.w,n.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return Bt(this._view,t,e)},inLabelRange:function(t,e){var i=this._view;return Lt(i)?Bt(i,t,null):Bt(i,null,e)},inXRange:function(t){return Bt(this._view,t,null)},inYRange:function(t){return Bt(this._view,null,t)},getCenterPoint:function(){var t,e,i=this._view;return Lt(i)?(t=i.x,e=(i.y+i.base)/2):(t=(i.x+i.base)/2,e=i.y),{x:t,y:e}},getArea:function(){var t=this._view;return Lt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),Wt={},Vt=_t,Et=Pt,Ht=Tt,jt=Nt;Wt.Arc=Vt,Wt.Line=Et,Wt.Point=Ht,Wt.Rectangle=jt;var qt=ut.options.resolve;st._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}});var Yt=Mt.extend({dataElementType:Wt.Rectangle,initialize:function(){var t;Mt.prototype.initialize.apply(this,arguments),(t=this.getMeta()).stack=this.getDataset().stack,t.bar=!0},update:function(t){var e,i,n=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,i=n.length;e0?Math.min(r,n-i):r,i=n;return r}(i,l):-1,pixels:l,start:r,end:s,stackCount:n,scale:i}},calculateBarValuePixels:function(t,e){var i,n,a,o,r,s,l=this.chart,d=this.getMeta(),u=this._getValueScale(),h=u.isHorizontal(),c=l.data.datasets,f=+u.getRightValue(c[t].data[e]),g=u.options.minBarLength,p=u.options.stacked,m=d.stack,v=0;if(p||void 0===p&&void 0!==m)for(i=0;i=0&&a>0)&&(v+=a));return o=u.getPixelForValue(v),s=(r=u.getPixelForValue(v+f))-o,void 0!==g&&Math.abs(s)=0&&!h||f<0&&h?o-g:o+g),{size:s,base:o,head:r,center:r+s/2}},calculateBarIndexPixels:function(t,e,i){var n=i.scale.options,a="flex"===n.barThickness?function(t,e,i){var n,a=e.pixels,o=a[t],r=t>0?a[t-1]:null,s=t');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o'),a[o]&&e.push(a[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),o=e.datasets[0],r=a.data[n],s=r&&r.custom||{},l=t.options.elements.arc;return{text:i,fillStyle:Gt([s.backgroundColor,o.backgroundColor,l.backgroundColor],void 0,n),strokeStyle:Gt([s.borderColor,o.borderColor,l.borderColor],void 0,n),lineWidth:Gt([s.borderWidth,o.borderWidth,l.borderWidth],void 0,n),hidden:isNaN(o.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i=Math.PI?-1:m<-Math.PI?1:0))+g,b={x:Math.cos(m),y:Math.sin(m)},x={x:Math.cos(v),y:Math.sin(v)},y=m<=0&&v>=0||m<=2*Math.PI&&2*Math.PI<=v,k=m<=.5*Math.PI&&.5*Math.PI<=v||m<=2.5*Math.PI&&2.5*Math.PI<=v,w=m<=-Math.PI&&-Math.PI<=v||m<=Math.PI&&Math.PI<=v,M=m<=.5*-Math.PI&&.5*-Math.PI<=v||m<=1.5*Math.PI&&1.5*Math.PI<=v,_=f/100,C={x:w?-1:Math.min(b.x*(b.x<0?1:_),x.x*(x.x<0?1:_)),y:M?-1:Math.min(b.y*(b.y<0?1:_),x.y*(x.y<0?1:_))},S={x:y?1:Math.max(b.x*(b.x>0?1:_),x.x*(x.x>0?1:_)),y:k?1:Math.max(b.y*(b.y>0?1:_),x.y*(x.y>0?1:_))},P={width:.5*(S.x-C.x),height:.5*(S.y-C.y)};d=Math.min(s/P.width,l/P.height),u={x:-.5*(S.x+C.x),y:-.5*(S.y+C.y)}}for(e=0,i=c.length;e0&&!isNaN(t)?2*Math.PI*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,i,n,a,o,r,s,l,d=0,u=this.chart;if(!t)for(e=0,i=u.data.datasets.length;e(d=s>d?s:d)?l:d);return d},setHoverStyle:function(t){var e=t._model,i=t._options,n=ut.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Zt(i.hoverBackgroundColor,n(i.backgroundColor)),e.borderColor=Zt(i.hoverBorderColor,n(i.borderColor)),e.borderWidth=Zt(i.hoverBorderWidth,i.borderWidth)},_resolveElementOptions:function(t,e){var i,n,a,o=this.chart,r=this.getDataset(),s=t.custom||{},l=o.options.elements.arc,d={},u={chart:o,dataIndex:e,dataset:r,datasetIndex:this.index},h=["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"];for(i=0,n=h.length;i0&&ee(l[t-1]._model,s)&&(i.controlPointPreviousX=d(i.controlPointPreviousX,s.left,s.right),i.controlPointPreviousY=d(i.controlPointPreviousY,s.top,s.bottom)),t');var i=t.data,n=i.datasets,a=i.labels;if(n.length)for(var o=0;o'),a[o]&&e.push(a[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map(function(i,n){var a=t.getDatasetMeta(0),o=e.datasets[0],r=a.data[n].custom||{},s=t.options.elements.arc;return{text:i,fillStyle:ae([r.backgroundColor,o.backgroundColor,s.backgroundColor],void 0,n),strokeStyle:ae([r.borderColor,o.borderColor,s.borderColor],void 0,n),lineWidth:ae([r.borderWidth,o.borderWidth,s.borderWidth],void 0,n),hidden:isNaN(o.data[n])||a.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var i,n,a,o=e.index,r=this.chart;for(i=0,n=(r.data.datasets||[]).length;i0&&(o=t.getDatasetMeta(o[0]._datasetIndex).data),o},"x-axis":function(t,e){return me(t,e,{intersect:!1})},point:function(t,e){return fe(t,he(e,t))},nearest:function(t,e,i){var n=he(e,t);i.axis=i.axis||"xy";var a=pe(i.axis);return ge(t,n,i.intersect,a)},x:function(t,e,i){var n=he(e,t),a=[],o=!1;return ce(t,function(t){t.inXRange(n.x)&&a.push(t),t.inRange(n.x,n.y)&&(o=!0)}),i.intersect&&!o&&(a=[]),a},y:function(t,e,i){var n=he(e,t),a=[],o=!1;return ce(t,function(t){t.inYRange(n.y)&&a.push(t),t.inRange(n.x,n.y)&&(o=!0)}),i.intersect&&!o&&(a=[]),a}}};function be(t,e){return ut.where(t,function(t){return t.position===e})}function xe(t,e){t.forEach(function(t,e){return t._tmpIndex_=e,t}),t.sort(function(t,i){var n=e?i:t,a=e?t:i;return n.weight===a.weight?n._tmpIndex_-a._tmpIndex_:n.weight-a.weight}),t.forEach(function(t){delete t._tmpIndex_})}function ye(t,e){ut.each(t,function(t){e[t.position]+=t.isHorizontal()?t.height:t.width})}st._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var ke={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,t.boxes.push(e)},removeBox:function(t,e){var i=t.boxes?t.boxes.indexOf(e):-1;-1!==i&&t.boxes.splice(i,1)},configure:function(t,e,i){for(var n,a=["fullWidth","position","weight"],o=a.length,r=0;rdiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&we.default||we,_e="$chartjs",Ce="chartjs-size-monitor",Se="chartjs-render-monitor",Pe="chartjs-render-animation",Ie=["animationstart","webkitAnimationStart"],Ae={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function De(t,e){var i=ut.getStyle(t,e),n=i&&i.match(/^(\d+)(\.\d+)?px$/);return n?Number(n[1]):void 0}var Te=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Fe(t,e,i){t.addEventListener(e,i,Te)}function Le(t,e,i){t.removeEventListener(e,i,Te)}function Re(t,e,i,n,a){return{type:t,chart:e,native:a||null,x:void 0!==i?i:null,y:void 0!==n?n:null}}function Oe(t){var e=document.createElement("div");return e.className=t||"",e}function ze(t,e,i){var n,a,o,r,s=t[_e]||(t[_e]={}),l=s.resizer=function(t){var e=Oe(Ce),i=Oe(Ce+"-expand"),n=Oe(Ce+"-shrink");i.appendChild(Oe()),n.appendChild(Oe()),e.appendChild(i),e.appendChild(n),e._reset=function(){i.scrollLeft=1e6,i.scrollTop=1e6,n.scrollLeft=1e6,n.scrollTop=1e6};var a=function(){e._reset(),t()};return Fe(i,"scroll",a.bind(i,"expand")),Fe(n,"scroll",a.bind(n,"shrink")),e}((n=function(){if(s.resizer){var n=i.options.maintainAspectRatio&&t.parentNode,a=n?n.clientWidth:0;e(Re("resize",i)),n&&n.clientWidth0){var o=t[0];o.label?i=o.label:o.xLabel?i=o.xLabel:a>0&&o.index-1?t.split("\n"):t}function Xe(t){var e=st.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,bodyFontColor:t.bodyFontColor,_bodyFontFamily:je(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:je(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:je(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:je(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:je(t.titleFontStyle,e.defaultFontStyle),titleFontSize:je(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:je(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:je(t.footerFontStyle,e.defaultFontStyle),footerFontSize:je(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function Ke(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function Ge(t){return Ye([],Ue(t))}var Ze=pt.extend({initialize:function(){this._model=Xe(this._options),this._lastActive=[]},getTitle:function(){var t=this._options.callbacks,e=t.beforeTitle.apply(this,arguments),i=t.title.apply(this,arguments),n=t.afterTitle.apply(this,arguments),a=[];return a=Ye(a,Ue(e)),a=Ye(a,Ue(i)),a=Ye(a,Ue(n))},getBeforeBody:function(){return Ge(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var i=this,n=i._options.callbacks,a=[];return ut.each(t,function(t){var o={before:[],lines:[],after:[]};Ye(o.before,Ue(n.beforeLabel.call(i,t,e))),Ye(o.lines,n.label.call(i,t,e)),Ye(o.after,Ue(n.afterLabel.call(i,t,e))),a.push(o)}),a},getAfterBody:function(){return Ge(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this._options.callbacks,e=t.beforeFooter.apply(this,arguments),i=t.footer.apply(this,arguments),n=t.afterFooter.apply(this,arguments),a=[];return a=Ye(a,Ue(e)),a=Ye(a,Ue(i)),a=Ye(a,Ue(n))},update:function(t){var e,i,n,a,o,r,s,l,d,u,h=this,c=h._options,f=h._model,g=h._model=Xe(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var k=[],w=[];y=qe[c.position].call(h,p,h._eventPosition);var M=[];for(e=0,i=p.length;en.width&&(a=n.width-e.width),a<0&&(a=0)),"top"===u?o+=h:o-="bottom"===u?e.height+h:e.height/2,"center"===u?"left"===d?a+=h:"right"===d&&(a-=h):"left"===d?a-=c:"right"===d&&(a+=c),{x:a,y:o}}(g,x,v=function(t,e){var i,n,a,o,r,s=t._model,l=t._chart,d=t._chart.chartArea,u="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(d.left+d.right)/2,f=(d.top+d.bottom)/2;"center"===h?(i=function(t){return t<=c},n=function(t){return t>c}):(i=function(t){return t<=e.width/2},n=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},o=function(t){return t-e.width-s.caretSize-s.caretPadding<0},r=function(t){return t<=f?"top":"bottom"},i(s.x)?(u="left",a(s.x)&&(u="center",h=r(s.y))):n(s.x)&&(u="right",o(s.x)&&(u="center",h=r(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:u,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var i=this._chart.ctx,n=this._view,a=this.getCaretPosition(t,e,n);i.lineTo(a.x1,a.y1),i.lineTo(a.x2,a.y2),i.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,i){var n,a,o,r,s,l,d=i.caretSize,u=i.cornerRadius,h=i.xAlign,c=i.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(n=f)-d,o=n,r=s+d,l=s-d):(a=(n=f+p)+d,o=n,r=s-d,l=s+d);else if("left"===h?(n=(a=f+u+d)-d,o=a+d):"right"===h?(n=(a=f+p-u-d)-d,o=a+d):(n=(a=i.caretX)-d,o=a+d),"top"===c)s=(r=g)-d,l=r;else{s=(r=g+m)+d,l=r;var v=o;o=n,n=v}return{x1:n,x2:a,x3:o,y1:r,y2:s,y3:l}},drawTitle:function(t,e,i){var n=e.title;if(n.length){t.x=Ke(e,e._titleAlign),i.textAlign=e._titleAlign,i.textBaseline="top";var a,o,r=e.titleFontSize,s=e.titleSpacing;for(i.fillStyle=e.titleFontColor,i.font=ut.fontString(r,e._titleFontStyle,e._titleFontFamily),a=0,o=n.length;a0&&i.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var i={width:e.width,height:e.height},n={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,o=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&o&&(t.save(),t.globalAlpha=a,this.drawBackground(n,e,t,i),n.y+=e.yPadding,this.drawTitle(n,e,t),this.drawBody(n,e,t),this.drawFooter(n,e,t),t.restore())}},handleEvent:function(t){var e,i=this,n=i._options;return i._lastActive=i._lastActive||[],"mouseout"===t.type?i._active=[]:i._active=i._chart.getElementsAtEventForMode(t,n.mode,n),(e=!ut.arrayEquals(i._active,i._lastActive))&&(i._lastActive=i._active,(n.enabled||n.custom)&&(i._eventPosition={x:t.x,y:t.y},i.update(!0),i.pivot())),e}}),$e=qe,Je=Ze;Je.positioners=$e;var Qe=ut.valueOrDefault;function ti(){return ut.merge({},[].slice.call(arguments),{merger:function(t,e,i,n){if("xAxes"===t||"yAxes"===t){var a,o,r,s=i[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||r.type&&r.type!==e[t][a].type?ut.merge(e[t][a],[He.getScaleDefaults(o),r]):ut.merge(e[t][a],r)}else ut._merger(t,e,i,n)}})}function ei(){return ut.merge({},[].slice.call(arguments),{merger:function(t,e,i,n){var a=e[t]||{},o=i[t];"scales"===t?e[t]=ti(a,o):"scale"===t?e[t]=ut.merge(a,[He.getScaleDefaults(o.type),o]):ut._merger(t,e,i,n)}})}function ii(t){return"top"===t||"bottom"===t}st._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var ni=function(t,e){return this.construct(t,e),this};ut.extend(ni.prototype,{construct:function(t,e){var i=this;e=function(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=ei(st.global,st[t.type],t.options||{}),t}(e);var n=Ve.acquireContext(t,e),a=n&&n.canvas,o=a&&a.height,r=a&&a.width;i.id=ut.uid(),i.ctx=n,i.canvas=a,i.config=e,i.width=r,i.height=o,i.aspectRatio=o?r/o:null,i.options=e.options,i._bufferedRender=!1,i.chart=i,i.controller=i,ni.instances[i.id]=i,Object.defineProperty(i,"data",{get:function(){return i.config.data},set:function(t){i.config.data=t}}),n&&a?(i.initialize(),i.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Ee.notify(t,"beforeInit"),ut.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.initToolTip(),Ee.notify(t,"afterInit"),t},clear:function(){return ut.canvas.clear(this),this},stop:function(){return bt.cancelAnimation(this),this},resize:function(t){var e=this,i=e.options,n=e.canvas,a=i.maintainAspectRatio&&e.aspectRatio||null,o=Math.max(0,Math.floor(ut.getMaximumWidth(n))),r=Math.max(0,Math.floor(a?o/a:ut.getMaximumHeight(n)));if((e.width!==o||e.height!==r)&&(n.width=e.width=o,n.height=e.height=r,n.style.width=o+"px",n.style.height=r+"px",ut.retinaScale(e,i.devicePixelRatio),!t)){var s={width:o,height:r};Ee.notify(e,"resize",[s]),i.onResize&&i.onResize(e,s),e.stop(),e.update({duration:i.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},i=t.scale;ut.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),ut.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),i&&(i.id=i.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,i=t.scales||{},n=[],a=Object.keys(i).reduce(function(t,e){return t[e]=!1,t},{});e.scales&&(n=n.concat((e.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category",dposition:"bottom"}}),(e.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear",dposition:"left"}}))),e.scale&&n.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),ut.each(n,function(e){var n=e.options,o=n.id,r=Qe(n.type,e.dtype);ii(n.position)!==ii(e.dposition)&&(n.position=e.dposition),a[o]=!0;var s=null;if(o in i&&i[o].type===r)(s=i[o]).options=n,s.ctx=t.ctx,s.chart=t;else{var l=He.getScaleConstructor(r);if(!l)return;s=new l({id:o,type:r,options:n,ctx:t.ctx,chart:t}),i[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)}),ut.each(a,function(t,e){t||delete i[e]}),t.scales=i,He.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t=this,e=[];return ut.each(t.data.datasets,function(i,n){var a=t.getDatasetMeta(n),o=i.type||t.config.type;if(a.type&&a.type!==o&&(t.destroyDatasetMeta(n),a=t.getDatasetMeta(n)),a.type=o,a.controller)a.controller.updateIndex(n),a.controller.linkScales();else{var r=ue[a.type];if(void 0===r)throw new Error('"'+a.type+'" is not a chart type.');a.controller=new r(t,n),e.push(a.controller)}},t),e},resetElements:function(){var t=this;ut.each(t.data.datasets,function(e,i){t.getDatasetMeta(i).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t){var e,i,n=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),i=(e=n).options,ut.each(e.scales,function(t){ke.removeBox(e,t)}),i=ei(st.global,st[e.config.type],i),e.options=e.config.options=i,e.ensureScalesHaveIDs(),e.buildOrUpdateScales(),e.tooltip._options=i.tooltips,e.tooltip.initialize(),Ee._invalidate(n),!1!==Ee.notify(n,"beforeUpdate")){n.tooltip._data=n.data;var a=n.buildOrUpdateControllers();ut.each(n.data.datasets,function(t,e){n.getDatasetMeta(e).controller.buildOrUpdateElements()},n),n.updateLayout(),n.options.animation&&n.options.animation.duration&&ut.each(a,function(t){t.reset()}),n.updateDatasets(),n.tooltip.initialize(),n.lastActive=[],Ee.notify(n,"afterUpdate"),n._bufferedRender?n._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:n.render(t)}},updateLayout:function(){!1!==Ee.notify(this,"beforeLayout")&&(ke.update(this,this.width,this.height),Ee.notify(this,"afterScaleUpdate"),Ee.notify(this,"afterLayout"))},updateDatasets:function(){if(!1!==Ee.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t=0;--i)e.isDatasetVisible(i)&&e.drawDataset(i,t);Ee.notify(e,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var i=this.getDatasetMeta(t),n={meta:i,index:t,easingValue:e};!1!==Ee.notify(this,"beforeDatasetDraw",[n])&&(i.controller.draw(e),Ee.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,i={tooltip:e,easingValue:t};!1!==Ee.notify(this,"beforeTooltipDraw",[i])&&(e.draw(),Ee.notify(this,"afterTooltipDraw",[i]))},getElementAtEvent:function(t){return ve.modes.single(this,t)},getElementsAtEvent:function(t){return ve.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return ve.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,i){var n=ve.modes[e];return"function"==typeof n?n(this,t,i):[]},getDatasetAtEvent:function(t){return ve.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var i=e._meta[this.id];return i||(i=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,i=this.data.datasets.length;e3?i[2]-i[1]:i[1]-i[0];Math.abs(n)>1&&t!==Math.floor(t)&&(n=t-Math.floor(t));var a=ut.log10(Math.abs(n)),o="";if(0!==t)if(Math.max(Math.abs(i[0]),Math.abs(i[i.length-1]))<1e-4){var r=ut.log10(Math.abs(t));o=t.toExponential(Math.floor(r)-Math.floor(a))}else{var s=-1*Math.floor(a);s=Math.max(Math.min(s,20),0),o=t.toFixed(s)}else o="0";return o},logarithmic:function(t,e,i){var n=t/Math.pow(10,Math.floor(ut.log10(t)));return 0===t?"0":1===n||2===n||5===n||0===e||e===i.length-1?t.toExponential():""}}},di=ut.valueOrDefault,ui=ut.valueAtIndexOrDefault;function hi(t){var e,i,n=[];for(e=0,i=t.length;ed&&ot.maxHeight){o--;break}o++,l=r*s}t.labelRotation=o},afterCalculateTickRotation:function(){ut.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){ut.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},i=hi(t._ticks),n=t.options,a=n.ticks,o=n.scaleLabel,r=n.gridLines,s=t._isVisible(),l=n.position,d=t.isHorizontal(),u=ut.options._parseFont,h=u(a),c=n.gridLines.tickMarkLength;if(e.width=d?t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:s&&r.drawTicks?c:0,e.height=d?s&&r.drawTicks?c:0:t.maxHeight,o.display&&s){var f=u(o),g=ut.options.toPadding(o.padding),p=f.lineHeight+g.height;d?e.height+=p:e.width+=p}if(a.display&&s){var m=ut.longestText(t.ctx,h.string,i,t.longestTextCache),v=ut.numberOfLabelLines(i),b=.5*h.size,x=t.options.ticks.padding;if(t._maxLabelLines=v,t.longestLabelWidth=m,d){var y=ut.toRadians(t.labelRotation),k=Math.cos(y),w=Math.sin(y)*m+h.lineHeight*v+b;e.height=Math.min(t.maxHeight,e.height+w+x),t.ctx.font=h.string;var M,_,C=ci(t.ctx,i[0],h.string),S=ci(t.ctx,i[i.length-1],h.string),P=t.getPixelForTick(0)-t.left,I=t.right-t.getPixelForTick(i.length-1);0!==t.labelRotation?(M="bottom"===l?k*C:k*b,_="bottom"===l?k*b:k*S):(M=C/2,_=S/2),t.paddingLeft=Math.max(M-P,0)+3,t.paddingRight=Math.max(_-I,0)+3}else a.mirror?m=0:m+=x+b,e.width=Math.min(t.maxWidth,e.width+m),t.paddingTop=h.size/2,t.paddingBottom=h.size/2}t.handleMargins(),t.width=e.width,t.height=e.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){ut.callback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(ut.isNullOrUndef(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},getLabelForIndex:ut.noop,getPixelForValue:ut.noop,getValueForPixel:ut.noop,getPixelForTick:function(t){var e=this,i=e.options.offset;if(e.isHorizontal()){var n=(e.width-(e.paddingLeft+e.paddingRight))/Math.max(e._ticks.length-(i?0:1),1),a=n*t+e.paddingLeft;i&&(a+=n/2);var o=e.left+a;return o+=e.isFullWidth()?e.margins.left:0}var r=e.height-(e.paddingTop+e.paddingBottom);return e.top+t*(r/(e._ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var i=(e.width-(e.paddingLeft+e.paddingRight))*t+e.paddingLeft,n=e.left+i;return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,i,n=this,a=n.isHorizontal(),o=n.options.ticks.minor,r=t.length,s=!1,l=o.maxTicksLimit,d=n._tickSize()*(r-1),u=a?n.width-(n.paddingLeft+n.paddingRight):n.height-(n.paddingTop+n.PaddingBottom),h=[];for(d>u&&(s=1+Math.floor(d/u)),r>l&&(s=Math.max(s,1+Math.floor(r/l))),e=0;e1&&e%s>0&&delete i.label,h.push(i);return h},_tickSize:function(){var t=this,e=t.isHorizontal(),i=t.options.ticks.minor,n=ut.toRadians(t.labelRotation),a=Math.abs(Math.cos(n)),o=Math.abs(Math.sin(n)),r=i.autoSkipPadding||0,s=t.longestLabelWidth+r||0,l=ut.options._parseFont(i),d=t._maxLabelLines*l.lineHeight+r||0;return e?d*a>s*o?s/a:d/o:d*o0&&n>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,o=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==o&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,i=e.stepSize,n=e.maxTicksLimit;return i?t=Math.ceil(this.max/i)-Math.floor(this.min/i)+1:(t=this._computeTickLimit(),n=n||11),n&&(t=Math.min(n,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:mi,buildTicks:function(){var t=this,e=t.options.ticks,i=t.getTickLimit(),n={maxTicks:i=Math.max(2,i),min:e.min,max:e.max,precision:e.precision,stepSize:ut.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var i,n,a,o,r=[],s=t.stepSize,l=s||1,d=t.maxTicks-1,u=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=ut.niceNum((g-f)/d/l)*l;if(p<1e-14&&vi(u)&&vi(h))return[f,g];(o=Math.ceil(g/p)-Math.floor(f/p))>d&&(p=ut.niceNum(o*p/d/l)*l),s||vi(c)?i=Math.pow(10,ut._decimalPlaces(p)):(i=Math.pow(10,c),p=Math.ceil(p*i)/i),n=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!vi(u)&&ut.almostWhole(u/p,p/1e3)&&(n=u),!vi(h)&&ut.almostWhole(h/p,p/1e3)&&(a=h)),o=(a-n)/p,o=ut.almostEquals(o,Math.round(o),p/1e3)?Math.round(o):Math.ceil(o),n=Math.round(n*i)/i,a=Math.round(a*i)/i,r.push(vi(u)?n:u);for(var m=1;mt.max&&(t.max=n))})});t.min=isFinite(t.min)&&!isNaN(t.min)?t.min:0,t.max=isFinite(t.max)&&!isNaN(t.max)?t.max:1,this.handleTickRangeOptions()},_computeTickLimit:function(){var t;return this.isHorizontal()?Math.ceil(this.width/40):(t=ut.options._parseFont(this.options.ticks),Math.ceil(this.height/t.lineHeight))},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e=this,i=e.start,n=+e.getRightValue(t),a=e.end-i;return e.isHorizontal()?e.left+e.width/a*(n-i):e.bottom-e.height/a*(n-i)},getValueForPixel:function(t){var e=this,i=e.isHorizontal(),n=i?e.width:e.height,a=(i?t-e.left:e.bottom-t)/n;return e.start+(e.end-e.start)*a},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}}),ki=xi;yi._defaults=ki;var wi=ut.valueOrDefault;var Mi={position:"left",ticks:{callback:li.formatters.logarithmic}};function _i(t,e){return ut.isFinite(t)&&t>=0?t:e}var Ci=fi.extend({determineDataLimits:function(){var t=this,e=t.options,i=t.chart,n=i.data.datasets,a=t.isHorizontal();function o(e){return a?e.xAxisID===t.id:e.yAxisID===t.id}t.min=null,t.max=null,t.minNotZero=null;var r=e.stacked;if(void 0===r&&ut.each(n,function(t,e){if(!r){var n=i.getDatasetMeta(e);i.isDatasetVisible(e)&&o(n)&&void 0!==n.stack&&(r=!0)}}),e.stacked||r){var s={};ut.each(n,function(n,a){var r=i.getDatasetMeta(a),l=[r.type,void 0===e.stacked&&void 0===r.stack?a:"",r.stack].join(".");i.isDatasetVisible(a)&&o(r)&&(void 0===s[l]&&(s[l]=[]),ut.each(n.data,function(e,i){var n=s[l],a=+t.getRightValue(e);isNaN(a)||r.data[i].hidden||a<0||(n[i]=n[i]||0,n[i]+=a)}))}),ut.each(s,function(e){if(e.length>0){var i=ut.min(e),n=ut.max(e);t.min=null===t.min?i:Math.min(t.min,i),t.max=null===t.max?n:Math.max(t.max,n)}})}else ut.each(n,function(e,n){var a=i.getDatasetMeta(n);i.isDatasetVisible(n)&&o(a)&&ut.each(e.data,function(e,i){var n=+t.getRightValue(e);isNaN(n)||a.data[i].hidden||n<0||(null===t.min?t.min=n:nt.max&&(t.max=n),0!==n&&(null===t.minNotZero||n0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(ut.log10(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,i=!t.isHorizontal(),n={min:_i(e.min),max:_i(e.max)},a=t.ticks=function(t,e){var i,n,a=[],o=wi(t.min,Math.pow(10,Math.floor(ut.log10(e.min)))),r=Math.floor(ut.log10(e.max)),s=Math.ceil(e.max/Math.pow(10,r));0===o?(i=Math.floor(ut.log10(e.minNotZero)),n=Math.floor(e.minNotZero/Math.pow(10,i)),a.push(o),o=n*Math.pow(10,i)):(i=Math.floor(ut.log10(o)),n=Math.floor(o/Math.pow(10,i)));var l=i<0?Math.pow(10,Math.abs(i)):1;do{a.push(o),10==++n&&(n=1,l=++i>=0?1:l),o=Math.round(n*Math.pow(10,i)*l)/l}while(ia?{start:e-i,end:e}:{start:e,end:e+i}}function Ri(t){return 0===t||180===t?"center":t<180?"left":"right"}function Oi(t,e,i,n){var a,o,r=i.y+n/2;if(ut.isArray(e))for(a=0,o=e.length;a270||t<90)&&(i.y-=e.h)}function Bi(t){return ut.isNumber(t)?t:0}var Ni=bi.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Fi(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,i=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY;ut.each(e.data.datasets,function(a,o){if(e.isDatasetVisible(o)){var r=e.getDatasetMeta(o);ut.each(a.data,function(e,a){var o=+t.getRightValue(e);isNaN(o)||r.data[a].hidden||(i=Math.min(o,i),n=Math.max(o,n))})}}),t.min=i===Number.POSITIVE_INFINITY?0:i,t.max=n===Number.NEGATIVE_INFINITY?0:n,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Fi(this.options))},convertTicksToLabels:function(){var t=this;bi.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map(t.options.pointLabels.callback,t)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,i,n,a=ut.options._parseFont(t.options.pointLabels),o={l:0,r:t.width,t:0,b:t.height-t.paddingTop},r={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,d,u=Ti(t);for(e=0;eo.r&&(o.r=f.end,r.r=h),g.starto.b&&(o.b=g.end,r.b=h)}t.setReductions(t.drawingArea,o,r)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,i){var n=this,a=e.l/Math.sin(i.l),o=Math.max(e.r-n.width,0)/Math.sin(i.r),r=-e.t/Math.cos(i.t),s=-Math.max(e.b-(n.height-n.paddingTop),0)/Math.cos(i.b);a=Bi(a),o=Bi(o),r=Bi(r),s=Bi(s),n.drawingArea=Math.min(Math.floor(t-(a+o)/2),Math.floor(t-(r+s)/2)),n.setCenterPoint(a,o,r,s)},setCenterPoint:function(t,e,i,n){var a=this,o=a.width-e-a.drawingArea,r=t+a.drawingArea,s=i+a.drawingArea,l=a.height-a.paddingTop-n-a.drawingArea;a.xCenter=Math.floor((r+o)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){return t*(2*Math.PI/Ti(this))+(this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var i=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*i:(t-e.min)*i},getPointPosition:function(t,e){var i=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(i)*e+this.xCenter,y:Math.sin(i)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this.min,e=this.max;return this.getPointPositionForValue(0,this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0)},draw:function(){var t=this,e=t.options,i=e.gridLines,n=e.ticks;if(e.display){var a=t.ctx,o=this.getIndexAngle(0),r=ut.options._parseFont(n);(e.angleLines.display||e.pointLabels.display)&&function(t){var e=t.ctx,i=t.options,n=i.angleLines,a=i.gridLines,o=i.pointLabels,r=Pi(n.lineWidth,a.lineWidth),s=Pi(n.color,a.color),l=Fi(i);e.save(),e.lineWidth=r,e.strokeStyle=s,e.setLineDash&&(e.setLineDash(Ai([n.borderDash,a.borderDash,[]])),e.lineDashOffset=Ai([n.borderDashOffset,a.borderDashOffset,0]));var d=t.getDistanceFromCenterForValue(i.ticks.reverse?t.min:t.max),u=ut.options._parseFont(o);e.font=u.string,e.textBaseline="middle";for(var h=Ti(t)-1;h>=0;h--){if(n.display&&r&&s){var c=t.getPointPosition(h,d);e.beginPath(),e.moveTo(t.xCenter,t.yCenter),e.lineTo(c.x,c.y),e.stroke()}if(o.display){var f=0===h?l/2:0,g=t.getPointPosition(h,d+f+5),p=Ii(o.fontColor,h,st.global.defaultFontColor);e.fillStyle=p;var m=t.getIndexAngle(h),v=ut.toDegrees(m);e.textAlign=Ri(v),zi(v,t._pointLabelSizes[h],g),Oi(e,t.pointLabels[h]||"",g,u.lineHeight)}}e.restore()}(t),ut.each(t.ticks,function(e,s){if(s>0||n.reverse){var l=t.getDistanceFromCenterForValue(t.ticksAsNumbers[s]);if(i.display&&0!==s&&function(t,e,i,n){var a,o=t.ctx,r=e.circular,s=Ti(t),l=Ii(e.color,n-1),d=Ii(e.lineWidth,n-1);if((r||s)&&l&&d){if(o.save(),o.strokeStyle=l,o.lineWidth=d,o.setLineDash&&(o.setLineDash(e.borderDash||[]),o.lineDashOffset=e.borderDashOffset||0),o.beginPath(),r)o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI);else{a=t.getPointPosition(0,i),o.moveTo(a.x,a.y);for(var u=1;u=0&&r<=s;){if(a=t[(n=r+s>>1)-1]||null,o=t[n],!a)return{lo:null,hi:o};if(o[e]i))return{lo:a,hi:o};s=n-1}}return{lo:o,hi:null}}(t,e,i),o=a.lo?a.hi?a.lo:t[t.length-2]:t[0],r=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=r[e]-o[e],l=s?(i-o[e])/s:0,d=(r[n]-o[n])*l;return o[n]+d}function Ki(t,e){var i=t._adapter,n=t.options.time,a=n.parser,o=a||n.format,r=e;return"function"==typeof a&&(r=a(r)),ut.isFinite(r)||(r="string"==typeof o?i.parse(r,o):i.parse(r)),null!==r?+r:(a||"function"!=typeof o||(r=o(e),ut.isFinite(r)||(r=i.parse(r))),r)}function Gi(t,e){if(ut.isNullOrUndef(e))return null;var i=t.options.time,n=Ki(t,t.getRightValue(e));return null===n?n:(i.round&&(n=+t._adapter.startOf(n,i.round)),n)}function Zi(t){for(var e=qi.indexOf(t)+1,i=qi.length;e=a&&i<=o&&d.push(i);return n.min=a,n.max=o,n._unit=s.unit||function(t,e,i,n,a){var o,r;for(o=qi.length-1;o>=qi.indexOf(i);o--)if(r=qi[o],ji[r].common&&t._adapter.diff(a,n,r)>=e.length)return r;return qi[i?qi.indexOf(i):0]}(n,d,s.minUnit,n.min,n.max),n._majorUnit=Zi(n._unit),n._table=function(t,e,i,n){if("linear"===n||!t.length)return[{time:e,pos:0},{time:i,pos:1}];var a,o,r,s,l,d=[],u=[e];for(a=0,o=t.length;ae&&s=0&&t0?r:1}}),Qi={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};Ji._defaults=Qi;var tn={category:gi,linear:yi,logarithmic:Ci,radialLinear:Ni,time:Ji},en={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};si._date.override("function"==typeof t?{_id:"moment",formats:function(){return en},parse:function(e,i){return"string"==typeof e&&"string"==typeof i?e=t(e,i):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,i){return t(e).format(i)},add:function(e,i,n){return t(e).add(i,n).valueOf()},diff:function(e,i,n){return t.duration(t(e).diff(t(i))).as(n)},startOf:function(e,i,n){return e=t(e),"isoWeek"===i?e.isoWeekday(n).valueOf():e.startOf(i).valueOf()},endOf:function(e,i){return t(e).endOf(i).valueOf()},_create:function(e){return t(e)}}:{}),st._set("global",{plugins:{filler:{propagate:!0}}});var nn={dataset:function(t){var e=t.fill,i=t.chart,n=i.getDatasetMeta(e),a=n&&i.isDatasetVisible(e)&&n.dataset._children||[],o=a.length||0;return o?function(t,e){return e=i)&&n;switch(o){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return o;default:return!1}}function on(t){var e,i=t.el._model||{},n=t.el._scale||{},a=t.fill,o=null;if(isFinite(a))return null;if("start"===a?o=void 0===i.scaleBottom?n.bottom:i.scaleBottom:"end"===a?o=void 0===i.scaleTop?n.top:i.scaleTop:void 0!==i.scaleZero?o=i.scaleZero:n.getBasePosition?o=n.getBasePosition():n.getBasePixel&&(o=n.getBasePixel()),null!=o){if(void 0!==o.x&&void 0!==o.y)return o;if(ut.isFinite(o))return{x:(e=n.isHorizontal())?o:null,y:e?null:o}}return null}function rn(t,e,i){var n,a=t[e].fill,o=[e];if(!i)return a;for(;!1!==a&&-1===o.indexOf(a);){if(!isFinite(a))return a;if(!(n=t[a]))return!1;if(n.visible)return a;o.push(a),a=n.fill}return!1}function sn(t){var e=t.fill,i="dataset";return!1===e?null:(isFinite(e)||(i="boundary"),nn[i](t))}function ln(t){return t&&!t.skip}function dn(t,e,i,n,a){var o;if(n&&a){for(t.moveTo(e[0].x,e[0].y),o=1;o0;--o)ut.canvas.lineTo(t,i[o],i[o-1],!0)}}var un={id:"filler",afterDatasetsUpdate:function(t,e){var i,n,a,o,r=(t.data.datasets||[]).length,s=e.propagate,l=[];for(n=0;ne?e:t.boxWidth}st._set("global",{legend:{display:!0,position:"top",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var i=e.datasetIndex,n=this.chart,a=n.getDatasetMeta(i);a.hidden=null===a.hidden?!n.data.datasets[i].hidden:null,n.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return ut.isArray(e.datasets)?e.datasets.map(function(e,i){return{text:e.label,fillStyle:ut.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(i),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:i}},this):[]}}},legendCallback:function(t){var e=[];e.push('
              ');for(var i=0;i'),t.data.datasets[i].label&&e.push(t.data.datasets[i].label),e.push("");return e.push("
            "),e.join("")}});var gn=pt.extend({initialize:function(t){ut.extend(this,t),this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1},beforeUpdate:hn,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:hn,beforeSetDimensions:hn,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:hn,beforeBuildLabels:hn,buildLabels:function(){var t=this,e=t.options.labels||{},i=ut.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(i=i.filter(function(i){return e.filter(i,t.chart.data)})),t.options.reverse&&i.reverse(),t.legendItems=i},afterBuildLabels:hn,beforeFit:hn,fit:function(){var t=this,e=t.options,i=e.labels,n=e.display,a=t.ctx,o=ut.options._parseFont(i),r=o.size,s=t.legendHitBoxes=[],l=t.minSize,d=t.isHorizontal();if(d?(l.width=t.maxWidth,l.height=n?10:0):(l.width=n?10:0,l.height=t.maxHeight),n)if(a.font=o.string,d){var u=t.lineWidths=[0],h=0;a.textAlign="left",a.textBaseline="top",ut.each(t.legendItems,function(t,e){var n=fn(i,r)+r/2+a.measureText(t.text).width;(0===e||u[u.length-1]+n+i.padding>l.width)&&(h+=r+i.padding,u[u.length-(e>0?0:1)]=i.padding),s[e]={left:0,top:0,width:n,height:r},u[u.length-1]+=n+i.padding}),l.height+=h}else{var c=i.padding,f=t.columnWidths=[],g=i.padding,p=0,m=0,v=r+c;ut.each(t.legendItems,function(t,e){var n=fn(i,r)+r/2+a.measureText(t.text).width;e>0&&m+v>l.height-c&&(g+=p+i.padding,f.push(p),p=0,m=0),p=Math.max(p,n),m+=v,s[e]={left:0,top:0,width:n,height:r}}),g+=p,f.push(p),l.width+=g}t.width=l.width,t.height=l.height},afterFit:hn,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,i=e.labels,n=st.global,a=n.defaultColor,o=n.elements.line,r=t.width,s=t.lineWidths;if(e.display){var l,d=t.ctx,u=cn(i.fontColor,n.defaultFontColor),h=ut.options._parseFont(i),c=h.size;d.textAlign="left",d.textBaseline="middle",d.lineWidth=.5,d.strokeStyle=u,d.fillStyle=u,d.font=h.string;var f=fn(i,c),g=t.legendHitBoxes,p=t.isHorizontal();l=p?{x:t.left+(r-s[0])/2+i.padding,y:t.top+i.padding,line:0}:{x:t.left+i.padding,y:t.top+i.padding,line:0};var m=c+i.padding;ut.each(t.legendItems,function(n,u){var h=d.measureText(n.text).width,v=f+c/2+h,b=l.x,x=l.y;p?u>0&&b+v+i.padding>t.left+t.minSize.width&&(x=l.y+=m,l.line++,b=l.x=t.left+(r-s[l.line])/2+i.padding):u>0&&x+m>t.top+t.minSize.height&&(b=l.x=b+t.columnWidths[l.line]+i.padding,x=l.y=t.top+i.padding,l.line++),function(t,i,n){if(!(isNaN(f)||f<=0)){d.save();var r=cn(n.lineWidth,o.borderWidth);if(d.fillStyle=cn(n.fillStyle,a),d.lineCap=cn(n.lineCap,o.borderCapStyle),d.lineDashOffset=cn(n.lineDashOffset,o.borderDashOffset),d.lineJoin=cn(n.lineJoin,o.borderJoinStyle),d.lineWidth=r,d.strokeStyle=cn(n.strokeStyle,a),d.setLineDash&&d.setLineDash(cn(n.lineDash,o.borderDash)),e.labels&&e.labels.usePointStyle){var s=f*Math.SQRT2/2,l=t+f/2,u=i+c/2;ut.canvas.drawPoint(d,n.pointStyle,s,l,u)}else 0!==r&&d.strokeRect(t,i,f,c),d.fillRect(t,i,f,c);d.restore()}}(b,x,n),g[u].left=b,g[u].top=x,function(t,e,i,n){var a=c/2,o=f+a+t,r=e+a;d.fillText(i.text,o,r),i.hidden&&(d.beginPath(),d.lineWidth=2,d.moveTo(o,r),d.lineTo(o+n,r),d.stroke())}(b,x,n,h),p?l.x+=v+i.padding:l.y+=m})}},_getLegendItemAt:function(t,e){var i,n,a,o=this;if(t>=o.left&&t<=o.right&&e>=o.top&&e<=o.bottom)for(a=o.legendHitBoxes,i=0;i=(n=a[i]).left&&t<=n.left+n.width&&e>=n.top&&e<=n.top+n.height)return o.legendItems[i];return null},handleEvent:function(t){var e,i=this,n=i.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!n.onHover&&!n.onLeave)return}else{if("click"!==a)return;if(!n.onClick)return}e=i._getLegendItemAt(t.x,t.y),"click"===a?e&&n.onClick&&n.onClick.call(i,t.native,e):(n.onLeave&&e!==i._hoveredItem&&(i._hoveredItem&&n.onLeave.call(i,t.native,i._hoveredItem),i._hoveredItem=e),n.onHover&&e&&n.onHover.call(i,t.native,e))}});function pn(t,e){var i=new gn({ctx:t.ctx,options:e,chart:t});ke.configure(t,i,e),ke.addBox(t,i),t.legend=i}var mn={id:"legend",_element:gn,beforeInit:function(t){var e=t.options.legend;e&&pn(t,e)},beforeUpdate:function(t){var e=t.options.legend,i=t.legend;e?(ut.mergeIf(e,st.global.legend),i?(ke.configure(t,i,e),i.options=e):pn(t,e)):i&&(ke.removeBox(t,i),delete t.legend)},afterEvent:function(t,e){var i=t.legend;i&&i.handleEvent(e)}},vn=ut.noop;st._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var bn=pt.extend({initialize:function(t){ut.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:vn,update:function(t,e,i){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i,n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeBuildLabels(),n.buildLabels(),n.afterBuildLabels(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:vn,beforeSetDimensions:vn,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:vn,beforeBuildLabels:vn,buildLabels:vn,afterBuildLabels:vn,beforeFit:vn,fit:function(){var t=this,e=t.options,i=e.display,n=t.minSize,a=ut.isArray(e.text)?e.text.length:1,o=ut.options._parseFont(e),r=i?a*o.lineHeight+2*e.padding:0;t.isHorizontal()?(n.width=t.maxWidth,n.height=r):(n.width=r,n.height=t.maxHeight),t.width=n.width,t.height=n.height},afterFit:vn,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,i=t.options;if(i.display){var n,a,o,r=ut.options._parseFont(i),s=r.lineHeight,l=s/2+i.padding,d=0,u=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=ut.valueOrDefault(i.fontColor,st.global.defaultFontColor),e.font=r.string,t.isHorizontal()?(a=h+(f-h)/2,o=u+l,n=f-h):(a="left"===i.position?h+l:f-l,o=u+(c-u)/2,n=c-u,d=Math.PI*("left"===i.position?-.5:.5)),e.save(),e.translate(a,o),e.rotate(d),e.textAlign="center",e.textBaseline="middle";var g=i.text;if(ut.isArray(g))for(var p=0,m=0;m=0;n--){var a=t[n];if(e(a))return a}},ut.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},ut.almostEquals=function(t,e,i){return Math.abs(t-e)t},ut.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},ut.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},ut.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0==(t=+t)||isNaN(t)?t:t>0?1:-1},ut.log10=Math.log10?function(t){return Math.log10(t)}:function(t){var e=Math.log(t)*Math.LOG10E,i=Math.round(e);return t===Math.pow(10,i)?i:e},ut.toRadians=function(t){return t*(Math.PI/180)},ut.toDegrees=function(t){return t*(180/Math.PI)},ut._decimalPlaces=function(t){if(ut.isFinite(t)){for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i}},ut.getAngleFromPoint=function(t,e){var i=e.x-t.x,n=e.y-t.y,a=Math.sqrt(i*i+n*n),o=Math.atan2(n,i);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:a}},ut.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},ut.aliasPixel=function(t){return t%2==0?0:.5},ut._alignPixel=function(t,e,i){var n=t.currentDevicePixelRatio,a=i/2;return Math.round((e-a)*n)/n+a},ut.splineCurve=function(t,e,i,n){var a=t.skip?e:t,o=e,r=i.skip?e:i,s=Math.sqrt(Math.pow(o.x-a.x,2)+Math.pow(o.y-a.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),d=s/(s+l),u=l/(s+l),h=n*(d=isNaN(d)?0:d),c=n*(u=isNaN(u)?0:u);return{previous:{x:o.x-h*(r.x-a.x),y:o.y-h*(r.y-a.y)},next:{x:o.x+c*(r.x-a.x),y:o.y+c*(r.y-a.y)}}},ut.EPSILON=Number.EPSILON||1e-14,ut.splineCurveMonotone=function(t){var e,i,n,a,o,r,s,l,d,u=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),h=u.length;for(e=0;e0?u[e-1]:null,(a=e0?u[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},ut.previousItem=function(t,e,i){return i?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},ut.niceNum=function(t,e){var i=Math.floor(ut.log10(t)),n=t/Math.pow(10,i);return(e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10)*Math.pow(10,i)},ut.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},ut.getRelativePosition=function(t,e){var i,n,a=t.originalEvent||t,o=t.target||t.srcElement,r=o.getBoundingClientRect(),s=a.touches;s&&s.length>0?(i=s[0].clientX,n=s[0].clientY):(i=a.clientX,n=a.clientY);var l=parseFloat(ut.getStyle(o,"padding-left")),d=parseFloat(ut.getStyle(o,"padding-top")),u=parseFloat(ut.getStyle(o,"padding-right")),h=parseFloat(ut.getStyle(o,"padding-bottom")),c=r.right-r.left-l-u,f=r.bottom-r.top-d-h;return{x:i=Math.round((i-r.left-l)/c*o.width/e.currentDevicePixelRatio),y:n=Math.round((n-r.top-d)/f*o.height/e.currentDevicePixelRatio)}},ut.getConstraintWidth=function(t){return i(t,"max-width","clientWidth")},ut.getConstraintHeight=function(t){return i(t,"max-height","clientHeight")},ut._calculatePadding=function(t,e,i){return(e=ut.getStyle(t,e)).indexOf("%")>-1?i*parseInt(e,10)/100:parseInt(e,10)},ut._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},ut.getMaximumWidth=function(t){var e=ut._getParentNode(t);if(!e)return t.clientWidth;var i=e.clientWidth,n=i-ut._calculatePadding(e,"padding-left",i)-ut._calculatePadding(e,"padding-right",i),a=ut.getConstraintWidth(t);return isNaN(a)?n:Math.min(n,a)},ut.getMaximumHeight=function(t){var e=ut._getParentNode(t);if(!e)return t.clientHeight;var i=e.clientHeight,n=i-ut._calculatePadding(e,"padding-top",i)-ut._calculatePadding(e,"padding-bottom",i),a=ut.getConstraintHeight(t);return isNaN(a)?n:Math.min(n,a)},ut.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},ut.retinaScale=function(t,e){var i=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==i){var n=t.canvas,a=t.height,o=t.width;n.height=a*i,n.width=o*i,t.ctx.scale(i,i),n.style.height||n.style.width||(n.style.height=a+"px",n.style.width=o+"px")}},ut.fontString=function(t,e,i){return e+" "+t+"px "+i},ut.longestText=function(t,e,i,n){var a=(n=n||{}).data=n.data||{},o=n.garbageCollect=n.garbageCollect||[];n.font!==e&&(a=n.data={},o=n.garbageCollect=[],n.font=e),t.font=e;var r=0;ut.each(i,function(e){null!=e&&!0!==ut.isArray(e)?r=ut.measureText(t,a,o,r,e):ut.isArray(e)&&ut.each(e,function(e){null==e||ut.isArray(e)||(r=ut.measureText(t,a,o,r,e))})});var s=o.length/2;if(s>i.length){for(var l=0;ln&&(n=o),n},ut.numberOfLabelLines=function(t){var e=1;return ut.each(t,function(t){ut.isArray(t)&&t.length>e&&(e=t.length)}),e},ut.color=X?function(t){return t instanceof CanvasGradient&&(t=st.global.defaultColor),X(t)}:function(t){return console.error("Color.js not found!"),t},ut.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:ut.color(t).saturate(.5).darken(.1).rgbString()}}(),ai._adapters=si,ai.Animation=vt,ai.animationService=bt,ai.controllers=ue,ai.DatasetController=Mt,ai.defaults=st,ai.Element=pt,ai.elements=Wt,ai.Interaction=ve,ai.layouts=ke,ai.platform=Ve,ai.plugins=Ee,ai.Scale=fi,ai.scaleService=He,ai.Ticks=li,ai.Tooltip=Je,ai.helpers.each(tn,function(t,e){ai.scaleService.registerScaleType(e,t,t._defaults)}),yn)yn.hasOwnProperty(_n)&&ai.plugins.register(yn[_n]);ai.platform.initialize();var Cn=ai;return"undefined"!=typeof window&&(window.Chart=ai),ai.Chart=ai,ai.Legend=yn.legend._element,ai.Title=yn.title._element,ai.pluginService=ai.plugins,ai.PluginBase=ai.Element.extend({}),ai.canvasHelpers=ai.helpers.canvas,ai.layoutService=ai.layouts,ai.LinearScaleBase=bi,ai.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],function(t){ai[t]=function(e,i){return new ai(e,ai.helpers.merge(i||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}}),Cn}); diff --git a/assets/js/country-select.js b/assets/js/country-select.js new file mode 100755 index 00000000..7c170981 --- /dev/null +++ b/assets/js/country-select.js @@ -0,0 +1,113 @@ +jQuery( document ).ready( function ( $ ) { + + /** + * Country select. + */ + var $country_el = $( '.opalestate-submission-form #opalestate_ppt_location, [name="location"],' + + ' [name="opalestate_ofe_location"], [name="opalestate_agt_location"]' ), + $state_el = $( '.opalestate-submission-form #opalestate_ppt_state, [name="state"],' + + ' [name="opalestate_ofe_state"], [name="opalestate_agt_state"]' ), + $city_el = $( '.opalestate-submission-form #opalestate_ppt_city, [name="city"],' + + ' [name="opalestate_ofe_city"], [name="opalestate_agt_city"]' ); + + $country_el.each( function () { + if ( $( this ).val() != '' && $( this ).val() != '-1' ) { + opalestate_ajax_get_state_by_country( $( this ) ); + } + } ); + + $country_el.on( 'change', function () { + opalestate_ajax_get_state_by_country( $( this ) ); + } ); + + $state_el.on( 'change', function () { + opalestate_ajax_get_city_by_state( $( this ) ); + } ); + + function opalestate_ajax_get_state_by_country( $el ) { + var country = $el.val(); + var is_search = 0; + + if ( $el.closest( '.opalestate-search-form' ).length !== 0 ) { + is_search = 1; + } + + var opalAjaxUrl = opalestate_get_ajax_url(); + + $.ajax( { + type: 'POST', + url: opalAjaxUrl, + data: { + 'action': 'opalestate_ajax_get_state_by_country', + 'country': country, + 'is_search': is_search + }, + success: function ( data ) { + var old_selected = $state_el.val(); + var selected = is_search ? '-1' : ''; + if ( old_selected != '' && old_selected != '-1' ) { + $.each( $.parseJSON( data ), function( key, value ) { + if ( old_selected == value.id ) { + selected = value.id; + } + }); + } + + $state_el.empty(); + $state_el.select2( { + data: $.parseJSON( data ) + } ); + $state_el.val( selected ).trigger( 'change' ); + } + } ); + } + + function opalestate_ajax_get_city_by_state( $el ) { + var state = $el.val(); + var is_search = 0; + + if ( $el.closest( '.opalestate-search-form' ).length !== 0 ) { + is_search = 1; + } + + var opalAjaxUrl = opalestate_get_ajax_url(); + + $.ajax( { + type: 'POST', + url: opalAjaxUrl, + data: { + 'action': 'opalestate_ajax_get_city_by_state', + 'state': state, + 'is_search': is_search + }, + success: function ( data ) { + var old_selected = $city_el.val(); + var selected = is_search ? '-1' : ''; + if ( old_selected != '' && old_selected != '-1' ) { + $.each( $.parseJSON( data ), function( key, value ) { + if ( old_selected == value.id ) { + selected = value.id; + } + }); + } + + $city_el.empty(); + $city_el.select2( { + data: $.parseJSON( data ) + } ); + $city_el.val( selected ).trigger( 'change' ); + } + } ); + } + + function opalestate_get_ajax_url() { + var opalAjaxUrl = ''; + if ( typeof ajaxurl != 'undefined' ) { + opalAjaxUrl = ajaxurl; + } else { + opalAjaxUrl = opalesateJS.ajaxurl; + } + + return opalAjaxUrl; + } +} ); diff --git a/assets/js/frontend/dashboard.js b/assets/js/frontend/dashboard.js new file mode 100755 index 00000000..5aed9929 --- /dev/null +++ b/assets/js/frontend/dashboard.js @@ -0,0 +1,186 @@ +;(function ($, settings) { + "use strict"; + + if (window.Opalestate === undefined) { + window.Opalestate = {}; + } + + /** + * GooglemapSearch + */ + var AgencyUpdateProfile = Opalestate.AgencyUpdateProfile = function ( form ) { + + /** + * Create Google Map In Single Property Only + */ + function getFormData () { + + var formData = new FormData(); + + formData.append('section', 'general'); + $(".cmb2-uploader-files").each( function(){ + var file_btn = $( 'input.select-file', this ); + + var files = $(".uploader-item-preview", this ); + + var name = $(this).data( 'name' ); + var issingle = $( this ).data('single'); + $(files).each( function( i , element ){ + var file = $(this).prop( 'file'); + if( file ) { + if( issingle ){ + formData.append( name, file ); + } else { + formData.append( name+"["+i+"]", file ); + } + } + } ); + }); + + return formData; + } + + + function toggleSubmit ( _this ){ + if( $( _this ).attr('disabled') == "disabled" ){ + $( _this ).removeAttr( 'disabled' ); + $(_this).find('i').remove( ); + } else { + $( _this ).attr('disabled','disabled'); + $(_this).append( ' ' ); + } + + }; + + function makeAjax( formData, $submit_btn ) { + $.ajax({ + url : opalesateJS.ajaxurl, + data : formData, + type : 'POST', + processData: false, + contentType: false, + dataType: "json", + success : function( response ){ + if( response.status == true ){ + if( response.redirect ){ + window.location.href = response.redirect; + } + + var myToast = $.toast({ + heading: response.heading, + text: response.message, + icon: 'success', + position: 'bottom-right', + hideAfter: 5000, + showHideTransition: 'fade', + }); + } else { + toggleSubmit( $submit_btn ); + var myToast = $.toast({ + heading: response.heading, + text: response.message, + icon: 'error', + position: 'bottom-right', + hideAfter: 5000, + showHideTransition: 'fade' + }); + } + } + }); + } + + var init = function ( form ){ + $( form ).on( "submit", function(){ + + if( typeof(tinyMCE) != "undefined" ) { + tinyMCE.triggerSave(); + } + + toggleSubmit( $("button:submit" , form ) ) ; + + var formData = getFormData(); + var dataSubmit = $( form ).serializeArray(); + + $.each( dataSubmit, function ( key, input ) { + formData.append( input.name, input.value ); + }); + + makeAjax( formData, $("button:submit" , form ) ) + return false; + } ); + } + init( form ); + } + + + ///// + $(document).ready(function () { + /// update agency profile + if( $("#opalestate_ofe_front").length > 0 ){ + new AgencyUpdateProfile( $("#opalestate_ofe_front") ); + } + // update agent profile + if( $("#opalestate_agt_front").length > 0 ){ + new AgencyUpdateProfile( $("#opalestate_agt_front") ); + } + + if( $("#opalestate_user_front").length > 0 ){ + new AgencyUpdateProfile( $("#opalestate_user_front") ); + } + + if( $("#opalestate-add-team-form").length > 0 ){ + function formatRepo (repo) { + if ( repo.loading ) { + return repo.text; + } + var markup = "
            " + + "
            " + + "
            " + + "
            " + repo.full_name + "
            "; + markup += "
            "; + return markup; + } + + function formatRepoSelection (repo) { + return repo.full_name || repo.text; + } + function load_select2_member ( id, action ) { + $( id ).select2({ + width: '100%', + ajax: { + url: opalesateJS.ajaxurl+"?action="+action, + dataType: 'json', + delay: 250, + data: function (params) { + return { + q: params.term, // search term + page: params.page + }; + }, + processResults: function (data, params) { + params.page = params.page || 1; + + return { + results: data.items, + pagination: { + more: (params.page * 30) < data.total_count + } + }; + }, + cache: true + }, + placeholder: 'Search for a repository', + escapeMarkup: function (markup) { return markup; }, // let our custom formatter work + minimumInputLength: 1, + templateResult: formatRepo, + templateSelection: formatRepoSelection + }); + } + + load_select2_member( ".opalesate-find-user", 'opalestate_search_property_users'); + } + + } ); + +})(jQuery); + \ No newline at end of file diff --git a/assets/js/frontend/elementor.js b/assets/js/frontend/elementor.js new file mode 100755 index 00000000..505df7e8 --- /dev/null +++ b/assets/js/frontend/elementor.js @@ -0,0 +1,86 @@ +(function ($ ) { + "use strict"; + + var carouselSlick = function( $scope , $selector, elementorFrontend ) { + + + var slidesToShow = 0; + + var elementSettings = $scope.data('settings'); + + if( elementSettings === undefined ){ + var elementSettings = $scope.find(".elementor-opal-slick-slider").data('settings'); + } + // console.log( elementSettings ); + if( elementSettings === undefined ){ + return true; + } + + var slidesToShow =+ elementSettings.slides_to_show || 3, + isSingleSlide = 1 === slidesToShow, + breakpoints = elementorFrontend.config.breakpoints; + + var slickOptions = { + slidesToShow: slidesToShow, + autoplay: 'yes' === elementSettings.autoplay, + autoplaySpeed: elementSettings.autoplay_speed, + infinite: 'yes' === elementSettings.infinite, + pauseOnHover: 'yes' === elementSettings.pause_on_hover, + speed: elementSettings.speed, + arrows: -1 !== [ 'arrows', 'both' ].indexOf( elementSettings.navigation ), + dots: -1 !== [ 'dots', 'both' ].indexOf( elementSettings.navigation ), + rtl: 'rtl' === elementSettings.direction, + responsive: [ + { + breakpoint: breakpoints.lg, + settings: { + slidesToShow: +elementSettings.slides_to_show_tablet || ( isSingleSlide ? 1 : 2 ), + slidesToScroll: 1, + }, + }, + { + breakpoint: breakpoints.md, + settings: { + slidesToShow: +elementSettings.slides_to_show_mobile || 1, + slidesToScroll: 1, + }, + }, + ], + }; + + if ( isSingleSlide ) { + slickOptions.fade = 'fade' === elementSettings.effect; + } else { + slickOptions.slidesToScroll = +elementSettings.slides_to_scroll; + } + + var $carousel = $scope.find( $selector ); + // $carousel.removeClass('products'); + $carousel.slick( slickOptions ); + // $carousel.addClass('products'); + } + + /// // / / / / + $(window).on('elementor/frontend/init', function(){ + + elementorFrontend.hooks.addAction( 'frontend/element_ready/opalestate-agent-collection.default', function( $scope ) { + if( $scope.find(".elementor-opal-slick-slider") ) { + carouselSlick( $scope, '.elementor-slick-slider-row.row-items', elementorFrontend ); + } + } ); + + elementorFrontend.hooks.addAction( 'frontend/element_ready/opalestate-property-collection.default', function( $scope ) { + if( $scope.find(".elementor-opal-slick-slider") ) { + carouselSlick( $scope, '.elementor-slick-slider-row.row-items' , elementorFrontend ); + } + } ); + + elementorFrontend.hooks.addAction( 'frontend/element_ready/opalestate-category-list.default', function( $scope ) { + if( $scope.find(".elementor-opal-slick-slider") ) { + carouselSlick( $scope, '.elementor-slick-slider-row.row-items' , elementorFrontend ); + } + } ); + + }); + +})( jQuery ); diff --git a/assets/js/frontend/googlemaps.js b/assets/js/frontend/googlemaps.js new file mode 100755 index 00000000..54ce1fd0 --- /dev/null +++ b/assets/js/frontend/googlemaps.js @@ -0,0 +1,621 @@ +;(function ($, settings) { + "use strict"; + + if (window.Opalestate === undefined) { + window.Opalestate = {}; + } + + /** + * GooglemapSearch + */ + var GooglemapSingle = Opalestate.GooglemapSingle = function ( data , id ) { + + /** + * Create Google Map In Single Property Only + */ + var initializePropertyMap = function ( data , id ){ + + var propertyMarkerInfo = data; + var enable = true ; + var url = propertyMarkerInfo.icon; + var size = new google.maps.Size( 42, 57 ); + + + var allMarkers = []; + + var setMapOnAll = function (markers, map) { + for (var i = 0; i < markers.length; i++) { + markers[i].setMap( map ); + } + } + // retina + if( window.devicePixelRatio > 1.5 ) { + if ( propertyMarkerInfo.retinaIcon ) { + url = propertyMarkerInfo.retinaIcon; + size = new google.maps.Size( 83, 113 ); + } + } + + var propertyLocation = new google.maps.LatLng( propertyMarkerInfo.latitude, propertyMarkerInfo.longitude ); + var propertyMapOptions = { + center: propertyLocation, + zoom: 15, + mapTypeId: google.maps.MapTypeId.ROADMAP, + scrollwheel: false + }; + var propertyMap = new google.maps.Map( document.getElementById( id ), propertyMapOptions ); + + /** + * + */ + + var createMarker = function ( position, icon ) { + + var image = { + url: icon, + size: size, + scaledSize: new google.maps.Size( 32, 57 ), + origin: new google.maps.Point( 0, 0 ), + anchor: new google.maps.Point( 21, 56 ) + }; + + var _marker = new google.maps.Marker({ + map: propertyMap, + position: position, + icon: image + }); + return _marker; + } + + + var infowindow = new google.maps.InfoWindow(); + + createMarker( propertyLocation, url ); + + /** + * Places near with actived types + */ + if( enable ){ + var $navs = $("#"+id).parent().find( '.property-search-places' ); + $(' .btn-map-search', $navs ).unbind('click').bind( 'click', function(){ + var service = new google.maps.places.PlacesService( propertyMap ) ; + var type = $(this).data('type'); + var $this = $(this).parent(); + + var icon = { + url: opalesateJS.mapiconurl+$(this).data('icon'), + scaledSize: new google.maps.Size( 28, 28 ), + anchor: new google.maps.Point( 21, 16 ), + origin: new google.maps.Point( 0, 0 ) + }; + + if( !allMarkers[type] || allMarkers[type].length <= 0 ){ + var markers = [] ; + var bounds = propertyMap.getBounds(); + + var $this = $(this); + + service.nearbySearch({ + location: propertyLocation, + radius: 2000, + bounds: bounds, + type: type + }, callbackNearBy); + + function callbackNearBy(results, status) { + if (status === google.maps.places.PlacesServiceStatus.OK) { + for (var i = 0; i < results.length; i++) { + createMarkerNearBy(results[i]); + } + + $('.nearby-counter',$this).remove(); + $('span',$this).append( $(''+markers.length+'') ); + allMarkers[type] = markers; + } + } + + function abc(){ + if (status === google.maps.places.PlacesServiceStatus.OK) { + for (var i = 0; i < results.length; i++) { + var place = results[i]; + var marker = new google.maps.Marker({ + map: propertyMap, + position: place.geometry.location, + icon: icon, + visible: true + }); + + marker.setMap( propertyMap ); + + google.maps.event.addListener(marker, 'click', function() { + + infowindow.setContent( place.name ); + + infowindow.open(propertyMap, this); + }); + + markers.push( marker ); + } + $('.nearby-counter',$this).remove(); + $('span',$this).append( $(''+markers.length+'') ); + allMarkers[type] = markers; + //console.log( place ); + } + } + + function createMarkerNearBy(place) { + var placeLoc = place.geometry.location; + var marker = new google.maps.Marker({ + map: propertyMap, + position: place.geometry.location, + icon: icon, + visible: true + }); + + marker.setMap( propertyMap ); + + google.maps.event.addListener(marker, 'click', function() { + infowindow.setContent(place.name); + infowindow.open(propertyMap, this); + }); + + markers.push( marker ); + } + }else { + for( var i=0 ; i < allMarkers[type].length; i++ ){ + allMarkers[type][i].setMap( null ); + } + allMarkers[type] = []; + } + + $(this).toggleClass('active'); + } ); + } + } + initializePropertyMap( data , id ); + } + + var GoogleMapSearch = Opalestate.GooglemapSingle = function ( data ) { + var initializePropertiesMap = function ( properties ) { + // Properties Array + var mapOptions = { + zoom: 12, + maxZoom: 16, + scrollwheel: false, + mapTypeId: google.maps.MapTypeId.ROADMAP, + panControl: false, + zoomControl: true, + mapTypeControl: false, + scaleControl: false, + streetViewControl: true, + overviewMapControl: false, + zoomControlOptions: { + style: google.maps.ZoomControlStyle.SMALL, + position: google.maps.ControlPosition.RIGHT_TOP + }, + streetViewControlOptions: { + position: google.maps.ControlPosition.RIGHT_TOP + } + }; + + var map = new google.maps.Map( document.getElementById( "opalestate-map-preview" ), mapOptions ); + + var bounds = new google.maps.LatLngBounds(); + + // Loop to generate marker and infowindow based on properties array + var markers = new Array(); + + for ( var i=0; i < properties.length; i++ ) { + + // console.log( properties[i] ); + var url = properties[i].icon; + var size = new google.maps.Size( 42, 57 ); + if( window.devicePixelRatio > 1.5 ) { + if ( properties[i].retinaIcon ) { + url = properties[i].retinaIcon; + size = new google.maps.Size( 83, 113 ); + } + } + + var image = { + url: url, + size: size, + scaledSize: new google.maps.Size( 30, 51 ), + origin: new google.maps.Point( 0, 0 ), + anchor: new google.maps.Point( 21, 56 ) + }; + + markers[i] = new google.maps.Marker({ + position: new google.maps.LatLng( properties[i].lat, properties[i].lng ), + map: map, + icon: image, + title: properties[i].title, + animation: google.maps.Animation.DROP, + visible: true + }); + + bounds.extend( markers[i].getPosition() ); + + var boxText = document.createElement( "div" ); + var pricelabel = ''; + + if( properties[i].pricelabel ){ + pricelabel = ' / ' + properties[i].pricelabel; + } + + // console.log( properties[i] ); + boxText.className = 'map-info-preview media'; + + var meta = '
              '; + if( properties[i].metas ){ + for ( var x in properties[i].metas ){ + var m = properties[i].metas[x]; + meta += '
            • ' + m.value +'' + m.label + '
            • ' + } + } + meta += '
            '; + + boxText.innerHTML = '
            ' + + '' + properties[i].title + '' + + ''+ properties[i].status +'
            ' + + '
            ' + + '
            ' + properties[i].title + + '

            ' + properties[i].address + '

            ' + properties[i].pricehtml + pricelabel + + '

            '+meta+'
            '+'
            '; + + var myOptions = { + content: boxText, + disableAutoPan: true, + maxWidth: 0, + alignBottom: true, + pixelOffset: new google.maps.Size( -122, -48 ), + zIndex: null, + closeBoxMargin: "0 0 -16px -16px", + closeBoxURL: opalesateJS.mapiconurl+"close.png", + infoBoxClearance: new google.maps.Size( 1, 1 ), + isHidden: false, + pane: "floatPane", + enableEventPropagation: false + }; + + var ib = new InfoBox( myOptions ); + + attachInfoBoxToMarker( map, markers[i], ib, i ); + } + + var last = null ; + + $('body').delegate( '[data-related="map"]', 'mouseenter', function(){ + if( $(this).hasClass('map-active') ){ + return true; + } + + var i = $(this).data( 'id' ); + $( '[data-related="map"]' ).removeClass( 'map-active' ); + $(this).addClass( 'active' ); + map.setZoom( 65536 );// alert( scale ); + + if( markers[i] ){ + var marker = markers[i]; + google.maps.event.trigger( markers[i], 'click' ); + + var scale = Math.pow( 2, map.getZoom() ); + var offsety = ( (100/scale) || 0 ); + var projection = map.getProjection(); + var markerPosition = marker.getPosition(); + var markerScreenPosition = projection.fromLatLngToPoint( markerPosition ); + var pointHalfScreenAbove = new google.maps.Point( markerScreenPosition.x, markerScreenPosition.y - offsety ); + var aboveMarkerLatLng = projection.fromPointToLatLng( pointHalfScreenAbove ); + map.setZoom( scale ); + map.setCenter( aboveMarkerLatLng ); + + } + return false; + }); + + map.fitBounds(bounds); + + /* Marker Clusters */ + var markerClustererOptions = { + ignoreHidden: true, + maxZoom: 14, + styles: [{ + textColor: '#000000', + url: opalesateJS.mapiconurl+"cluster-icon.png", + height: 51, + width: 30 + }] + }; + + var markerClusterer = new MarkerClusterer( map, markers, markerClustererOptions ); + + + + function attachInfoBoxToMarker( map, marker, infoBox , i ){ + + google.maps.event.addListener( marker, 'click', function(){ + + if( $( '[data-related="map"]' ).filter('[data-id="'+i+'"]').length > 0 ){ + var $m = $( '[data-related="map"]' ).filter('[data-id="'+i+'"]'); + $( '[data-related="map"]' ).removeClass( 'map-active' ); + $m.addClass('map-active'); + } + + if( last != null ){ + last.close(); + } + + var scale = Math.pow( 2, map.getZoom() ); + var offsety = ( (100/scale) || 0 ); + var projection = map.getProjection(); + var markerPosition = marker.getPosition(); + var markerScreenPosition = projection.fromLatLngToPoint( markerPosition ); + var pointHalfScreenAbove = new google.maps.Point( markerScreenPosition.x, markerScreenPosition.y - offsety ); + var aboveMarkerLatLng = projection.fromPointToLatLng( pointHalfScreenAbove ); + map.setCenter( aboveMarkerLatLng ); + infoBox.open( map, marker ); + last = infoBox; + }); + } + } + initializePropertiesMap( data ); + } + + ///// + $(document).ready(function () { + + function initialize_property_street_view( data , id ){ + + var propertyMarkerInfo = data; + + var propertyLocation = new google.maps.LatLng( propertyMarkerInfo.latitude, propertyMarkerInfo.longitude ); + + /** + * Street View + */ + var panoramaOptions = { + position: propertyLocation, + pov: { + heading: 34, + pitch: 10 + } + }; + var panorama = new google.maps.StreetViewPanorama( document.getElementById( id ), panoramaOptions); + google.maps.event.trigger(panorama, 'resize'); + } + + $( ".property-preview-map").each( function(){ + new GooglemapSingle( $(this).data() , $(this).attr('id') ); + } ); + + $( ".tab-google-street-view-btn") .click( function(){ + $( ".property-preview-street-map").hide(); + $( ".property-preview-street-map").each( function(){ + + var d = $(this).data() ; + var i = $(this).attr('id') ; + + initialize_property_street_view( d , i ); + } ); + $( ".property-preview-street-map").show( 100 ); + } ); + /// + // auto set height for split google map + $( '.split-maps-container' ).each( function() { + $( "#opalestate-map-preview ").height( $(window).height() ); + } ); + }) + + + $(document).ready(function () { + + // search + // show google maps + // update google maps + var updatePreviewGoogleMap = function( url ) { + if( $('#opalestate-map-preview').length > 0 ) { + $.ajax({ + type: 'GET', + dataType: 'json', + url: opalesateJS.ajaxurl, + data: url, + success: function(data) { + new GoogleMapSearch( data ); + } + }); + } + }; + if( $('#opalestate-map-preview').length > 0 || $( '.opalesate-properties-results').length > 0 ) { + var currentLocation = location.search.substr(1)+"&action=opalestate_ajx_get_properties&paged="+$('#opalestate-map-preview').data('page'); + updatePreviewGoogleMap( currentLocation ); + } + // update results + function updatePropertiesResults( data ){ + $( '.opalesate-properties-results').append( $('
            ') ); + $.ajax({ + type: "GET", + url: opalesateJS.ajaxurl, + data: data+"&action=opalestate_render_get_properties" , + success: function( response ) { + if( response ){ + + $( '.opalesate-properties-results' ).html( response ); + } + $( '.opalesate-properties-results .opalestate-loading').remove(); + $('.opalestate-sortable select').select2( { + width: '100%', + minimumResultsForSearch: -1 + } ); + } + }); + } + + function updatePropertiesByParseringHtml( newurl ){ + $( '.opalesate-properties-results .opalesate-archive-bottom').append( $('
            ') ); + $.ajax({ + type: "GET", + url: newurl, + dataType : 'html', + cache: false, + success: function( data ) { + if( data ){ + $( '.opalesate-properties-results' ).html( $(data).find('.opalesate-properties-results').html() ); + $('.opalestate-sortable select').select2( { + width: '100%', + minimumResultsForSearch: -1 + } ); + } + // $( '.opalesate-properties-results .opalestate-loading').remove(); + } + }); + } + + + $('form.opalestate-search-form').submit( function ( ){ + if( $('#opalestate-map-preview').length > 0 ) { + if( $(".opalesate-properties-results") && $(".opalesate-properties-results").data('mode') == 'html' ) { + var $form = $(this); + if (history.pushState) { + var ps = $form.serialize(); + var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?'+ ps; + window.history.pushState({path:newurl},'',newurl); + updatePropertiesByParseringHtml( newurl ); + } + + } else { + updatePropertiesResults( $(this).serialize() ); + } + + return false; + } + return true; + } ); + + + $( '.ajax-search-form form.opalestate-search-form' ).each( function(){ + var $form = $(this); + $( '.ajax-change select', this ).change( function(){ + if (history.pushState) { + var ps = $form.serialize(); + var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?'+ ps; + window.history.pushState({path:newurl},'',newurl); + } + $form.submit(); + return false; + } ); + } ); + + // // Sortable Change // // + $("body").delegate( '#opalestate-sortable-form select', 'change', function(){ + + var ps = ''; + if( $('form.opalestate-search-form').length > 0 ) { + var $form =$('form.opalestate-search-form'); + var ps = $form.serialize()+"&opalsortable="+$(this).val()+"&display="+$(".display-mode a.active").data('mode'); + } + + if( $(".opalesate-properties-results") && ps ) { + if (history.pushState) { + var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?'+ ps; + window.history.pushState({path:newurl},'',newurl); + updatePropertiesByParseringHtml( newurl ); + } + } else { + $("#opalestate-sortable-form").submit(); + } + } ); + // display mode + $( "body" ).delegate( ".display-mode a", 'click', function() { + if( $(".opalesate-properties-results").length > 0 ){ + var newurl = $(this).attr('href'); + window.history.pushState({path:newurl},'',newurl); + updatePropertiesByParseringHtml( newurl ); + return false; + } + } ); + // check any estate search form is enabled ///////////////// + if( $('#opalestate-map-preview').length > 0 ) { + $( "body" ).delegate( "form.opalestate-search-form select", "change", function () { + var params = $( "form.opalestate-search-form" ).serialize(); + var url = "action=opalestate_ajx_get_properties&"+params; + + updatePreviewGoogleMap( url ); + $('form.opalestate-search-form').submit(); + return true; + } ); + + $( "body" ).delegate( "form.opalestate-search-form input", "change", function () { + + if( $(this).hasClass("ranger-geo_radius") ){ + return false; + } + + var params = $( "form.opalestate-search-form" ).serialize(); + var url = "action=opalestate_ajx_get_properties&"+params; + updatePreviewGoogleMap( url ); + $('form.opalestate-search-form').submit(); + } ); + } + /////////// /////// + + + } ); +})(jQuery); + +//// ////// +(function( $ ) { + 'use strict'; + + + $(document).ready(function () { + $( '.opalestate-search-opal-map' ).each( function() { + initializeMapAdressSearch( $(this) ); + }); + } ); + + + function initializeMapAdressSearch( mapInstance ) { + var searchInput = mapInstance.find( '.opal-map-search' ); + + // Search + var autocomplete = new google.maps.places.Autocomplete( searchInput[0] ); + // autocomplete.bindTo( 'bounds', map ); + var latitude = mapInstance.find( '.opal-map-latitude' ); + var longitude = mapInstance.find( '.opal-map-longitude' ); + + google.maps.event.addListener( autocomplete, 'place_changed', function() { + + var place = autocomplete.getPlace(); + + + if ( ! place.geometry ) { + return; + } + + if( place.geometry.location.lat() ){ + $(mapInstance).addClass("active"); + } else { + $(mapInstance).removeClass("active"); + } + + latitude.val( place.geometry.location.lat() ); + longitude.val( place.geometry.location.lng() ); + }); + + $( ".map-remove", mapInstance ).click( function() { + latitude.val( "" ); + longitude.val( "" ); + searchInput.val(""); + latitude.change(); + } ); + + $( searchInput ).keypress( function( event ) { + if ( 13 === event.keyCode ) { + event.preventDefault(); + } + }); + + + } + +})( jQuery ); \ No newline at end of file diff --git a/assets/js/frontend/property.js b/assets/js/frontend/property.js new file mode 100755 index 00000000..23d69a75 --- /dev/null +++ b/assets/js/frontend/property.js @@ -0,0 +1,263 @@ +/* global tinymce, wpCookies, autosaveL10n, switchEditors */ +// Back-compat +window.opalestate_messages = function() { + return true; +}; + +/** + * @summary Adds autosave to the window object on dom ready. + * + * @since 3.9.0 + * + * @param {jQuery} $ jQuery object. + * @param {window} The window object. + * + */ + +( function( $, window ) { + + /** + * @summary Auto saves the post. + * + * @since 3.9.0 + * + * @returns {Object} + * {{ + * getPostData: getPostData, + * getCompareString: getCompareString, + * disableButtons: disableButtons, + * enableButtons: enableButtons, + * local: ({hasStorage, getSavedPostData, save, suspend, resume}|*), + * server: ({tempBlockSave, triggerSave, postChanged, suspend, resume}|*)} + * } + * The object with all functions for autosave. + */ + + function opalestate_messages() { + + var $document = $( document ); + var $page = $( '#page-importer' ); + + /** + * + */ + function trigger_send_messages(){ + $( ".opalestate-message-form" ).on('submit', function(){ + make_ajax( $( this ).serialize(), this ); + return false; + } ); + } + + + function toggle_submit_button ( submit ){ + var _this = $('button[type="submit"]', submit ); + if( $( _this ).attr('disabled') == "disabled" ){ + $( _this ).removeAttr( 'disabled' ); + $(_this).find('i').remove( ); + } else { + $( _this ).attr('disabled','disabled'); + $(_this).append( '' ); + } + + }; + + function trigger_send_reply(){ + $( ".opalestate-form-reply" ).on( "submit" , function(){ + var message = $( 'textarea', this).val(); + if( message ) { + make_ajax_reply( $( this ).serialize(), this ); + } + + return false; + } ); + } + + function make_ajax_reply( data, _this ){ + + $( '.opalestate-message-notify', _this ).remove(); + $.ajax({ + type : 'POST', + dataType : 'json', + url : opalesateJS.ajaxurl, + data : 'action=send_email_contact_reply&' + data, + success: function( response ) { + if( response ) { + var _class = response.status ? 'success' : 'danger'; + // $( _this ).append('

            '+ response.msg +'

            '); + if( response.status ){ + $( 'textarea', _this ).val( "" ); + var myToast = $.toast({ + heading: response.heading, + text: response.msg, + icon: 'success', + position: 'bottom-right', + hideAfter: 3500, + showHideTransition: 'fade' + }); + if ( response.data ){ + var html = '
            '; + html += '
            '; + html += ''; + html += '
            '; + html += '
            '+response.data.created+'
            ' + response.data.message; + html += '
            '; + html += '
            '; + + $(".opalestate-read-message").append( html ); + } + } else { + + } + } + } + }); + } + + function load_message_reply(){ + + } + + function make_ajax ( data, _this ) { + $( '.opalestate-message-notify', _this ).remove(); + var action = $( _this ).data('action')? $( _this ).data('action') : 'send_email_contact'; + toggle_submit_button( _this ); + $.ajax({ + type : 'POST', + dataType : 'json', + url : opalesateJS.ajaxurl, + data : 'action='+action+'&' + data, + success: function( response ) { + if( response ) { + var _class = response.status ? 'success' : 'danger'; + $( _this ).append('

            '+ response.msg +'

            '); + if( response.status ){ + $( 'textarea', _this ).val( "" ); + } + toggle_submit_button( _this ); + } + } + }); + } + + function trigger_print_property() { + $( '.js-print-property' ).on( 'click', function ( e ) { + e.preventDefault(); + + var id = $( this ).data( 'id' ); + var newWindown = window.open( '', 'Print!', 'width=800 ,height=850' ); + + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + data: { + 'action': 'opalestate_ajax_create_property_print', + 'id': id, + }, + success: function ( data ) { + newWindown.document.write( data ); + newWindown.document.close(); + newWindown.focus(); + + setTimeout( function () { + newWindown.print(); + }, 1000 ); + } + } ); + } ); + } + + function trigger_toggle_featured() { + /// ajax set featured + $( 'body' ).delegate( '.btn-toggle-featured', 'click', function () { + var $this = $( this ); + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + data: 'property_id=' + $( this ).data( 'property-id' ) + '&action=opalestate_toggle_featured_property', // elements. + dataType: 'json', + success: function ( data ) { + if ( data.status ) { + $( '[data-id="property-toggle-featured-' + $this.data( 'property-id' ) + '"]' ) + .removeClass( 'hide' ); + $this.remove(); + } else { + alert( data.msg ); + } + } + } ); + return false; + } ); + } + + function trigger_view_gallery(){ + $( 'body' ).delegate( '.opalestate-ajax-gallery', 'click', function () { + var parent = $(this).parent(); + var open_gallery = function ( parent ){ + $(parent ).magnificPopup({ + type: 'image', + delegate: 'a.gallery-item', + gallery:{ + enabled:true + } + }); + $( 'a.gallery-item', parent ).trigger('click'); + } + if( $(".gallery-item", parent ).length <= 0 ){ + var items = []; + + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + data: 'property_id=' + $( this ).data( 'id' ) + '&action=opalestate_gallery_property', // elements. + dataType: 'json', + success: function ( data ) { + if( data.gallery ){ + for( var image in data.gallery ){ + parent.append( '' ); + } + + } + open_gallery( parent ); + } + } ); + } else { + open_gallery( parent ); + } + + return false; + } ); + } + /** + * @summary Sets the autosave time out. + * + * Wait for TinyMCE to initialize plus 1 second. for any external css to finish loading, + * then save to the textarea before setting initialCompareString. + * This avoids any insignificant differences between the initial textarea content and the content + * extracted from the editor. + * + * @since 3.9.0 + * + * @returns {void} + */ + $document.on( '.opalestate-message-form', function( event, editor ) { + + }).ready( function() { + trigger_send_messages(); + trigger_send_reply(); + + trigger_print_property(); + trigger_toggle_featured(); + + trigger_view_gallery(); + }); + + return { + + }; + } + + /** @namespace wp */ + window.wp = window.wp || {}; + window.wp.opalestate_messages = opalestate_messages(); + +}( jQuery, window )); \ No newline at end of file diff --git a/assets/js/frontend/submission.js b/assets/js/frontend/submission.js new file mode 100755 index 00000000..0190dece --- /dev/null +++ b/assets/js/frontend/submission.js @@ -0,0 +1,245 @@ +jQuery( document ).ready( function ( $ ) { + 'use strict'; + + + var toggleSubmit = function ( _this ){ + if( $( _this ).attr('disabled') == "disabled" ){ + $( _this ).removeAttr( 'disabled' ); + $(_this).find('i').remove( ); + } else { + $( _this ).attr('disabled','disabled'); + $(_this).append( '' ); + } + + }; + + $( '.opalestate-submission-tab' ).each( function () { + var $submission_tab = $( this ); + var $submit_btn = $submission_tab.find( '[name=submit-cmb]' ); + var $next_btn = $( '.submission-next-btn' ); + var $back_btn = $( '.submission-back-btn' ); + var $tab_content = $submission_tab.find( '.opalestate-tab-content' ); + + $submission_tab.find( '.tab-item' ).first().addClass( 'active' ); + $tab_content.first().addClass( 'active' ); + if ( $tab_content.length != 1 ) { + $submit_btn.hide(); + } else { + $next_btn.hide(); + } + + $submit_btn.on( 'click', function ( e ) { + e.preventDefault(); + var empty_required_inputs = opalestate_get_empty_required_inputs( $submission_tab ); + if ( empty_required_inputs.length === 0 ) { + $submit_btn.parents( 'form' ).submit(); + } + } ); + + /* + $next_btn.click( function(){ + // $submit_btn.click(); + + return false; + }); + */ + var submitFormFiles = function ( name, files ) { + + var formData = new FormData(); + + formData.append('section', 'general'); +// formData.append('action', 'opalestate_submitted_property'); + + + $(".cmb2-uploader-files").each( function(){ + var file_btn = $( 'input.select-file', this ); + + var files = $(".uploader-item-preview", this ); + + var name = $(this).data( 'name' ); + var issingle = $( this ).data('single'); + $(files).each( function( i , element ){ + var file = $(this).prop( 'file'); + if( file ) { + if( issingle ){ + formData.append( name, file ); + } else { + formData.append( name+"["+i+"]", file ); + } + } + } ); + }); + + // console.log( formData ); + + var dataSubmit = $submit_btn.parents( 'form' ).serializeArray(); + + $.each( dataSubmit, function ( key, input ) { + formData.append( input.name, input.value ); + }); + + formData.append('action', 'opalestate_save_agency_data'); + toggleSubmit( $submit_btn ); + $.ajax({ + url : opalesateJS.ajaxurl, + data : formData, + type : 'POST', + processData: false, + contentType: false, + dataType: "json", + success : function( response ){ + if( response.status == true ){ + if( response.redirect ){ + window.location.href = response.redirect; + } + + var myToast = $.toast({ + heading: response.heading, + text: response.message, + icon: 'success', + position: 'bottom-right', + hideAfter: 5000, + showHideTransition: 'fade', + }); + } else { + toggleSubmit( $submit_btn ); + var myToast = $.toast({ + heading: response.heading, + text: response.message, + icon: 'error', + position: 'bottom-right', + hideAfter: 5000, + showHideTransition: 'fade' + }); + } + } + }); + } + + $submit_btn.parents( 'form' ).on('submit', function() { + submitFormFiles(); + return false; + } ); + + + // Clicking Next button + $next_btn.on( 'click', function ( e ) { + e.preventDefault(); + var $tab_content = $( this ).parents( '.opalestate-tab-content' ); + var empty_required_inputs = opalestate_get_empty_required_inputs( $tab_content ); + + if ( empty_required_inputs.length === 0 ) { + var $next_tab_content = $tab_content.next(); + if ( $next_tab_content.length != 0 ) { + $submission_tab.find( '.opalestate-tab-content' ).removeClass( 'active' ); + $submission_tab.find( '.tab-item.active' ) + .removeClass( 'active' ) + .addClass( 'validated' ) + .addClass( 'passed' ) + .next() + .addClass( 'active' ); + $tab_content.addClass( 'validated' ).addClass( 'passed' ); + $next_tab_content.addClass( 'active' ); + + $( 'html, body' ).animate( { + scrollTop: $next_tab_content.offset().top - 100 + }, 500 ); + + // Show Save button if is last tab. + if ( $next_tab_content.is( ':last-child' ) ) { + $next_btn.hide(); + $submit_btn.show(); + } + } + } + } ); + + // Clicking Back button + $back_btn.on( 'click', function ( e ) { + e.preventDefault(); + var $tab_content = $( this ).parents( '.opalestate-tab-content' ); + + $submission_tab.find( '.opalestate-tab-content' ).removeClass( 'active' ); + $submission_tab.find( '.tab-item.active' ) + .removeClass( 'active' ) + .removeClass( 'passed' ) + .prev() + .addClass( 'active' ); + $tab_content.removeClass( 'active' ); + + var $prev_tab_content = $tab_content.prev(); + + if ( $prev_tab_content.length != 0 ) { + $prev_tab_content.addClass( 'active' ).removeClass( 'passed' ); + $( 'html, body' ).animate( { + scrollTop: $prev_tab_content.offset().top - 100 + }, 500 ); + } + + $submit_btn.hide(); + $next_btn.show(); + } ); + + $( '.tab-item' ).on( 'click', function ( e ) { + e.preventDefault(); + var $el = $( this ); + var $prev_tab_item = $el.prev(); + if ( $el.hasClass( 'validated' ) || ($prev_tab_item.length != 0 && $prev_tab_item.hasClass( 'validated' ) && + $prev_tab_item.hasClass( 'passed' )) ) { + $submission_tab.find( '.opalestate-tab-content' ).removeClass( 'active' ); + $submission_tab.find( '.tab-item.active' ).removeClass( 'active' ); + var $tab_id = $el.attr( 'href' ); + var $prev_tab_content = $( $tab_id ).prev(); + var $next_tab_content = $( $tab_id ).next(); + + if ( $prev_tab_content.length != 0 ) { + $back_btn.show(); + } else { + $back_btn.hide(); + } + + if ( $next_tab_content.length != 0 ) { + $next_btn.show(); + $submit_btn.hide(); + } else { + $next_btn.hide(); + $submit_btn.show(); + } + + $el.addClass( 'active' ); + $( $tab_id ).addClass( 'active' ); + } + } ); + } ); + + function opalestate_get_empty_required_inputs( el_wrapper ) { + var empty_required_inputs = []; + el_wrapper.find( 'input' ).each( function () { + $( this ).removeClass( 'required' ); + $( this ).blur(); + + if ( $( this ).prop( 'required' ) ) { + if ( $( this ).val() == '' ) { + $( this ).addClass( 'required' ); + $( this ).focus(); + empty_required_inputs.push( $( this ) ); + } + } + } ); + + return empty_required_inputs; + } + + $( '.opalestate-tab-content input' ).each( function ( e ) { + if ( $( this ).prop( 'required' ) ) { + $( this ).on( 'input', function () { + if ( $( this ).val() == '' ) { + $( this ).addClass( 'required' ); + $( this ).focus(); + } else { + $( this ).removeClass( 'required' ); + } + } ); + } + } ); +} ); diff --git a/assets/js/frontend/uploader.js b/assets/js/frontend/uploader.js new file mode 100755 index 00000000..578e67b8 --- /dev/null +++ b/assets/js/frontend/uploader.js @@ -0,0 +1,193 @@ +/* global tinymce, wpCookies, autosaveL10n, switchEditors */ +// Back-compat +window.opalestate_uploader = function() { + return true; +}; + +/** + * @summary Adds autosave to the window object on dom ready. + * + * @since 3.9.0 + * + * @param {jQuery} $ jQuery object. + * @param {window} The window object. + * + */ + +( function( $, window ) { + + /** + * @summary Auto saves the post. + * + * @since 3.9.0 + * + * The object with all functions for autosave. + */ + + function opalestate_uploader() { + + $document = $( document ); + + function is_image_file( file ) { + const acceptedImageTypes = ['image/gif', 'image/jpeg', 'image/png']; + return file && acceptedImageTypes.includes(file['type']) + } + + function check_number_files( file , i ) { + if( is_image_file(file) ) { + if( i+1 > opalesateJS.mfile_image ){ + return false; + } + } else { + if( i+1 > opalesateJS.mfile_other ){ + return false; + } + } + return true; + } + + function check_filesize ( file , i ) { + + if( is_image_file(file) ) { + if( file.size > opalesateJS.size_image ){ + var myToast = $.toast({ + heading: file.name, + text: opalesateJS.error_upload_size, + icon: 'error', + position: 'bottom-right', + hideAfter: 3500, + showHideTransition: 'fade' + }); + return false; + } else { + return true; + } + } else { + return true; + } + + } + /** + * + */ + function trigger_button_upload(){ + + var handleUpload = function ( _container ){ + + var file_btn = $( 'input.select-file', _container ); + var allow_files = []; + // var all_selected = []; + var name = $(this).data( 'name' ); + var issingle = $(_container).data('single'); + var show_icon = $(_container).data( 'show-icon' ); + + var on_select_files = function ( files, _container ) { + + if ( window.File && window.FileList && window.FileReader ) { + $(files).each( function( i, file ){ + + if( check_number_files( file, i+$(".uploader-item-preview",_container).length ) == false ){ + return ; + } + if( check_filesize( file, i ) ) { + var picReader = new FileReader(); + picReader.addEventListener("load", function ( event ) { + var input = '
            '; + var picFile = event.target; + if ( picFile.result ) { + if( show_icon == 1 ) { + input += '
            '+ file.name +'
            '; + } else { + input += '
            '; + } + + } + input += '
            '; + var a = $(input) ; + if( issingle ){ + $( ".uploader-item-preview", _container ).remove(); + all_selected = []; + } + $( _container ).prepend( a ); + a.prop( 'file', file ); + } ); + picReader.readAsDataURL( file ); + } + } ); + } + }; + + file_btn.on("change", function( event ){ + on_select_files( event.target.files, _container, allow_files ); + + } ); + + $( _container ).on( "click", ".btn-close", function(){ + if( confirm(opalesateJS.confirmed ) ){ + if( $("input", $(this).parent().parent()).length ){ + var rinput = $(""); + $(_container).append( rinput ); + } + + $(this).parent().parent().remove(); + } + } ); + + $( ".button-placehold", _container ).click( function(){ + file_btn.trigger("click"); + } ); + } + + $(".cmb2-uploader-files").each( function(){ + handleUpload( this ) + } ); + + // fix for submittion form + window.CMB2 = window.CMB2 || {}; + window.CMB2.metabox().find('.cmb-repeatable-group').on( 'cmb2_add_row', function(i, row ) { + var _container = $( row ); + if( $(".cmb2-uploader-files", _container ).length ) { + $( ".uploader-item-preview", _container ).remove(); + $(".cmb2-uploader-files", _container ).each( function(){ + var name = $( 'input', this ).attr('name'); + $( this ).attr('data-name', name ); + $(this).data( 'name', name ); + handleUpload( this ); + }); + } + } ); + } + + function upload_attachments( name, files ) { + + alert( name ); + } + + /** + * @summary Sets the autosave time out. + * + * Wait for TinyMCE to initialize plus 1 second. for any external css to finish loading, + * then save to the textarea before setting initialCompareString. + * This avoids any insignificant differences between the initial textarea content and the content + * extracted from the editor. + * + * @since 3.9.0 + * + * @returns {void} + */ + $document.on( 'body', function( event, editor ) { + + }).ready( function() { + trigger_button_upload(); + }); + + return { + + }; + } + + /** @namespace wp */ + window.wp = window.wp || {}; + window.wp.opalestate_uploader = opalestate_uploader(); + +}( jQuery, window )); \ No newline at end of file diff --git a/assets/js/infobox.js b/assets/js/infobox.js new file mode 100755 index 00000000..546f1b0b --- /dev/null +++ b/assets/js/infobox.js @@ -0,0 +1,772 @@ +/** + * @name InfoBox + * @version 1.1.9 [October 2, 2011] + * @author Gary Little (inspired by proof-of-concept code from Pamela Fox of Google) + * @copyright Copyright 2010 Gary Little [gary at luxcentral.com] + * @fileoverview InfoBox extends the Google Maps JavaScript API V3 OverlayView class. + *

            + * An InfoBox behaves like a google.maps.InfoWindow, but it supports several + * additional properties for advanced styling. An InfoBox can also be used as a map label. + *

            + * An InfoBox also fires the same events as a google.maps.InfoWindow. + *

            + * Browsers tested: + *

            + * Mac -- Safari (4.0.4), Firefox (3.6), Opera (10.10), Chrome (4.0.249.43), OmniWeb (5.10.1) + *
            + * Win -- Safari, Firefox, Opera, Chrome (3.0.195.38), Internet Explorer (8.0.6001.18702) + *
            + * iPod Touch/iPhone -- Safari (3.1.2) + */ + +/*! + * + * 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. + */ + +/*jslint browser:true */ +/*global google */ + +/** + * @name InfoBoxOptions + * @class This class represents the optional parameter passed to the {@link InfoBox} constructor. + * @property {string|Node} content The content of the InfoBox (plain text or an HTML DOM node). + * @property {boolean} disableAutoPan Disable auto-pan on open (default is false). + * @property {number} maxWidth The maximum width (in pixels) of the InfoBox. Set to 0 if no maximum. + * @property {Size} pixelOffset The offset (in pixels) from the top left corner of the InfoBox + * (or the bottom left corner if the alignBottom property is true) + * to the map pixel corresponding to position. + * @property {LatLng} position The geographic location at which to display the InfoBox. + * @property {number} zIndex The CSS z-index style value for the InfoBox. + * Note: This value overrides a zIndex setting specified in the boxStyle property. + * @property {string} boxClass The name of the CSS class defining the styles for the InfoBox container. + * The default name is infoBox. + * @property {Object} [boxStyle] An object literal whose properties define specific CSS + * style values to be applied to the InfoBox. Style values defined here override those that may + * be defined in the boxClass style sheet. If this property is changed after the + * InfoBox has been created, all previously set styles (except those defined in the style sheet) + * are removed from the InfoBox before the new style values are applied. + * @property {string} closeBoxMargin The CSS margin style value for the close box. + * The default is "2px" (a 2-pixel margin on all sides). + * @property {string} closeBoxURL The URL of the image representing the close box. + * Note: The default is the URL for Google's standard close box. + * Set this property to "" if no close box is required. + * @property {Size} infoBoxClearance Minimum offset (in pixels) from the InfoBox to the + * map edge after an auto-pan. + * @property {boolean} isHidden Hide the InfoBox on open (default is false). + * @property {boolean} alignBottom Align the bottom left corner of the InfoBox to the position + * location (default is false which means that the top left corner of the InfoBox is aligned). + * @property {string} pane The pane where the InfoBox is to appear (default is "floatPane"). + * Set the pane to "mapPane" if the InfoBox is being used as a map label. + * Valid pane names are the property names for the google.maps.MapPanes object. + * @property {boolean} enableEventPropagation Propagate mousedown, click, dblclick, + * and contextmenu events in the InfoBox (default is false to mimic the behavior + * of a google.maps.InfoWindow). Set this property to true if the InfoBox + * is being used as a map label. iPhone note: This property setting has no effect; events are + * always propagated. + */ + +/** + * Creates an InfoBox with the options specified in {@link InfoBoxOptions}. + * Call InfoBox.open to add the box to the map. + * @constructor + * @param {InfoBoxOptions} [opt_opts] + */ +function InfoBox(opt_opts) { + + opt_opts = opt_opts || {}; + + google.maps.OverlayView.apply(this, arguments); + + // Standard options (in common with google.maps.InfoWindow): + // + this.content_ = opt_opts.content || ""; + this.disableAutoPan_ = opt_opts.disableAutoPan || false; + this.maxWidth_ = opt_opts.maxWidth || 0; + this.pixelOffset_ = opt_opts.pixelOffset || new google.maps.Size(0, 0); + this.position_ = opt_opts.position || new google.maps.LatLng(0, 0); + this.zIndex_ = opt_opts.zIndex || null; + + // Additional options (unique to InfoBox): + // + this.boxClass_ = opt_opts.boxClass || "infoBox"; + this.boxStyle_ = opt_opts.boxStyle || {}; + this.closeBoxMargin_ = opt_opts.closeBoxMargin || "2px"; + this.closeBoxURL_ = opt_opts.closeBoxURL || "http://www.google.com/intl/en_us/mapfiles/close.gif"; + if (opt_opts.closeBoxURL === "") { + this.closeBoxURL_ = ""; + } + this.infoBoxClearance_ = opt_opts.infoBoxClearance || new google.maps.Size(1, 1); + this.isHidden_ = opt_opts.isHidden || false; + this.alignBottom_ = opt_opts.alignBottom || false; + this.pane_ = opt_opts.pane || "floatPane"; + this.enableEventPropagation_ = opt_opts.enableEventPropagation || false; + + this.div_ = null; + this.closeListener_ = null; + this.eventListener1_ = null; + this.eventListener2_ = null; + this.eventListener3_ = null; + this.moveListener_ = null; + this.contextListener_ = null; + this.fixedWidthSet_ = null; +} + +/* InfoBox extends OverlayView in the Google Maps API v3. + */ +InfoBox.prototype = new google.maps.OverlayView(); + +/** + * Creates the DIV representing the InfoBox. + * @private + */ +InfoBox.prototype.createInfoBoxDiv_ = function () { + + var bw; + var me = this; + + // This handler prevents an event in the InfoBox from being passed on to the map. + // + var cancelHandler = function (e) { + e.cancelBubble = true; + + if (e.stopPropagation) { + + e.stopPropagation(); + } + }; + + // This handler ignores the current event in the InfoBox and conditionally prevents + // the event from being passed on to the map. It is used for the contextmenu event. + // + var ignoreHandler = function (e) { + + e.returnValue = false; + + if (e.preventDefault) { + + e.preventDefault(); + } + + if (!me.enableEventPropagation_) { + + cancelHandler(e); + } + }; + + if (!this.div_) { + + this.div_ = document.createElement("div"); + + this.setBoxStyle_(); + + if (typeof this.content_.nodeType === "undefined") { + this.div_.innerHTML = this.getCloseBoxImg_() + this.content_; + } else { + this.div_.innerHTML = this.getCloseBoxImg_(); + this.div_.appendChild(this.content_); + } + + // Add the InfoBox DIV to the DOM + this.getPanes()[this.pane_].appendChild(this.div_); + + this.addClickHandler_(); + + if (this.div_.style.width) { + + this.fixedWidthSet_ = true; + + } else { + + if (this.maxWidth_ !== 0 && this.div_.offsetWidth > this.maxWidth_) { + + this.div_.style.width = this.maxWidth_; + this.div_.style.overflow = "auto"; + this.fixedWidthSet_ = true; + + } else { // The following code is needed to overcome problems with MSIE + + bw = this.getBoxWidths_(); + + this.div_.style.width = (this.div_.offsetWidth - bw.left - bw.right) + "px"; + this.fixedWidthSet_ = false; + } + } + + this.panBox_(this.disableAutoPan_); + + if (!this.enableEventPropagation_) { + + // Cancel event propagation. + // + this.eventListener1_ = google.maps.event.addDomListener(this.div_, "mousedown", cancelHandler); + this.eventListener2_ = google.maps.event.addDomListener(this.div_, "click", cancelHandler); + this.eventListener3_ = google.maps.event.addDomListener(this.div_, "dblclick", cancelHandler); + this.eventListener4_ = google.maps.event.addDomListener(this.div_, "mouseover", function (e) { + this.style.cursor = "default"; + }); + } + + this.contextListener_ = google.maps.event.addDomListener(this.div_, "contextmenu", ignoreHandler); + + /** + * This event is fired when the DIV containing the InfoBox's content is attached to the DOM. + * @name InfoBox#domready + * @event + */ + google.maps.event.trigger(this, "domready"); + } +}; + +/** + * Returns the HTML tag for the close box. + * @private + */ +InfoBox.prototype.getCloseBoxImg_ = function () { + + var img = ""; + + if (this.closeBoxURL_ !== "") { + + img = " mapWidth) { + xOffset = pixPosition.x + iwWidth + iwOffsetX + padX - mapWidth; + } + if (this.alignBottom_) { + if (pixPosition.y < (-iwOffsetY + padY + iwHeight)) { + yOffset = pixPosition.y + iwOffsetY - padY - iwHeight; + } else if ((pixPosition.y + iwOffsetY + padY) > mapHeight) { + yOffset = pixPosition.y + iwOffsetY + padY - mapHeight; + } + } else { + if (pixPosition.y < (-iwOffsetY + padY)) { + yOffset = pixPosition.y + iwOffsetY - padY; + } else if ((pixPosition.y + iwHeight + iwOffsetY + padY) > mapHeight) { + yOffset = pixPosition.y + iwHeight + iwOffsetY + padY - mapHeight; + } + } + + if (!(xOffset === 0 && yOffset === 0)) { + + // Move the map to the shifted center. + // + var c = map.getCenter(); + map.panBy(xOffset, yOffset); + } + } + } +}; + +/** + * Sets the style of the InfoBox by setting the style sheet and applying + * other specific styles requested. + * @private + */ +InfoBox.prototype.setBoxStyle_ = function () { + + var i, boxStyle; + + if (this.div_) { + + // Apply style values from the style sheet defined in the boxClass parameter: + this.div_.className = this.boxClass_; + + // Clear existing inline style values: + this.div_.style.cssText = ""; + + // Apply style values defined in the boxStyle parameter: + boxStyle = this.boxStyle_; + for (i in boxStyle) { + + if (boxStyle.hasOwnProperty(i)) { + + this.div_.style[i] = boxStyle[i]; + } + } + + // Fix up opacity style for benefit of MSIE: + // + if (typeof this.div_.style.opacity !== "undefined" && this.div_.style.opacity !== "") { + + this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")"; + } + + // Apply required styles: + // + this.div_.style.position = "absolute"; + this.div_.style.visibility = 'hidden'; + if (this.zIndex_ !== null) { + + this.div_.style.zIndex = this.zIndex_; + } + } +}; + +/** + * Get the widths of the borders of the InfoBox. + * @private + * @return {Object} widths object (top, bottom left, right) + */ +InfoBox.prototype.getBoxWidths_ = function () { + + var computedStyle; + var bw = {top: 0, bottom: 0, left: 0, right: 0}; + var box = this.div_; + + if (document.defaultView && document.defaultView.getComputedStyle) { + + computedStyle = box.ownerDocument.defaultView.getComputedStyle(box, ""); + + if (computedStyle) { + + // The computed styles are always in pixel units (good!) + bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0; + bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; + bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0; + bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0; + } + + } else if (document.documentElement.currentStyle) { // MSIE + + if (box.currentStyle) { + + // The current styles may not be in pixel units, but assume they are (bad!) + bw.top = parseInt(box.currentStyle.borderTopWidth, 10) || 0; + bw.bottom = parseInt(box.currentStyle.borderBottomWidth, 10) || 0; + bw.left = parseInt(box.currentStyle.borderLeftWidth, 10) || 0; + bw.right = parseInt(box.currentStyle.borderRightWidth, 10) || 0; + } + } + + return bw; +}; + +/** + * Invoked when close is called. Do not call it directly. + */ +InfoBox.prototype.onRemove = function () { + + if (this.div_) { + + this.div_.parentNode.removeChild(this.div_); + this.div_ = null; + } +}; + +/** + * Draws the InfoBox based on the current map projection and zoom level. + */ +InfoBox.prototype.draw = function () { + + this.createInfoBoxDiv_(); + + var pixPosition = this.getProjection().fromLatLngToDivPixel(this.position_); + + this.div_.style.left = (pixPosition.x + this.pixelOffset_.width) + "px"; + + if (this.alignBottom_) { + this.div_.style.bottom = -(pixPosition.y + this.pixelOffset_.height) + "px"; + } else { + this.div_.style.top = (pixPosition.y + this.pixelOffset_.height) + "px"; + } + + if (this.isHidden_) { + + this.div_.style.visibility = 'hidden'; + + } else { + + this.div_.style.visibility = "visible"; + } +}; + +/** + * Sets the options for the InfoBox. Note that changes to the maxWidth, + * closeBoxMargin, closeBoxURL, and enableEventPropagation + * properties have no affect until the current InfoBox is closed and a new one + * is opened. + * @param {InfoBoxOptions} opt_opts + */ +InfoBox.prototype.setOptions = function (opt_opts) { + if (typeof opt_opts.boxClass !== "undefined") { // Must be first + + this.boxClass_ = opt_opts.boxClass; + this.setBoxStyle_(); + } + if (typeof opt_opts.boxStyle !== "undefined") { // Must be second + + this.boxStyle_ = opt_opts.boxStyle; + this.setBoxStyle_(); + } + if (typeof opt_opts.content !== "undefined") { + + this.setContent(opt_opts.content); + } + if (typeof opt_opts.disableAutoPan !== "undefined") { + + this.disableAutoPan_ = opt_opts.disableAutoPan; + } + if (typeof opt_opts.maxWidth !== "undefined") { + + this.maxWidth_ = opt_opts.maxWidth; + } + if (typeof opt_opts.pixelOffset !== "undefined") { + + this.pixelOffset_ = opt_opts.pixelOffset; + } + if (typeof opt_opts.alignBottom !== "undefined") { + + this.alignBottom_ = opt_opts.alignBottom; + } + if (typeof opt_opts.position !== "undefined") { + + this.setPosition(opt_opts.position); + } + if (typeof opt_opts.zIndex !== "undefined") { + + this.setZIndex(opt_opts.zIndex); + } + if (typeof opt_opts.closeBoxMargin !== "undefined") { + + this.closeBoxMargin_ = opt_opts.closeBoxMargin; + } + if (typeof opt_opts.closeBoxURL !== "undefined") { + + this.closeBoxURL_ = opt_opts.closeBoxURL; + } + if (typeof opt_opts.infoBoxClearance !== "undefined") { + + this.infoBoxClearance_ = opt_opts.infoBoxClearance; + } + if (typeof opt_opts.isHidden !== "undefined") { + + this.isHidden_ = opt_opts.isHidden; + } + if (typeof opt_opts.enableEventPropagation !== "undefined") { + + this.enableEventPropagation_ = opt_opts.enableEventPropagation; + } + + if (this.div_) { + + this.draw(); + } +}; + +/** + * Sets the content of the InfoBox. + * The content can be plain text or an HTML DOM node. + * @param {string|Node} content + */ +InfoBox.prototype.setContent = function (content) { + this.content_ = content; + + if (this.div_) { + + if (this.closeListener_) { + + google.maps.event.removeListener(this.closeListener_); + this.closeListener_ = null; + } + + // Odd code required to make things work with MSIE. + // + if (!this.fixedWidthSet_) { + + this.div_.style.width = ""; + } + + if (typeof content.nodeType === "undefined") { + this.div_.innerHTML = this.getCloseBoxImg_() + content; + } else { + this.div_.innerHTML = this.getCloseBoxImg_(); + this.div_.appendChild(content); + } + + // Perverse code required to make things work with MSIE. + // (Ensures the close box does, in fact, float to the right.) + // + if (!this.fixedWidthSet_) { + this.div_.style.width = this.div_.offsetWidth + "px"; + if (typeof content.nodeType === "undefined") { + this.div_.innerHTML = this.getCloseBoxImg_() + content; + } else { + this.div_.innerHTML = this.getCloseBoxImg_(); + this.div_.appendChild(content); + } + } + + this.addClickHandler_(); + } + + /** + * This event is fired when the content of the InfoBox changes. + * @name InfoBox#content_changed + * @event + */ + google.maps.event.trigger(this, "content_changed"); +}; + +/** + * Sets the geographic location of the InfoBox. + * @param {LatLng} latlng + */ +InfoBox.prototype.setPosition = function (latlng) { + + this.position_ = latlng; + + if (this.div_) { + + this.draw(); + } + + /** + * This event is fired when the position of the InfoBox changes. + * @name InfoBox#position_changed + * @event + */ + google.maps.event.trigger(this, "position_changed"); +}; + +/** + * Sets the zIndex style for the InfoBox. + * @param {number} index + */ +InfoBox.prototype.setZIndex = function (index) { + + this.zIndex_ = index; + + if (this.div_) { + + this.div_.style.zIndex = index; + } + + /** + * This event is fired when the zIndex of the InfoBox changes. + * @name InfoBox#zindex_changed + * @event + */ + google.maps.event.trigger(this, "zindex_changed"); +}; + +/** + * Returns the content of the InfoBox. + * @returns {string} + */ +InfoBox.prototype.getContent = function () { + + return this.content_; +}; + +/** + * Returns the geographic location of the InfoBox. + * @returns {LatLng} + */ +InfoBox.prototype.getPosition = function () { + + return this.position_; +}; + +/** + * Returns the zIndex for the InfoBox. + * @returns {number} + */ +InfoBox.prototype.getZIndex = function () { + + return this.zIndex_; +}; + +/** + * Shows the InfoBox. + */ +InfoBox.prototype.show = function () { + + this.isHidden_ = false; + if (this.div_) { + this.div_.style.visibility = "visible"; + } +}; + +/** + * Hides the InfoBox. + */ +InfoBox.prototype.hide = function () { + + this.isHidden_ = true; + if (this.div_) { + this.div_.style.visibility = "hidden"; + } +}; + +/** + * Adds the InfoBox to the specified map or Street View panorama. If anchor + * (usually a google.maps.Marker) is specified, the position + * of the InfoBox is set to the position of the anchor. If the + * anchor is dragged to a new location, the InfoBox moves as well. + * @param {Map|StreetViewPanorama} map + * @param {MVCObject} [anchor] + */ +InfoBox.prototype.open = function (map, anchor) { + + var me = this; + + if (anchor) { + + this.position_ = anchor.getPosition(); + this.moveListener_ = google.maps.event.addListener(anchor, "position_changed", function () { + me.setPosition(this.getPosition()); + }); + } + + this.setMap(map); + + if (this.div_) { + + this.panBox_(); + } +}; + +/** + * Removes the InfoBox from the map. + */ +InfoBox.prototype.close = function () { + + if (this.closeListener_) { + + google.maps.event.removeListener(this.closeListener_); + this.closeListener_ = null; + } + + if (this.eventListener1_) { + + google.maps.event.removeListener(this.eventListener1_); + google.maps.event.removeListener(this.eventListener2_); + google.maps.event.removeListener(this.eventListener3_); + google.maps.event.removeListener(this.eventListener4_); + this.eventListener1_ = null; + this.eventListener2_ = null; + this.eventListener3_ = null; + this.eventListener4_ = null; + } + + if (this.moveListener_) { + + google.maps.event.removeListener(this.moveListener_); + this.moveListener_ = null; + } + + if (this.contextListener_) { + + google.maps.event.removeListener(this.contextListener_); + this.contextListener_ = null; + } + + this.setMap(null); +}; \ No newline at end of file diff --git a/assets/js/jquery.fitvids.js b/assets/js/jquery.fitvids.js new file mode 100755 index 00000000..f8d6b977 --- /dev/null +++ b/assets/js/jquery.fitvids.js @@ -0,0 +1,83 @@ +/*global jQuery */ +/*jshint browser:true */ +/*! +* FitVids 1.1 +* +* Copyright 2013, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com +* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ +* Released under the WTFPL license - http://sam.zoy.org/wtfpl/ +* +*/ + +;(function( $ ){ + + 'use strict'; + + $.fn.fitVids = function( options ) { + var settings = { + customSelector: null, + ignore: null + }; + + if(!document.getElementById('fit-vids-style')) { + // appendStyles: https://github.com/toddmotto/fluidvids/blob/master/dist/fluidvids.js + var head = document.head || document.getElementsByTagName('head')[0]; + var css = '.fluid-width-video-wrapper{width:100%;position:relative;padding:0;}.fluid-width-video-wrapper iframe,.fluid-width-video-wrapper object,.fluid-width-video-wrapper embed {position:absolute;top:0;left:0;width:100%;height:100%;}'; + var div = document.createElement("div"); + div.innerHTML = '

            x

            '; + head.appendChild(div.childNodes[1]); + } + + if ( options ) { + $.extend( settings, options ); + } + + return this.each(function(){ + var selectors = [ + 'iframe[src*="player.vimeo.com"]', + 'iframe[src*="youtube.com"]', + 'iframe[src*="youtube-nocookie.com"]', + 'iframe[src*="kickstarter.com"][src*="video.html"]', + 'object', + 'embed' + ]; + + if (settings.customSelector) { + selectors.push(settings.customSelector); + } + + var ignoreList = '.fitvidsignore'; + + if(settings.ignore) { + ignoreList = ignoreList + ', ' + settings.ignore; + } + + var $allVideos = $(this).find(selectors.join(',')); + $allVideos = $allVideos.not('object object'); // SwfObj conflict patch + $allVideos = $allVideos.not(ignoreList); // Disable FitVids on this video. + + $allVideos.each(function(count){ + var $this = $(this); + if($this.parents(ignoreList).length > 0) { + return; // Disable FitVids on this video. + } + if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } + if ((!$this.css('height') && !$this.css('width')) && (isNaN($this.attr('height')) || isNaN($this.attr('width')))) + { + $this.attr('height', 9); + $this.attr('width', 16); + } + var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(), + width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(), + aspectRatio = height / width; + if(!$this.attr('id')){ + var videoID = 'fitvid' + count; + $this.attr('id', videoID); + } + $this.wrap('
            ').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+'%'); + $this.removeAttr('height').removeAttr('width'); + }); + }); + }; +// Works with either jQuery or Zepto +})( window.jQuery || window.Zepto ); diff --git a/assets/js/markerclusterer.js b/assets/js/markerclusterer.js new file mode 100755 index 00000000..979333d8 --- /dev/null +++ b/assets/js/markerclusterer.js @@ -0,0 +1,1642 @@ +/** + * @name MarkerClustererPlus for Google Maps V3 + * @version 2.1.1 [November 4, 2013] + * @author Gary Little + * @fileoverview + * The library creates and manages per-zoom-level clusters for large amounts of markers. + *

            + * This is an enhanced V3 implementation of the + * V2 MarkerClusterer by Xiaoxi Wu. It is based on the + * V3 MarkerClusterer port by Luke Mahe. MarkerClustererPlus was created by Gary Little. + *

            + * v2.0 release: MarkerClustererPlus v2.0 is backward compatible with MarkerClusterer v1.0. It + * adds support for the ignoreHidden, title, batchSizeIE, + * and calculator properties as well as support for four more events. It also allows + * greater control over the styling of the text that appears on the cluster marker. The + * documentation has been significantly improved and the overall code has been simplified and + * polished. Very large numbers of markers can now be managed without causing Javascript timeout + * errors on Internet Explorer. Note that the name of the clusterclick event has been + * deprecated. The new name is click, so please change your application code now. + */ + +/** + * 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. + */ + + +/** + * @name ClusterIconStyle + * @class This class represents the object for values in the styles array passed + * to the {@link MarkerClusterer} constructor. The element in this array that is used to + * style the cluster icon is determined by calling the calculator function. + * + * @property {string} url The URL of the cluster icon image file. Required. + * @property {number} height The display height (in pixels) of the cluster icon. Required. + * @property {number} width The display width (in pixels) of the cluster icon. Required. + * @property {Array} [anchorText] The position (in pixels) from the center of the cluster icon to + * where the text label is to be centered and drawn. The format is [yoffset, xoffset] + * where yoffset increases as you go down from center and xoffset + * increases to the right of center. The default is [0, 0]. + * @property {Array} [anchorIcon] The anchor position (in pixels) of the cluster icon. This is the + * spot on the cluster icon that is to be aligned with the cluster position. The format is + * [yoffset, xoffset] where yoffset increases as you go down and + * xoffset increases to the right of the top-left corner of the icon. The default + * anchor position is the center of the cluster icon. + * @property {string} [textColor="black"] The color of the label text shown on the + * cluster icon. + * @property {number} [textSize=11] The size (in pixels) of the label text shown on the + * cluster icon. + * @property {string} [textDecoration="none"] The value of the CSS text-decoration + * property for the label text shown on the cluster icon. + * @property {string} [fontWeight="bold"] The value of the CSS font-weight + * property for the label text shown on the cluster icon. + * @property {string} [fontStyle="normal"] The value of the CSS font-style + * property for the label text shown on the cluster icon. + * @property {string} [fontFamily="Arial,sans-serif"] The value of the CSS font-family + * property for the label text shown on the cluster icon. + * @property {string} [backgroundPosition="0 0"] The position of the cluster icon image + * within the image defined by url. The format is "xpos ypos" + * (the same format as for the CSS background-position property). You must set + * this property appropriately when the image defined by url represents a sprite + * containing multiple images. Note that the position must be specified in px units. + */ +/** + * @name ClusterIconInfo + * @class This class is an object containing general information about a cluster icon. This is + * the object that a calculator function returns. + * + * @property {string} text The text of the label to be shown on the cluster icon. + * @property {number} index The index plus 1 of the element in the styles + * array to be used to style the cluster icon. + * @property {string} title The tooltip to display when the mouse moves over the cluster icon. + * If this value is undefined or "", title is set to the + * value of the title property passed to the MarkerClusterer. + */ +/** + * A cluster icon. + * + * @constructor + * @extends google.maps.OverlayView + * @param {Cluster} cluster The cluster with which the icon is to be associated. + * @param {Array} [styles] An array of {@link ClusterIconStyle} defining the cluster icons + * to use for various cluster sizes. + * @private + */ +function ClusterIcon(cluster, styles) { + cluster.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView); + + this.cluster_ = cluster; + this.className_ = cluster.getMarkerClusterer().getClusterClass(); + this.styles_ = styles; + this.center_ = null; + this.div_ = null; + this.sums_ = null; + this.visible_ = false; + + this.setMap(cluster.getMap()); // Note: this causes onAdd to be called +} + + +/** + * Adds the icon to the DOM. + */ +ClusterIcon.prototype.onAdd = function () { + var cClusterIcon = this; + var cMouseDownInCluster; + var cDraggingMapByCluster; + + this.div_ = document.createElement("div"); + this.div_.className = this.className_; + if (this.visible_) { + this.show(); + } + + this.getPanes().overlayMouseTarget.appendChild(this.div_); + + // Fix for Issue 157 + this.boundsChangedListener_ = google.maps.event.addListener(this.getMap(), "bounds_changed", function () { + cDraggingMapByCluster = cMouseDownInCluster; + }); + + google.maps.event.addDomListener(this.div_, "mousedown", function () { + cMouseDownInCluster = true; + cDraggingMapByCluster = false; + }); + + google.maps.event.addDomListener(this.div_, "click", function (e) { + cMouseDownInCluster = false; + if (!cDraggingMapByCluster) { + var theBounds; + var mz; + var mc = cClusterIcon.cluster_.getMarkerClusterer(); + /** + * This event is fired when a cluster marker is clicked. + * @name MarkerClusterer#click + * @param {Cluster} c The cluster that was clicked. + * @event + */ + google.maps.event.trigger(mc, "click", cClusterIcon.cluster_); + google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name + + // The default click handler follows. Disable it by setting + // the zoomOnClick property to false. + if (mc.getZoomOnClick()) { + // Zoom into the cluster. + mz = mc.getMaxZoom(); + theBounds = cClusterIcon.cluster_.getBounds(); + mc.getMap().fitBounds(theBounds); + // There is a fix for Issue 170 here: + setTimeout(function () { + mc.getMap().fitBounds(theBounds); + // Don't zoom beyond the max zoom level + if (mz !== null && (mc.getMap().getZoom() > mz)) { + mc.getMap().setZoom(mz + 1); + } + }, 100); + } + + // Prevent event propagation to the map: + e.cancelBubble = true; + if (e.stopPropagation) { + e.stopPropagation(); + } + } + }); + + google.maps.event.addDomListener(this.div_, "mouseover", function () { + var mc = cClusterIcon.cluster_.getMarkerClusterer(); + /** + * This event is fired when the mouse moves over a cluster marker. + * @name MarkerClusterer#mouseover + * @param {Cluster} c The cluster that the mouse moved over. + * @event + */ + google.maps.event.trigger(mc, "mouseover", cClusterIcon.cluster_); + }); + + google.maps.event.addDomListener(this.div_, "mouseout", function () { + var mc = cClusterIcon.cluster_.getMarkerClusterer(); + /** + * This event is fired when the mouse moves out of a cluster marker. + * @name MarkerClusterer#mouseout + * @param {Cluster} c The cluster that the mouse moved out of. + * @event + */ + google.maps.event.trigger(mc, "mouseout", cClusterIcon.cluster_); + }); +}; + + +/** + * Removes the icon from the DOM. + */ +ClusterIcon.prototype.onRemove = function () { + if (this.div_ && this.div_.parentNode) { + this.hide(); + google.maps.event.removeListener(this.boundsChangedListener_); + google.maps.event.clearInstanceListeners(this.div_); + this.div_.parentNode.removeChild(this.div_); + this.div_ = null; + } +}; + + +/** + * Draws the icon. + */ +ClusterIcon.prototype.draw = function () { + if (this.visible_) { + var pos = this.getPosFromLatLng_(this.center_); + this.div_.style.top = pos.y + "px"; + this.div_.style.left = pos.x + "px"; + } +}; + + +/** + * Hides the icon. + */ +ClusterIcon.prototype.hide = function () { + if (this.div_) { + this.div_.style.display = "none"; + } + this.visible_ = false; +}; + + +/** + * Positions and shows the icon. + */ +ClusterIcon.prototype.show = function () { + if (this.div_) { + var img = ""; + // NOTE: values must be specified in px units + var bp = this.backgroundPosition_.split(" "); + var spriteH = parseInt(bp[0].trim(), 10); + var spriteV = parseInt(bp[1].trim(), 10); + var pos = this.getPosFromLatLng_(this.center_); + this.div_.style.cssText = this.createCss(pos); + img = ""; + this.div_.innerHTML = img + "

            " + this.sums_.text + "
            "; + if (typeof this.sums_.title === "undefined" || this.sums_.title === "") { + this.div_.title = this.cluster_.getMarkerClusterer().getTitle(); + } else { + this.div_.title = this.sums_.title; + } + this.div_.style.display = ""; + } + this.visible_ = true; +}; + + +/** + * Sets the icon styles to the appropriate element in the styles array. + * + * @param {ClusterIconInfo} sums The icon label text and styles index. + */ +ClusterIcon.prototype.useStyle = function (sums) { + this.sums_ = sums; + var index = Math.max(0, sums.index - 1); + index = Math.min(this.styles_.length - 1, index); + var style = this.styles_[index]; + this.url_ = style.url; + this.height_ = style.height; + this.width_ = style.width; + this.anchorText_ = style.anchorText || [0, 0]; + this.anchorIcon_ = style.anchorIcon || [parseInt(this.height_ / 2, 10), parseInt(this.width_ / 2, 10)]; + this.textColor_ = style.textColor || "black"; + this.textSize_ = style.textSize || 11; + this.textDecoration_ = style.textDecoration || "none"; + this.fontWeight_ = style.fontWeight || "bold"; + this.fontStyle_ = style.fontStyle || "normal"; + this.fontFamily_ = style.fontFamily || "Arial,sans-serif"; + this.backgroundPosition_ = style.backgroundPosition || "0 0"; +}; + + +/** + * Sets the position at which to center the icon. + * + * @param {google.maps.LatLng} center The latlng to set as the center. + */ +ClusterIcon.prototype.setCenter = function (center) { + this.center_ = center; +}; + + +/** + * Creates the cssText style parameter based on the position of the icon. + * + * @param {google.maps.Point} pos The position of the icon. + * @return {string} The CSS style text. + */ +ClusterIcon.prototype.createCss = function (pos) { + var style = []; + style.push("cursor: pointer;"); + style.push("position: absolute; top: " + pos.y + "px; left: " + pos.x + "px;"); + style.push("width: " + this.width_ + "px; height: " + this.height_ + "px;"); + return style.join(""); +}; + + +/** + * Returns the position at which to place the DIV depending on the latlng. + * + * @param {google.maps.LatLng} latlng The position in latlng. + * @return {google.maps.Point} The position in pixels. + */ +ClusterIcon.prototype.getPosFromLatLng_ = function (latlng) { + var pos = this.getProjection().fromLatLngToDivPixel(latlng); + pos.x -= this.anchorIcon_[1]; + pos.y -= this.anchorIcon_[0]; + pos.x = parseInt(pos.x, 10); + pos.y = parseInt(pos.y, 10); + return pos; +}; + + +/** + * Creates a single cluster that manages a group of proximate markers. + * Used internally, do not call this constructor directly. + * @constructor + * @param {MarkerClusterer} mc The MarkerClusterer object with which this + * cluster is associated. + */ +function Cluster(mc) { + this.markerClusterer_ = mc; + this.map_ = mc.getMap(); + this.gridSize_ = mc.getGridSize(); + this.minClusterSize_ = mc.getMinimumClusterSize(); + this.averageCenter_ = mc.getAverageCenter(); + this.markers_ = []; + this.center_ = null; + this.bounds_ = null; + this.clusterIcon_ = new ClusterIcon(this, mc.getStyles()); +} + + +/** + * Returns the number of markers managed by the cluster. You can call this from + * a click, mouseover, or mouseout event handler + * for the MarkerClusterer object. + * + * @return {number} The number of markers in the cluster. + */ +Cluster.prototype.getSize = function () { + return this.markers_.length; +}; + + +/** + * Returns the array of markers managed by the cluster. You can call this from + * a click, mouseover, or mouseout event handler + * for the MarkerClusterer object. + * + * @return {Array} The array of markers in the cluster. + */ +Cluster.prototype.getMarkers = function () { + return this.markers_; +}; + + +/** + * Returns the center of the cluster. You can call this from + * a click, mouseover, or mouseout event handler + * for the MarkerClusterer object. + * + * @return {google.maps.LatLng} The center of the cluster. + */ +Cluster.prototype.getCenter = function () { + return this.center_; +}; + + +/** + * Returns the map with which the cluster is associated. + * + * @return {google.maps.Map} The map. + * @ignore + */ +Cluster.prototype.getMap = function () { + return this.map_; +}; + + +/** + * Returns the MarkerClusterer object with which the cluster is associated. + * + * @return {MarkerClusterer} The associated marker clusterer. + * @ignore + */ +Cluster.prototype.getMarkerClusterer = function () { + return this.markerClusterer_; +}; + + +/** + * Returns the bounds of the cluster. + * + * @return {google.maps.LatLngBounds} the cluster bounds. + * @ignore + */ +Cluster.prototype.getBounds = function () { + var i; + var bounds = new google.maps.LatLngBounds(this.center_, this.center_); + var markers = this.getMarkers(); + for (i = 0; i < markers.length; i++) { + bounds.extend(markers[i].getPosition()); + } + return bounds; +}; + + +/** + * Removes the cluster from the map. + * + * @ignore + */ +Cluster.prototype.remove = function () { + this.clusterIcon_.setMap(null); + this.markers_ = []; + delete this.markers_; +}; + + +/** + * Adds a marker to the cluster. + * + * @param {google.maps.Marker} marker The marker to be added. + * @return {boolean} True if the marker was added. + * @ignore + */ +Cluster.prototype.addMarker = function (marker) { + var i; + var mCount; + var mz; + + if (this.isMarkerAlreadyAdded_(marker)) { + return false; + } + + if (!this.center_) { + this.center_ = marker.getPosition(); + this.calculateBounds_(); + } else { + if (this.averageCenter_) { + var l = this.markers_.length + 1; + var lat = (this.center_.lat() * (l - 1) + marker.getPosition().lat()) / l; + var lng = (this.center_.lng() * (l - 1) + marker.getPosition().lng()) / l; + this.center_ = new google.maps.LatLng(lat, lng); + this.calculateBounds_(); + } + } + + marker.isAdded = true; + this.markers_.push(marker); + + mCount = this.markers_.length; + mz = this.markerClusterer_.getMaxZoom(); + if (mz !== null && this.map_.getZoom() > mz) { + // Zoomed in past max zoom, so show the marker. + if (marker.getMap() !== this.map_) { + marker.setMap(this.map_); + } + } else if (mCount < this.minClusterSize_) { + // Min cluster size not reached so show the marker. + if (marker.getMap() !== this.map_) { + marker.setMap(this.map_); + } + } else if (mCount === this.minClusterSize_) { + // Hide the markers that were showing. + for (i = 0; i < mCount; i++) { + this.markers_[i].setMap(null); + } + } else { + marker.setMap(null); + } + + this.updateIcon_(); + return true; +}; + + +/** + * Determines if a marker lies within the cluster's bounds. + * + * @param {google.maps.Marker} marker The marker to check. + * @return {boolean} True if the marker lies in the bounds. + * @ignore + */ +Cluster.prototype.isMarkerInClusterBounds = function (marker) { + return this.bounds_.contains(marker.getPosition()); +}; + + +/** + * Calculates the extended bounds of the cluster with the grid. + */ +Cluster.prototype.calculateBounds_ = function () { + var bounds = new google.maps.LatLngBounds(this.center_, this.center_); + this.bounds_ = this.markerClusterer_.getExtendedBounds(bounds); +}; + + +/** + * Updates the cluster icon. + */ +Cluster.prototype.updateIcon_ = function () { + var mCount = this.markers_.length; + var mz = this.markerClusterer_.getMaxZoom(); + + if (mz !== null && this.map_.getZoom() > mz) { + this.clusterIcon_.hide(); + return; + } + + if (mCount < this.minClusterSize_) { + // Min cluster size not yet reached. + this.clusterIcon_.hide(); + return; + } + + var numStyles = this.markerClusterer_.getStyles().length; + var sums = this.markerClusterer_.getCalculator()(this.markers_, numStyles); + this.clusterIcon_.setCenter(this.center_); + this.clusterIcon_.useStyle(sums); + this.clusterIcon_.show(); +}; + + +/** + * Determines if a marker has already been added to the cluster. + * + * @param {google.maps.Marker} marker The marker to check. + * @return {boolean} True if the marker has already been added. + */ +Cluster.prototype.isMarkerAlreadyAdded_ = function (marker) { + var i; + if (this.markers_.indexOf) { + return this.markers_.indexOf(marker) !== -1; + } else { + for (i = 0; i < this.markers_.length; i++) { + if (marker === this.markers_[i]) { + return true; + } + } + } + return false; +}; + + +/** + * @name MarkerClustererOptions + * @class This class represents the optional parameter passed to + * the {@link MarkerClusterer} constructor. + * @property {number} [gridSize=60] The grid size of a cluster in pixels. The grid is a square. + * @property {number} [maxZoom=null] The maximum zoom level at which clustering is enabled or + * null if clustering is to be enabled at all zoom levels. + * @property {boolean} [zoomOnClick=true] Whether to zoom the map when a cluster marker is + * clicked. You may want to set this to false if you have installed a handler + * for the click event and it deals with zooming on its own. + * @property {boolean} [averageCenter=false] Whether the position of a cluster marker should be + * the average position of all markers in the cluster. If set to false, the + * cluster marker is positioned at the location of the first marker added to the cluster. + * @property {number} [minimumClusterSize=2] The minimum number of markers needed in a cluster + * before the markers are hidden and a cluster marker appears. + * @property {boolean} [ignoreHidden=false] Whether to ignore hidden markers in clusters. You + * may want to set this to true to ensure that hidden markers are not included + * in the marker count that appears on a cluster marker (this count is the value of the + * text property of the result returned by the default calculator). + * If set to true and you change the visibility of a marker being clustered, be + * sure to also call MarkerClusterer.repaint(). + * @property {string} [title=""] The tooltip to display when the mouse moves over a cluster + * marker. (Alternatively, you can use a custom calculator function to specify a + * different tooltip for each cluster marker.) + * @property {function} [calculator=MarkerClusterer.CALCULATOR] The function used to determine + * the text to be displayed on a cluster marker and the index indicating which style to use + * for the cluster marker. The input parameters for the function are (1) the array of markers + * represented by a cluster marker and (2) the number of cluster icon styles. It returns a + * {@link ClusterIconInfo} object. The default calculator returns a + * text property which is the number of markers in the cluster and an + * index property which is one higher than the lowest integer such that + * 10^i exceeds the number of markers in the cluster, or the size of the styles + * array, whichever is less. The styles array element used has an index of + * index minus 1. For example, the default calculator returns a + * text value of "125" and an index of 3 + * for a cluster icon representing 125 markers so the element used in the styles + * array is 2. A calculator may also return a title + * property that contains the text of the tooltip to be used for the cluster marker. If + * title is not defined, the tooltip is set to the value of the title + * property for the MarkerClusterer. + * @property {string} [clusterClass="cluster"] The name of the CSS class defining general styles + * for the cluster markers. Use this class to define CSS styles that are not set up by the code + * that processes the styles array. + * @property {Array} [styles] An array of {@link ClusterIconStyle} elements defining the styles + * of the cluster markers to be used. The element to be used to style a given cluster marker + * is determined by the function defined by the calculator property. + * The default is an array of {@link ClusterIconStyle} elements whose properties are derived + * from the values for imagePath, imageExtension, and + * imageSizes. + * @property {boolean} [enableRetinaIcons=false] Whether to allow the use of cluster icons that + * have sizes that are some multiple (typically double) of their actual display size. Icons such + * as these look better when viewed on high-resolution monitors such as Apple's Retina displays. + * Note: if this property is true, sprites cannot be used as cluster icons. + * @property {number} [batchSize=MarkerClusterer.BATCH_SIZE] Set this property to the + * number of markers to be processed in a single batch when using a browser other than + * Internet Explorer (for Internet Explorer, use the batchSizeIE property instead). + * @property {number} [batchSizeIE=MarkerClusterer.BATCH_SIZE_IE] When Internet Explorer is + * being used, markers are processed in several batches with a small delay inserted between + * each batch in an attempt to avoid Javascript timeout errors. Set this property to the + * number of markers to be processed in a single batch; select as high a number as you can + * without causing a timeout error in the browser. This number might need to be as low as 100 + * if 15,000 markers are being managed, for example. + * @property {string} [imagePath=MarkerClusterer.IMAGE_PATH] + * The full URL of the root name of the group of image files to use for cluster icons. + * The complete file name is of the form imagePathn.imageExtension + * where n is the image file number (1, 2, etc.). + * @property {string} [imageExtension=MarkerClusterer.IMAGE_EXTENSION] + * The extension name for the cluster icon image files (e.g., "png" or + * "jpg"). + * @property {Array} [imageSizes=MarkerClusterer.IMAGE_SIZES] + * An array of numbers containing the widths of the group of + * imagePathn.imageExtension image files. + * (The images are assumed to be square.) + */ +/** + * Creates a MarkerClusterer object with the options specified in {@link MarkerClustererOptions}. + * @constructor + * @extends google.maps.OverlayView + * @param {google.maps.Map} map The Google map to attach to. + * @param {Array.} [opt_markers] The markers to be added to the cluster. + * @param {MarkerClustererOptions} [opt_options] The optional parameters. + */ +function MarkerClusterer(map, opt_markers, opt_options) { + // MarkerClusterer implements google.maps.OverlayView interface. We use the + // extend function to extend MarkerClusterer with google.maps.OverlayView + // because it might not always be available when the code is defined so we + // look for it at the last possible moment. If it doesn't exist now then + // there is no point going ahead :) + this.extend(MarkerClusterer, google.maps.OverlayView); + + opt_markers = opt_markers || []; + opt_options = opt_options || {}; + + this.markers_ = []; + this.clusters_ = []; + this.listeners_ = []; + this.activeMap_ = null; + this.ready_ = false; + + this.gridSize_ = opt_options.gridSize || 60; + this.minClusterSize_ = opt_options.minimumClusterSize || 2; + this.maxZoom_ = opt_options.maxZoom || null; + this.styles_ = opt_options.styles || []; + this.title_ = opt_options.title || ""; + this.zoomOnClick_ = true; + if (opt_options.zoomOnClick !== undefined) { + this.zoomOnClick_ = opt_options.zoomOnClick; + } + this.averageCenter_ = false; + if (opt_options.averageCenter !== undefined) { + this.averageCenter_ = opt_options.averageCenter; + } + this.ignoreHidden_ = false; + if (opt_options.ignoreHidden !== undefined) { + this.ignoreHidden_ = opt_options.ignoreHidden; + } + this.enableRetinaIcons_ = false; + if (opt_options.enableRetinaIcons !== undefined) { + this.enableRetinaIcons_ = opt_options.enableRetinaIcons; + } + this.imagePath_ = opt_options.imagePath || MarkerClusterer.IMAGE_PATH; + this.imageExtension_ = opt_options.imageExtension || MarkerClusterer.IMAGE_EXTENSION; + this.imageSizes_ = opt_options.imageSizes || MarkerClusterer.IMAGE_SIZES; + this.calculator_ = opt_options.calculator || MarkerClusterer.CALCULATOR; + this.batchSize_ = opt_options.batchSize || MarkerClusterer.BATCH_SIZE; + this.batchSizeIE_ = opt_options.batchSizeIE || MarkerClusterer.BATCH_SIZE_IE; + this.clusterClass_ = opt_options.clusterClass || "cluster"; + + if (navigator.userAgent.toLowerCase().indexOf("msie") !== -1) { + // Try to avoid IE timeout when processing a huge number of markers: + this.batchSize_ = this.batchSizeIE_; + } + + this.setupStyles_(); + + this.addMarkers(opt_markers, true); + this.setMap(map); // Note: this causes onAdd to be called +} + + +/** + * Implementation of the onAdd interface method. + * @ignore + */ +MarkerClusterer.prototype.onAdd = function () { + var cMarkerClusterer = this; + + this.activeMap_ = this.getMap(); + this.ready_ = true; + + this.repaint(); + + // Add the map event listeners + this.listeners_ = [ + google.maps.event.addListener(this.getMap(), "zoom_changed", function () { + cMarkerClusterer.resetViewport_(false); + // Workaround for this Google bug: when map is at level 0 and "-" of + // zoom slider is clicked, a "zoom_changed" event is fired even though + // the map doesn't zoom out any further. In this situation, no "idle" + // event is triggered so the cluster markers that have been removed + // do not get redrawn. Same goes for a zoom in at maxZoom. + if (this.getZoom() === (this.get("minZoom") || 0) || this.getZoom() === this.get("maxZoom")) { + google.maps.event.trigger(this, "idle"); + } + }), + google.maps.event.addListener(this.getMap(), "idle", function () { + cMarkerClusterer.redraw_(); + }) + ]; +}; + + +/** + * Implementation of the onRemove interface method. + * Removes map event listeners and all cluster icons from the DOM. + * All managed markers are also put back on the map. + * @ignore + */ +MarkerClusterer.prototype.onRemove = function () { + var i; + + // Put all the managed markers back on the map: + for (i = 0; i < this.markers_.length; i++) { + if (this.markers_[i].getMap() !== this.activeMap_) { + this.markers_[i].setMap(this.activeMap_); + } + } + + // Remove all clusters: + for (i = 0; i < this.clusters_.length; i++) { + this.clusters_[i].remove(); + } + this.clusters_ = []; + + // Remove map event listeners: + for (i = 0; i < this.listeners_.length; i++) { + google.maps.event.removeListener(this.listeners_[i]); + } + this.listeners_ = []; + + this.activeMap_ = null; + this.ready_ = false; +}; + + +/** + * Implementation of the draw interface method. + * @ignore + */ +MarkerClusterer.prototype.draw = function () {}; + + +/** + * Sets up the styles object. + */ +MarkerClusterer.prototype.setupStyles_ = function () { + var i, size; + if (this.styles_.length > 0) { + return; + } + + for (i = 0; i < this.imageSizes_.length; i++) { + size = this.imageSizes_[i]; + this.styles_.push({ + url: this.imagePath_ + (i + 1) + "." + this.imageExtension_, + height: size, + width: size + }); + } +}; + + +/** + * Fits the map to the bounds of the markers managed by the clusterer. + */ +MarkerClusterer.prototype.fitMapToMarkers = function () { + var i; + var markers = this.getMarkers(); + var bounds = new google.maps.LatLngBounds(); + for (i = 0; i < markers.length; i++) { + bounds.extend(markers[i].getPosition()); + } + + this.getMap().fitBounds(bounds); +}; + + +/** + * Returns the value of the gridSize property. + * + * @return {number} The grid size. + */ +MarkerClusterer.prototype.getGridSize = function () { + return this.gridSize_; +}; + + +/** + * Sets the value of the gridSize property. + * + * @param {number} gridSize The grid size. + */ +MarkerClusterer.prototype.setGridSize = function (gridSize) { + this.gridSize_ = gridSize; +}; + + +/** + * Returns the value of the minimumClusterSize property. + * + * @return {number} The minimum cluster size. + */ +MarkerClusterer.prototype.getMinimumClusterSize = function () { + return this.minClusterSize_; +}; + +/** + * Sets the value of the minimumClusterSize property. + * + * @param {number} minimumClusterSize The minimum cluster size. + */ +MarkerClusterer.prototype.setMinimumClusterSize = function (minimumClusterSize) { + this.minClusterSize_ = minimumClusterSize; +}; + + +/** + * Returns the value of the maxZoom property. + * + * @return {number} The maximum zoom level. + */ +MarkerClusterer.prototype.getMaxZoom = function () { + return this.maxZoom_; +}; + + +/** + * Sets the value of the maxZoom property. + * + * @param {number} maxZoom The maximum zoom level. + */ +MarkerClusterer.prototype.setMaxZoom = function (maxZoom) { + this.maxZoom_ = maxZoom; +}; + + +/** + * Returns the value of the styles property. + * + * @return {Array} The array of styles defining the cluster markers to be used. + */ +MarkerClusterer.prototype.getStyles = function () { + return this.styles_; +}; + + +/** + * Sets the value of the styles property. + * + * @param {Array.} styles The array of styles to use. + */ +MarkerClusterer.prototype.setStyles = function (styles) { + this.styles_ = styles; +}; + + +/** + * Returns the value of the title property. + * + * @return {string} The content of the title text. + */ +MarkerClusterer.prototype.getTitle = function () { + return this.title_; +}; + + +/** + * Sets the value of the title property. + * + * @param {string} title The value of the title property. + */ +MarkerClusterer.prototype.setTitle = function (title) { + this.title_ = title; +}; + + +/** + * Returns the value of the zoomOnClick property. + * + * @return {boolean} True if zoomOnClick property is set. + */ +MarkerClusterer.prototype.getZoomOnClick = function () { + return this.zoomOnClick_; +}; + + +/** + * Sets the value of the zoomOnClick property. + * + * @param {boolean} zoomOnClick The value of the zoomOnClick property. + */ +MarkerClusterer.prototype.setZoomOnClick = function (zoomOnClick) { + this.zoomOnClick_ = zoomOnClick; +}; + + +/** + * Returns the value of the averageCenter property. + * + * @return {boolean} True if averageCenter property is set. + */ +MarkerClusterer.prototype.getAverageCenter = function () { + return this.averageCenter_; +}; + + +/** + * Sets the value of the averageCenter property. + * + * @param {boolean} averageCenter The value of the averageCenter property. + */ +MarkerClusterer.prototype.setAverageCenter = function (averageCenter) { + this.averageCenter_ = averageCenter; +}; + + +/** + * Returns the value of the ignoreHidden property. + * + * @return {boolean} True if ignoreHidden property is set. + */ +MarkerClusterer.prototype.getIgnoreHidden = function () { + return this.ignoreHidden_; +}; + + +/** + * Sets the value of the ignoreHidden property. + * + * @param {boolean} ignoreHidden The value of the ignoreHidden property. + */ +MarkerClusterer.prototype.setIgnoreHidden = function (ignoreHidden) { + this.ignoreHidden_ = ignoreHidden; +}; + + +/** + * Returns the value of the enableRetinaIcons property. + * + * @return {boolean} True if enableRetinaIcons property is set. + */ +MarkerClusterer.prototype.getEnableRetinaIcons = function () { + return this.enableRetinaIcons_; +}; + + +/** + * Sets the value of the enableRetinaIcons property. + * + * @param {boolean} enableRetinaIcons The value of the enableRetinaIcons property. + */ +MarkerClusterer.prototype.setEnableRetinaIcons = function (enableRetinaIcons) { + this.enableRetinaIcons_ = enableRetinaIcons; +}; + + +/** + * Returns the value of the imageExtension property. + * + * @return {string} The value of the imageExtension property. + */ +MarkerClusterer.prototype.getImageExtension = function () { + return this.imageExtension_; +}; + + +/** + * Sets the value of the imageExtension property. + * + * @param {string} imageExtension The value of the imageExtension property. + */ +MarkerClusterer.prototype.setImageExtension = function (imageExtension) { + this.imageExtension_ = imageExtension; +}; + + +/** + * Returns the value of the imagePath property. + * + * @return {string} The value of the imagePath property. + */ +MarkerClusterer.prototype.getImagePath = function () { + return this.imagePath_; +}; + + +/** + * Sets the value of the imagePath property. + * + * @param {string} imagePath The value of the imagePath property. + */ +MarkerClusterer.prototype.setImagePath = function (imagePath) { + this.imagePath_ = imagePath; +}; + + +/** + * Returns the value of the imageSizes property. + * + * @return {Array} The value of the imageSizes property. + */ +MarkerClusterer.prototype.getImageSizes = function () { + return this.imageSizes_; +}; + + +/** + * Sets the value of the imageSizes property. + * + * @param {Array} imageSizes The value of the imageSizes property. + */ +MarkerClusterer.prototype.setImageSizes = function (imageSizes) { + this.imageSizes_ = imageSizes; +}; + + +/** + * Returns the value of the calculator property. + * + * @return {function} the value of the calculator property. + */ +MarkerClusterer.prototype.getCalculator = function () { + return this.calculator_; +}; + + +/** + * Sets the value of the calculator property. + * + * @param {function(Array., number)} calculator The value + * of the calculator property. + */ +MarkerClusterer.prototype.setCalculator = function (calculator) { + this.calculator_ = calculator; +}; + + +/** + * Returns the value of the batchSizeIE property. + * + * @return {number} the value of the batchSizeIE property. + */ +MarkerClusterer.prototype.getBatchSizeIE = function () { + return this.batchSizeIE_; +}; + + +/** + * Sets the value of the batchSizeIE property. + * + * @param {number} batchSizeIE The value of the batchSizeIE property. + */ +MarkerClusterer.prototype.setBatchSizeIE = function (batchSizeIE) { + this.batchSizeIE_ = batchSizeIE; +}; + + +/** + * Returns the value of the clusterClass property. + * + * @return {string} the value of the clusterClass property. + */ +MarkerClusterer.prototype.getClusterClass = function () { + return this.clusterClass_; +}; + + +/** + * Sets the value of the clusterClass property. + * + * @param {string} clusterClass The value of the clusterClass property. + */ +MarkerClusterer.prototype.setClusterClass = function (clusterClass) { + this.clusterClass_ = clusterClass; +}; + + +/** + * Returns the array of markers managed by the clusterer. + * + * @return {Array} The array of markers managed by the clusterer. + */ +MarkerClusterer.prototype.getMarkers = function () { + return this.markers_; +}; + + +/** + * Returns the number of markers managed by the clusterer. + * + * @return {number} The number of markers. + */ +MarkerClusterer.prototype.getTotalMarkers = function () { + return this.markers_.length; +}; + + +/** + * Returns the current array of clusters formed by the clusterer. + * + * @return {Array} The array of clusters formed by the clusterer. + */ +MarkerClusterer.prototype.getClusters = function () { + return this.clusters_; +}; + + +/** + * Returns the number of clusters formed by the clusterer. + * + * @return {number} The number of clusters formed by the clusterer. + */ +MarkerClusterer.prototype.getTotalClusters = function () { + return this.clusters_.length; +}; + + +/** + * Adds a marker to the clusterer. The clusters are redrawn unless + * opt_nodraw is set to true. + * + * @param {google.maps.Marker} marker The marker to add. + * @param {boolean} [opt_nodraw] Set to true to prevent redrawing. + */ +MarkerClusterer.prototype.addMarker = function (marker, opt_nodraw) { + this.pushMarkerTo_(marker); + if (!opt_nodraw) { + this.redraw_(); + } +}; + + +/** + * Adds an array of markers to the clusterer. The clusters are redrawn unless + * opt_nodraw is set to true. + * + * @param {Array.} markers The markers to add. + * @param {boolean} [opt_nodraw] Set to true to prevent redrawing. + */ +MarkerClusterer.prototype.addMarkers = function (markers, opt_nodraw) { + var key; + for (key in markers) { + if (markers.hasOwnProperty(key)) { + this.pushMarkerTo_(markers[key]); + } + } + if (!opt_nodraw) { + this.redraw_(); + } +}; + + +/** + * Pushes a marker to the clusterer. + * + * @param {google.maps.Marker} marker The marker to add. + */ +MarkerClusterer.prototype.pushMarkerTo_ = function (marker) { + // If the marker is draggable add a listener so we can update the clusters on the dragend: + if (marker.getDraggable()) { + var cMarkerClusterer = this; + google.maps.event.addListener(marker, "dragend", function () { + if (cMarkerClusterer.ready_) { + this.isAdded = false; + cMarkerClusterer.repaint(); + } + }); + } + marker.isAdded = false; + this.markers_.push(marker); +}; + + +/** + * Removes a marker from the cluster. The clusters are redrawn unless + * opt_nodraw is set to true. Returns true if the + * marker was removed from the clusterer. + * + * @param {google.maps.Marker} marker The marker to remove. + * @param {boolean} [opt_nodraw] Set to true to prevent redrawing. + * @return {boolean} True if the marker was removed from the clusterer. + */ +MarkerClusterer.prototype.removeMarker = function (marker, opt_nodraw) { + var removed = this.removeMarker_(marker); + + if (!opt_nodraw && removed) { + this.repaint(); + } + + return removed; +}; + + +/** + * Removes an array of markers from the cluster. The clusters are redrawn unless + * opt_nodraw is set to true. Returns true if markers + * were removed from the clusterer. + * + * @param {Array.} markers The markers to remove. + * @param {boolean} [opt_nodraw] Set to true to prevent redrawing. + * @return {boolean} True if markers were removed from the clusterer. + */ +MarkerClusterer.prototype.removeMarkers = function (markers, opt_nodraw) { + var i, r; + var removed = false; + + for (i = 0; i < markers.length; i++) { + r = this.removeMarker_(markers[i]); + removed = removed || r; + } + + if (!opt_nodraw && removed) { + this.repaint(); + } + + return removed; +}; + + +/** + * Removes a marker and returns true if removed, false if not. + * + * @param {google.maps.Marker} marker The marker to remove + * @return {boolean} Whether the marker was removed or not + */ +MarkerClusterer.prototype.removeMarker_ = function (marker) { + var i; + var index = -1; + if (this.markers_.indexOf) { + index = this.markers_.indexOf(marker); + } else { + for (i = 0; i < this.markers_.length; i++) { + if (marker === this.markers_[i]) { + index = i; + break; + } + } + } + + if (index === -1) { + // Marker is not in our list of markers, so do nothing: + return false; + } + + marker.setMap(null); + this.markers_.splice(index, 1); // Remove the marker from the list of managed markers + return true; +}; + + +/** + * Removes all clusters and markers from the map and also removes all markers + * managed by the clusterer. + */ +MarkerClusterer.prototype.clearMarkers = function () { + this.resetViewport_(true); + this.markers_ = []; +}; + + +/** + * Recalculates and redraws all the marker clusters from scratch. + * Call this after changing any properties. + */ +MarkerClusterer.prototype.repaint = function () { + var oldClusters = this.clusters_.slice(); + this.clusters_ = []; + this.resetViewport_(false); + this.redraw_(); + + // Remove the old clusters. + // Do it in a timeout to prevent blinking effect. + setTimeout(function () { + var i; + for (i = 0; i < oldClusters.length; i++) { + oldClusters[i].remove(); + } + }, 0); +}; + + +/** + * Returns the current bounds extended by the grid size. + * + * @param {google.maps.LatLngBounds} bounds The bounds to extend. + * @return {google.maps.LatLngBounds} The extended bounds. + * @ignore + */ +MarkerClusterer.prototype.getExtendedBounds = function (bounds) { + var projection = this.getProjection(); + + // Turn the bounds into latlng. + var tr = new google.maps.LatLng(bounds.getNorthEast().lat(), + bounds.getNorthEast().lng()); + var bl = new google.maps.LatLng(bounds.getSouthWest().lat(), + bounds.getSouthWest().lng()); + + // Convert the points to pixels and the extend out by the grid size. + var trPix = projection.fromLatLngToDivPixel(tr); + trPix.x += this.gridSize_; + trPix.y -= this.gridSize_; + + var blPix = projection.fromLatLngToDivPixel(bl); + blPix.x -= this.gridSize_; + blPix.y += this.gridSize_; + + // Convert the pixel points back to LatLng + var ne = projection.fromDivPixelToLatLng(trPix); + var sw = projection.fromDivPixelToLatLng(blPix); + + // Extend the bounds to contain the new bounds. + bounds.extend(ne); + bounds.extend(sw); + + return bounds; +}; + + +/** + * Redraws all the clusters. + */ +MarkerClusterer.prototype.redraw_ = function () { + this.createClusters_(0); +}; + + +/** + * Removes all clusters from the map. The markers are also removed from the map + * if opt_hide is set to true. + * + * @param {boolean} [opt_hide] Set to true to also remove the markers + * from the map. + */ +MarkerClusterer.prototype.resetViewport_ = function (opt_hide) { + var i, marker; + // Remove all the clusters + for (i = 0; i < this.clusters_.length; i++) { + this.clusters_[i].remove(); + } + this.clusters_ = []; + + // Reset the markers to not be added and to be removed from the map. + for (i = 0; i < this.markers_.length; i++) { + marker = this.markers_[i]; + marker.isAdded = false; + if (opt_hide) { + marker.setMap(null); + } + } +}; + + +/** + * Calculates the distance between two latlng locations in km. + * + * @param {google.maps.LatLng} p1 The first lat lng point. + * @param {google.maps.LatLng} p2 The second lat lng point. + * @return {number} The distance between the two points in km. + * @see http://www.movable-type.co.uk/scripts/latlong.html +*/ +MarkerClusterer.prototype.distanceBetweenPoints_ = function (p1, p2) { + var R = 6371; // Radius of the Earth in km + var dLat = (p2.lat() - p1.lat()) * Math.PI / 180; + var dLon = (p2.lng() - p1.lng()) * Math.PI / 180; + var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) * + Math.sin(dLon / 2) * Math.sin(dLon / 2); + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + var d = R * c; + return d; +}; + + +/** + * Determines if a marker is contained in a bounds. + * + * @param {google.maps.Marker} marker The marker to check. + * @param {google.maps.LatLngBounds} bounds The bounds to check against. + * @return {boolean} True if the marker is in the bounds. + */ +MarkerClusterer.prototype.isMarkerInBounds_ = function (marker, bounds) { + return bounds.contains(marker.getPosition()); +}; + + +/** + * Adds a marker to a cluster, or creates a new cluster. + * + * @param {google.maps.Marker} marker The marker to add. + */ +MarkerClusterer.prototype.addToClosestCluster_ = function (marker) { + var i, d, cluster, center; + var distance = 40000; // Some large number + var clusterToAddTo = null; + for (i = 0; i < this.clusters_.length; i++) { + cluster = this.clusters_[i]; + center = cluster.getCenter(); + if (center) { + d = this.distanceBetweenPoints_(center, marker.getPosition()); + if (d < distance) { + distance = d; + clusterToAddTo = cluster; + } + } + } + + if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) { + clusterToAddTo.addMarker(marker); + } else { + cluster = new Cluster(this); + cluster.addMarker(marker); + this.clusters_.push(cluster); + } +}; + + +/** + * Creates the clusters. This is done in batches to avoid timeout errors + * in some browsers when there is a huge number of markers. + * + * @param {number} iFirst The index of the first marker in the batch of + * markers to be added to clusters. + */ +MarkerClusterer.prototype.createClusters_ = function (iFirst) { + var i, marker; + var mapBounds; + var cMarkerClusterer = this; + if (!this.ready_) { + return; + } + + // Cancel previous batch processing if we're working on the first batch: + if (iFirst === 0) { + /** + * This event is fired when the MarkerClusterer begins + * clustering markers. + * @name MarkerClusterer#clusteringbegin + * @param {MarkerClusterer} mc The MarkerClusterer whose markers are being clustered. + * @event + */ + google.maps.event.trigger(this, "clusteringbegin", this); + + if (typeof this.timerRefStatic !== "undefined") { + clearTimeout(this.timerRefStatic); + delete this.timerRefStatic; + } + } + + // Get our current map view bounds. + // Create a new bounds object so we don't affect the map. + // + // See Comments 9 & 11 on Issue 3651 relating to this workaround for a Google Maps bug: + if (this.getMap().getZoom() > 3) { + mapBounds = new google.maps.LatLngBounds(this.getMap().getBounds().getSouthWest(), + this.getMap().getBounds().getNorthEast()); + } else { + mapBounds = new google.maps.LatLngBounds(new google.maps.LatLng(85.02070771743472, -178.48388434375), new google.maps.LatLng(-85.08136444384544, 178.00048865625)); + } + var bounds = this.getExtendedBounds(mapBounds); + + var iLast = Math.min(iFirst + this.batchSize_, this.markers_.length); + + for (i = iFirst; i < iLast; i++) { + marker = this.markers_[i]; + if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) { + if (!this.ignoreHidden_ || (this.ignoreHidden_ && marker.getVisible())) { + this.addToClosestCluster_(marker); + } + } + } + + if (iLast < this.markers_.length) { + this.timerRefStatic = setTimeout(function () { + cMarkerClusterer.createClusters_(iLast); + }, 0); + } else { + delete this.timerRefStatic; + + /** + * This event is fired when the MarkerClusterer stops + * clustering markers. + * @name MarkerClusterer#clusteringend + * @param {MarkerClusterer} mc The MarkerClusterer whose markers are being clustered. + * @event + */ + google.maps.event.trigger(this, "clusteringend", this); + } +}; + + +/** + * Extends an object's prototype by another's. + * + * @param {Object} obj1 The object to be extended. + * @param {Object} obj2 The object to extend with. + * @return {Object} The new extended object. + * @ignore + */ +MarkerClusterer.prototype.extend = function (obj1, obj2) { + return (function (object) { + var property; + for (property in object.prototype) { + this.prototype[property] = object.prototype[property]; + } + return this; + }).apply(obj1, [obj2]); +}; + + +/** + * The default function for determining the label text and style + * for a cluster icon. + * + * @param {Array.} markers The array of markers represented by the cluster. + * @param {number} numStyles The number of marker styles available. + * @return {ClusterIconInfo} The information resource for the cluster. + * @constant + * @ignore + */ +MarkerClusterer.CALCULATOR = function (markers, numStyles) { + var index = 0; + var title = ""; + var count = markers.length.toString(); + + var dv = count; + while (dv !== 0) { + dv = parseInt(dv / 10, 10); + index++; + } + + index = Math.min(index, numStyles); + return { + text: count, + index: index, + title: title + }; +}; + + +/** + * The number of markers to process in one batch. + * + * @type {number} + * @constant + */ +MarkerClusterer.BATCH_SIZE = 2000; + + +/** + * The number of markers to process in one batch (IE only). + * + * @type {number} + * @constant + */ +MarkerClusterer.BATCH_SIZE_IE = 500; + + +/** + * The default root name for the marker cluster images. + * + * @type {string} + * @constant + */ +MarkerClusterer.IMAGE_PATH = "http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclustererplus/images/m"; + + +/** + * The default extension name for the marker cluster images. + * + * @type {string} + * @constant + */ +MarkerClusterer.IMAGE_EXTENSION = "png"; + + +/** + * The default array of sizes for the marker cluster images. + * + * @type {Array.} + * @constant + */ +MarkerClusterer.IMAGE_SIZES = [53, 56, 66, 78, 90]; + +if (typeof String.prototype.trim !== 'function') { + /** + * IE hack since trim() doesn't exist in all browsers + * @return {string} The string with removed whitespace + */ + String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g, ''); + } +} \ No newline at end of file diff --git a/assets/js/mortgage.js b/assets/js/mortgage.js new file mode 100755 index 00000000..f1a9c3dc --- /dev/null +++ b/assets/js/mortgage.js @@ -0,0 +1,51 @@ +(function ($) { + 'use strict' + $(document).ready(function ($) { + if (typeof opalestate_mortgage !== 'undefined') { + var currency = opalestate_mortgage.currency + var loan_amount_text = opalestate_mortgage.loan_amount_text + var your_payment_text = opalestate_mortgage.your_payment_text + + $('.opalestate-mortgage-form input').change(function (e) { + e.preventDefault() + var $el = $(this), + $widget = $el.closest('.opalestate-mortgage-widget-wrap') + + var sale_price = $widget.find('input[name="sale_price"]').val() + var precent_down = $widget.find('input[name="deposit"]').val() + var years = parseInt($widget.find('input[name="years"]').val(), 10) + var interest_rate = parseFloat($widget.find('input[name="interest_rate"]').val(), 10) / 100 + + var interest_rate_month = interest_rate / 12 + var number_of_payments_month = years * 12 + + var loan_amount = sale_price - precent_down + var monthly_payment = parseFloat( + (loan_amount * interest_rate_month) / (1 - Math.pow(1 + interest_rate_month, -number_of_payments_month))) + .toFixed(2) + + if (monthly_payment === 'NaN') { + monthly_payment = 0 + } + + var total = parseFloat(precent_down) + parseFloat(monthly_payment * number_of_payments_month) + var price_percent = loan_amount / total * 100 + var deposit_percent = precent_down / total * 100 + + $widget.find('.opalestate-monthly-value').html(currency + monthly_payment) + + $widget.find('.opalestate-loan-amount-value').html(currency + loan_amount) + + $widget.find('.opalestate-mortgage-chart-svg').html( + '' + + '' + + '' + + '' + + '' + + '' + ) + }) + } + }) +})(jQuery) diff --git a/assets/js/nouislider.min.js b/assets/js/nouislider.min.js new file mode 100755 index 00000000..62506275 --- /dev/null +++ b/assets/js/nouislider.min.js @@ -0,0 +1,340 @@ +(function(){ + + 'use strict'; + +var +/** @const */ FormatOptions = [ + 'decimals', + 'thousand', + 'mark', + 'prefix', + 'postfix', + 'encoder', + 'decoder', + 'negativeBefore', + 'negative', + 'edit', + 'undo' +]; + +// General + + // Reverse a string + function strReverse ( a ) { + return a.split('').reverse().join(''); + } + + // Check if a string starts with a specified prefix. + function strStartsWith ( input, match ) { + return input.substring(0, match.length) === match; + } + + // Check is a string ends in a specified postfix. + function strEndsWith ( input, match ) { + return input.slice(-1 * match.length) === match; + } + + // Throw an error if formatting options are incompatible. + function throwEqualError( F, a, b ) { + if ( (F[a] || F[b]) && (F[a] === F[b]) ) { + throw new Error(a); + } + } + + // Check if a number is finite and not NaN + function isValidNumber ( input ) { + return typeof input === 'number' && isFinite( input ); + } + + // Provide rounding-accurate toFixed method. + function toFixed ( value, decimals ) { + var scale = Math.pow(10, decimals); + return ( Math.round(value * scale) / scale).toFixed( decimals ); + } + + +// Formatting + + // Accept a number as input, output formatted string. + function formatTo ( decimals, thousand, mark, prefix, postfix, encoder, decoder, negativeBefore, negative, edit, undo, input ) { + + var originalInput = input, inputIsNegative, inputPieces, inputBase, inputDecimals = '', output = ''; + + // Apply user encoder to the input. + // Expected outcome: number. + if ( encoder ) { + input = encoder(input); + } + + // Stop if no valid number was provided, the number is infinite or NaN. + if ( !isValidNumber(input) ) { + return false; + } + + // Rounding away decimals might cause a value of -0 + // when using very small ranges. Remove those cases. + if ( decimals !== false && parseFloat(input.toFixed(decimals)) === 0 ) { + input = 0; + } + + // Formatting is done on absolute numbers, + // decorated by an optional negative symbol. + if ( input < 0 ) { + inputIsNegative = true; + input = Math.abs(input); + } + + // Reduce the number of decimals to the specified option. + if ( decimals !== false ) { + input = toFixed( input, decimals ); + } + + // Transform the number into a string, so it can be split. + input = input.toString(); + + // Break the number on the decimal separator. + if ( input.indexOf('.') !== -1 ) { + inputPieces = input.split('.'); + + inputBase = inputPieces[0]; + + if ( mark ) { + inputDecimals = mark + inputPieces[1]; + } + + } else { + + // If it isn't split, the entire number will do. + inputBase = input; + } + + // Group numbers in sets of three. + if ( thousand ) { + inputBase = strReverse(inputBase).match(/.{1,3}/g); + inputBase = strReverse(inputBase.join( strReverse( thousand ) )); + } + + // If the number is negative, prefix with negation symbol. + if ( inputIsNegative && negativeBefore ) { + output += negativeBefore; + } + + // Prefix the number + if ( prefix ) { + output += prefix; + } + + // Normal negative option comes after the prefix. Defaults to '-'. + if ( inputIsNegative && negative ) { + output += negative; + } + + // Append the actual number. + output += inputBase; + output += inputDecimals; + + // Apply the postfix. + if ( postfix ) { + output += postfix; + } + + // Run the output through a user-specified post-formatter. + if ( edit ) { + output = edit ( output, originalInput ); + } + + // All done. + return output; + } + + // Accept a sting as input, output decoded number. + function formatFrom ( decimals, thousand, mark, prefix, postfix, encoder, decoder, negativeBefore, negative, edit, undo, input ) { + + var originalInput = input, inputIsNegative, output = ''; + + // User defined pre-decoder. Result must be a non empty string. + if ( undo ) { + input = undo(input); + } + + // Test the input. Can't be empty. + if ( !input || typeof input !== 'string' ) { + return false; + } + + // If the string starts with the negativeBefore value: remove it. + // Remember is was there, the number is negative. + if ( negativeBefore && strStartsWith(input, negativeBefore) ) { + input = input.replace(negativeBefore, ''); + inputIsNegative = true; + } + + // Repeat the same procedure for the prefix. + if ( prefix && strStartsWith(input, prefix) ) { + input = input.replace(prefix, ''); + } + + // And again for negative. + if ( negative && strStartsWith(input, negative) ) { + input = input.replace(negative, ''); + inputIsNegative = true; + } + + // Remove the postfix. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice + if ( postfix && strEndsWith(input, postfix) ) { + input = input.slice(0, -1 * postfix.length); + } + + // Remove the thousand grouping. + if ( thousand ) { + input = input.split(thousand).join(''); + } + + // Set the decimal separator back to period. + if ( mark ) { + input = input.replace(mark, '.'); + } + + // Prepend the negative symbol. + if ( inputIsNegative ) { + output += '-'; + } + + // Add the number + output += input; + + // Trim all non-numeric characters (allow '.' and '-'); + output = output.replace(/[^0-9\.\-.]/g, ''); + + // The value contains no parse-able number. + if ( output === '' ) { + return false; + } + + // Covert to number. + output = Number(output); + + // Run the user-specified post-decoder. + if ( decoder ) { + output = decoder(output); + } + + // Check is the output is valid, otherwise: return false. + if ( !isValidNumber(output) ) { + return false; + } + + return output; + } + + +// Framework + + // Validate formatting options + function validate ( inputOptions ) { + + var i, optionName, optionValue, + filteredOptions = {}; + + for ( i = 0; i < FormatOptions.length; i+=1 ) { + + optionName = FormatOptions[i]; + optionValue = inputOptions[optionName]; + + if ( optionValue === undefined ) { + + // Only default if negativeBefore isn't set. + if ( optionName === 'negative' && !filteredOptions.negativeBefore ) { + filteredOptions[optionName] = '-'; + // Don't set a default for mark when 'thousand' is set. + } else if ( optionName === 'mark' && filteredOptions.thousand !== '.' ) { + filteredOptions[optionName] = '.'; + } else { + filteredOptions[optionName] = false; + } + + // Floating points in JS are stable up to 7 decimals. + } else if ( optionName === 'decimals' ) { + if ( optionValue >= 0 && optionValue < 8 ) { + filteredOptions[optionName] = optionValue; + } else { + throw new Error(optionName); + } + + // These options, when provided, must be functions. + } else if ( optionName === 'encoder' || optionName === 'decoder' || optionName === 'edit' || optionName === 'undo' ) { + if ( typeof optionValue === 'function' ) { + filteredOptions[optionName] = optionValue; + } else { + throw new Error(optionName); + } + + // Other options are strings. + } else { + + if ( typeof optionValue === 'string' ) { + filteredOptions[optionName] = optionValue; + } else { + throw new Error(optionName); + } + } + } + + // Some values can't be extracted from a + // string if certain combinations are present. + throwEqualError(filteredOptions, 'mark', 'thousand'); + throwEqualError(filteredOptions, 'prefix', 'negative'); + throwEqualError(filteredOptions, 'prefix', 'negativeBefore'); + + return filteredOptions; + } + + // Pass all options as function arguments + function passAll ( options, method, input ) { + var i, args = []; + + // Add all options in order of FormatOptions + for ( i = 0; i < FormatOptions.length; i+=1 ) { + args.push(options[FormatOptions[i]]); + } + + // Append the input, then call the method, presenting all + // options as arguments. + args.push(input); + return method.apply('', args); + } + + /** @constructor */ + function wNumb ( options ) { + + if ( !(this instanceof wNumb) ) { + return new wNumb ( options ); + } + + if ( typeof options !== "object" ) { + return; + } + + options = validate(options); + + // Call 'formatTo' with proper arguments. + this.to = function ( input ) { + return passAll(options, formatTo, input); + }; + + // Call 'formatFrom' with proper arguments. + this.from = function ( input ) { + return passAll(options, formatFrom, input); + }; + } + + /** @export */ + window.wNumb = wNumb; + +}()); + + +/*! nouislider - 9.0.0 - 2019-09-29 21:44:02 */ + +!function(a){"function"==typeof define&&define.amd?define([],a):"object"==typeof exports?module.exports=a():window.noUiSlider=a()}(function(){"use strict";function a(a,b){var c=document.createElement("div");return j(c,b),a.appendChild(c),c}function b(a){return a.filter(function(a){return!this[a]&&(this[a]=!0)},{})}function c(a,b){return Math.round(a/b)*b}function d(a,b){var c=a.getBoundingClientRect(),d=a.ownerDocument,e=d.documentElement,f=m();return/webkit.*Chrome.*Mobile/i.test(navigator.userAgent)&&(f.x=0),b?c.top+f.y-e.clientTop:c.left+f.x-e.clientLeft}function e(a){return"number"==typeof a&&!isNaN(a)&&isFinite(a)}function f(a,b,c){c>0&&(j(a,b),setTimeout(function(){k(a,b)},c))}function g(a){return Math.max(Math.min(a,100),0)}function h(a){return Array.isArray(a)?a:[a]}function i(a){a=String(a);var b=a.split(".");return b.length>1?b[1].length:0}function j(a,b){a.classList?a.classList.add(b):a.className+=" "+b}function k(a,b){a.classList?a.classList.remove(b):a.className=a.className.replace(new RegExp("(^|\\b)"+b.split(" ").join("|")+"(\\b|$)","gi")," ")}function l(a,b){return a.classList?a.classList.contains(b):new RegExp("\\b"+b+"\\b").test(a.className)}function m(){var a=void 0!==window.pageXOffset,b="CSS1Compat"===(document.compatMode||""),c=a?window.pageXOffset:b?document.documentElement.scrollLeft:document.body.scrollLeft,d=a?window.pageYOffset:b?document.documentElement.scrollTop:document.body.scrollTop;return{x:c,y:d}}function n(){return window.navigator.pointerEnabled?{start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled?{start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}:{start:"mousedown touchstart",move:"mousemove touchmove",end:"mouseup touchend"}}function o(a,b){return 100/(b-a)}function p(a,b){return 100*b/(a[1]-a[0])}function q(a,b){return p(a,a[0]<0?b+Math.abs(a[0]):b-a[0])}function r(a,b){return b*(a[1]-a[0])/100+a[0]}function s(a,b){for(var c=1;a>=b[c];)c+=1;return c}function t(a,b,c){if(c>=a.slice(-1)[0])return 100;var d,e,f,g,h=s(c,a);return d=a[h-1],e=a[h],f=b[h-1],g=b[h],f+q([d,e],c)/o(f,g)}function u(a,b,c){if(c>=100)return a.slice(-1)[0];var d,e,f,g,h=s(c,b);return d=a[h-1],e=a[h],f=b[h-1],g=b[h],r([d,e],(c-f)*o(f,g))}function v(a,b,d,e){if(100===e)return e;var f,g,h=s(e,a);return d?(f=a[h-1],g=a[h],e-f>(g-f)/2?g:f):b[h-1]?a[h-1]+c(e-a[h-1],b[h-1]):e}function w(a,b,c){var d;if("number"==typeof b&&(b=[b]),"[object Array]"!==Object.prototype.toString.call(b))throw new Error("noUiSlider: 'range' contains invalid value.");if(d="min"===a?0:"max"===a?100:parseFloat(a),!e(d)||!e(b[0]))throw new Error("noUiSlider: 'range' value isn't numeric.");c.xPct.push(d),c.xVal.push(b[0]),d?c.xSteps.push(!isNaN(b[1])&&b[1]):isNaN(b[1])||(c.xSteps[0]=b[1]),c.xHighestCompleteStep.push(0)}function x(a,b,c){if(!b)return!0;c.xSteps[a]=p([c.xVal[a],c.xVal[a+1]],b)/o(c.xPct[a],c.xPct[a+1]);var d=(c.xVal[a+1]-c.xVal[a])/c.xNumSteps[a],e=Math.ceil(Number(d.toFixed(3))-1),f=c.xVal[a]+c.xNumSteps[a]*e;c.xHighestCompleteStep[a]=f}function y(a,b,c,d){this.xPct=[],this.xVal=[],this.xSteps=[d||!1],this.xNumSteps=[!1],this.xHighestCompleteStep=[],this.snap=b,this.direction=c;var e,f=[];for(e in a)a.hasOwnProperty(e)&&f.push([a[e],e]);for(f.length&&"object"==typeof f[0][0]?f.sort(function(a,b){return a[0][0]-b[0][0]}):f.sort(function(a,b){return a[0]-b[0]}),e=0;e=0,d=b.indexOf("drag")>=0,e=b.indexOf("fixed")>=0,f=b.indexOf("snap")>=0,g=b.indexOf("hover")>=0;if(e){if(2!==a.handles)throw new Error("noUiSlider: 'fixed' behaviour must be used with 2 handles");H(a,a.start[1]-a.start[0])}a.events={tap:c||f,drag:d,fixed:e,snap:f,hover:g}}function L(a,b){if(b!==!1)if(b===!0){a.tooltips=[];for(var c=0;c-1?1:"steps"===c?2:0,!g&&i&&(q=0),l===v&&j||(f[n.toFixed(5)]=[l,q]),k=n}}),f}function w(a,b,c){function d(a,b){var c=b===e.cssClasses.value,d=c?m:n,f=c?k:l;return b+" "+d[e.ort]+" "+f[a]}function f(a,b,c){return'class="'+d(c[1],b)+'" style="'+e.style+": "+a+'%"'}function g(a,d){d[1]=d[1]&&b?b(d[0],d[1]):d[1],i+="
            ",d[1]&&(i+="
            "+c.to(d[0])+"
            ")}var h=document.createElement("div"),i="",k=[e.cssClasses.valueNormal,e.cssClasses.valueLarge,e.cssClasses.valueSub],l=[e.cssClasses.markerNormal,e.cssClasses.markerLarge,e.cssClasses.markerSub],m=[e.cssClasses.valueHorizontal,e.cssClasses.valueVertical],n=[e.cssClasses.markerHorizontal,e.cssClasses.markerVertical];return j(h,e.cssClasses.pips),j(h,0===e.ort?e.cssClasses.pipsHorizontal:e.cssClasses.pipsVertical),Object.keys(a).forEach(function(b){g(b,a[b])}),h.innerHTML=i,h}function x(a){var b=a.mode,c=a.density||1,d=a.filter||!1,e=a.values||!1,f=a.stepped||!1,g=u(b,e,f),h=v(c,b,g),i=a.format||{to:Math.round};return fa.appendChild(w(h,d,i))}function y(){var a=aa.getBoundingClientRect(),b="offset"+["Width","Height"][e.ort];return 0===e.ort?a.width||aa[b]:a.height||aa[b]}function z(a,b,c,d){var f=function(b){return!fa.hasAttribute("disabled")&&(!l(fa,e.cssClasses.tap)&&(b=A(b,d.pageOffset),!(a===ea.start&&void 0!==b.buttons&&b.buttons>1)&&((!d.hover||!b.buttons)&&(b.calcPoint=b.points[e.ort],void c(b,d)))))},g=[];return a.split(" ").forEach(function(a){b.addEventListener(a,f,!1),g.push([a,f])}),g}function A(a,b){a.preventDefault();var c,d,e=0===a.type.indexOf("touch"),f=0===a.type.indexOf("mouse"),g=0===a.type.indexOf("pointer"),h=a;if(0===a.type.indexOf("MSPointer")&&(g=!0),e){if(h.touches.length>1)return!1;c=a.changedTouches[0].pageX,d=a.changedTouches[0].pageY}return b=b||m(),(f||g)&&(c=a.clientX+b.x,d=a.clientY+b.y),h.pageOffset=b,h.points=[c,d],h.cursor=f||g,h}function B(a){var b=a-d(aa,e.ort),c=100*b/y();return e.dir?100-c:c}function C(a){var b=100,c=!1;return ba.forEach(function(d,e){if(!d.hasAttribute("disabled")){var f=Math.abs(ga[e]-a);f1?d.forEach(function(a,c){var d=M(e,a,e[a]+b,f[c],g[c]);d===!1?b=0:(b=d-e[a],e[a]=d)}):f=g=[!0];var h=!1;d.forEach(function(a,d){h=R(a,c[a]+b,f[d],g[d])||h}),h&&d.forEach(function(a){E("update",a),E("slide",a)})}function E(a,b,c){Object.keys(ka).forEach(function(d){var f=d.split(".")[0];a===f&&ka[d].forEach(function(a){a.call(da,ja.map(e.format.to),b,ja.slice(),c||!1,ga.slice())})})}function F(a,b){"mouseout"===a.type&&"HTML"===a.target.nodeName&&null===a.relatedTarget&&H(a,b)}function G(a,b){if(navigator.appVersion.indexOf("MSIE 9")===-1&&0===a.buttons&&0!==b.buttonsProperty)return H(a,b);var c=(e.dir?-1:1)*(a.calcPoint-b.startCalcPoint),d=100*c/b.baseSize;D(c>0,d,b.locations,b.handleNumbers)}function H(a,b){var c=aa.querySelector("."+e.cssClasses.active);null!==c&&k(c,e.cssClasses.active),a.cursor&&(document.body.style.cursor="",document.body.removeEventListener("selectstart",document.body.noUiListener)),document.documentElement.noUiListeners.forEach(function(a){document.documentElement.removeEventListener(a[0],a[1])}),k(fa,e.cssClasses.drag),P(),b.handleNumbers.forEach(function(a){E("set",a),E("change",a),E("end",a)})}function I(a,b){if(1===b.handleNumbers.length){var c=ba[b.handleNumbers[0]];if(c.hasAttribute("disabled"))return!1;j(c.children[0],e.cssClasses.active)}a.preventDefault(),a.stopPropagation();var d=z(ea.move,document.documentElement,G,{startCalcPoint:a.calcPoint,baseSize:y(),pageOffset:a.pageOffset,handleNumbers:b.handleNumbers,buttonsProperty:a.buttons,locations:ga.slice()}),f=z(ea.end,document.documentElement,H,{handleNumbers:b.handleNumbers}),g=z("mouseout",document.documentElement,F,{handleNumbers:b.handleNumbers});if(document.documentElement.noUiListeners=d.concat(f,g),a.cursor){document.body.style.cursor=getComputedStyle(a.target).cursor,ba.length>1&&j(fa,e.cssClasses.drag);var h=function(){return!1};document.body.noUiListener=h,document.body.addEventListener("selectstart",h,!1)}b.handleNumbers.forEach(function(a){E("start",a)})}function J(a){a.stopPropagation();var b=B(a.calcPoint),c=C(b);return c!==!1&&(e.events.snap||f(fa,e.cssClasses.tap,e.animationDuration),R(c,b,!0,!0),P(),E("slide",c,!0),E("set",c,!0),E("change",c,!0),E("update",c,!0),void(e.events.snap&&I(a,{handleNumbers:[c]})))}function K(a){var b=B(a.calcPoint),c=ia.getStep(b),d=ia.fromStepping(c);Object.keys(ka).forEach(function(a){"hover"===a.split(".")[0]&&ka[a].forEach(function(a){a.call(da,d)})})}function L(a){a.fixed||ba.forEach(function(a,b){z(ea.start,a.children[0],I,{handleNumbers:[b]})}),a.tap&&z(ea.start,aa,J,{}),a.hover&&z(ea.move,aa,K,{hover:!0}),a.drag&&ca.forEach(function(b,c){if(b!==!1&&0!==c&&c!==ca.length-1){var d=ba[c-1],f=ba[c],g=[b];j(b,e.cssClasses.draggable),a.fixed&&(g.push(d.children[0]),g.push(f.children[0])),g.forEach(function(a){z(ea.start,a,I,{handles:[d,f],handleNumbers:[c-1,c]})})}})}function M(a,b,c,d,f){return ba.length>1&&(d&&b>0&&(c=Math.max(c,a[b-1]+e.margin)),f&&b1&&e.limit&&(d&&b>0&&(c=Math.min(c,a[b-1]+e.limit)),f&&b50?-1:1,c=3+(ba.length+b*a);ba[a].childNodes[0].style.zIndex=c})}function R(a,b,c,d){return b=M(ga,a,b,c,d),b!==!1&&(O(a,b),!0)}function S(a){if(ca[a]){var b=0,c=100;0!==a&&(b=ga[a-1]),a!==ca.length-1&&(c=ga[a]),ca[a].style[e.style]=N(b),ca[a].style[e.styleOposite]=N(100-c)}}function T(a,b){null!==a&&a!==!1&&("number"==typeof a&&(a=String(a)),a=e.format.from(a),a===!1||isNaN(a)||R(b,ia.toStepping(a),!1,!1))}function U(a,b){var c=h(a),d=void 0===ga[0];b=void 0===b||!!b,c.forEach(T),e.animate&&!d&&f(fa,e.cssClasses.tap,e.animationDuration),ha.forEach(function(a){R(a,ga[a],!0,!1)}),P(),ha.forEach(function(a){E("update",a),null!==c[a]&&b&&E("set",a)})}function V(a){U(e.start,a)}function W(){var a=ja.map(e.format.to);return 1===a.length?a[0]:a}function X(){for(var a in e.cssClasses)e.cssClasses.hasOwnProperty(a)&&k(fa,e.cssClasses[a]);for(;fa.firstChild;)fa.removeChild(fa.firstChild);delete fa.noUiSlider}function Y(){return ga.map(function(a,b){var c=ia.getNearbySteps(a),d=ja[b],e=c.thisStep.step,f=null;e!==!1&&d+e>c.stepAfter.startValue&&(e=c.stepAfter.startValue-d),f=d>c.thisStep.startValue?c.thisStep.step:c.stepBefore.step!==!1&&d-c.stepBefore.highestStep,100===a?e=null:0===a&&(f=null);var g=ia.countStepDecimals();return null!==e&&e!==!1&&(e=Number(e.toFixed(g))),null!==f&&f!==!1&&(f=Number(f.toFixed(g))),[f,e]})}function Z(a,b){ka[a]=ka[a]||[],ka[a].push(b),"update"===a.split(".")[0]&&ba.forEach(function(a,b){E("update",b)})}function $(a){var b=a&&a.split(".")[0],c=b&&a.substring(b.length);Object.keys(ka).forEach(function(a){var d=a.split(".")[0],e=a.substring(d.length);b&&b!==d||c&&c!==e||delete ka[a]})}function _(a,b){var c=W(),d=["margin","limit","range","animate","snap","step","format"];d.forEach(function(b){void 0!==a[b]&&(i[b]=a[b])});var f=Q(i);d.forEach(function(b){void 0!==a[b]&&(e[b]=f[b])}),f.spectrum.direction=ia.direction,ia=f.spectrum,e.margin=f.margin,e.limit=f.limit,ga=[],U(a.start||c,b)}var aa,ba,ca,da,ea=n(),fa=c,ga=[],ha=[],ia=e.spectrum,ja=[],ka={};if(fa.noUiSlider)throw new Error("Slider was already initialized.");return r(fa),q(e.connect,aa),da={destroy:X,steps:Y,on:Z,off:$,get:W,set:U,reset:V,__moveHandles:function(a,b,c){D(a,b,ga,c)},options:i,updateOptions:_,target:fa,pips:x},L(e.events),U(e.start),e.pips&&x(e.pips),e.tooltips&&t(),da}function S(a,b){if(!a.nodeName)throw new Error("noUiSlider.create requires a single element.");var c=Q(b,a),d=R(a,c,b);return a.noUiSlider=d,d}y.prototype.getMargin=function(a){var b=this.xNumSteps[0];if(b&&a%b)throw new Error("noUiSlider: 'limit' and 'margin' must be divisible by step.");return 2===this.xPct.length&&p(this.xVal,a)},y.prototype.toStepping=function(a){return a=t(this.xVal,this.xPct,a)},y.prototype.fromStepping=function(a){return u(this.xVal,this.xPct,a)},y.prototype.getStep=function(a){return a=v(this.xPct,this.xSteps,this.snap,a)},y.prototype.getNearbySteps=function(a){var b=s(a,this.xPct);return{stepBefore:{startValue:this.xVal[b-2],step:this.xNumSteps[b-2],highestStep:this.xHighestCompleteStep[b-2]},thisStep:{startValue:this.xVal[b-1],step:this.xNumSteps[b-1],highestStep:this.xHighestCompleteStep[b-1]},stepAfter:{startValue:this.xVal[b-0],step:this.xNumSteps[b-0],highestStep:this.xHighestCompleteStep[b-0]}}},y.prototype.countStepDecimals=function(){var a=this.xNumSteps.map(i);return Math.max.apply(null,a)},y.prototype.convert=function(a){return this.getStep(this.toStepping(a))};var T={to:function(a){return void 0!==a&&a.toFixed(2)},from:Number};return{create:S}}); \ No newline at end of file diff --git a/assets/js/opalestate.js b/assets/js/opalestate.js new file mode 100755 index 00000000..843e68f8 --- /dev/null +++ b/assets/js/opalestate.js @@ -0,0 +1,573 @@ +jQuery( document ).ready( function ( $ ) { + + /** + * + */ + $( '#show-user-sidebar-btn' ).click( function () { + $( 'body' ).toggleClass( 'active' ); + } ); + + $( '.more-options-label, .form-item--types .group-item, .cmb2-checkbox-list.cmb2-list li' ).each( function () { + $( this ).append( '' ); + } ); + + $( '.opalestate-tooltip' ).each( function () { + if ( $( this ).tooltipster ) { + $( this ).tooltipster( { + side: [ 'bottom', 'top', 'right', 'left' ] + } ); + } + } ); + + /***/ + + // Social login. + $( '.js-opal-google-login' ).on( 'click', function ( e ) { + e.preventDefault(); + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + data: { + 'action': 'opalestate_ajax_redirect_google_login_link' + }, + success: function ( results ) { + window.location.href = results.data; + }, + error: function ( errorThrown ) { + // TODO: + } + } ); + } ); + + $( '.js-opal-facebook-login' ).on( 'click', function ( e ) { + e.preventDefault(); + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + data: { + 'action': 'opalestate_ajax_redirect_facebook_login_link' + }, + success: function ( results ) { + window.location.href = results.data; + }, + error: function ( errorThrown ) { + // TODO: + } + } ); + } ); + + if ( $( '.opalestate-swiper-play' ).length > 0 ) { + var play_swiper_sliders = function () { + if ( $( '.opalestate-swiper-play' ).length > 0 ) { + $( '.opalestate-swiper-play' ).each( function () { + var option = $( this ).data( 'swiper' ); + + if ( option ) { + option = $.extend( { + navigation: { + nextEl: '.swiper-button-next', + prevEl: '.swiper-button-prev' + }, + slidesPerView: 3, + spaceBetween: 30, + loop: true, + pagination: { + el: '.swiper-pagination', + clickable: true, + }, + breakpoints: { + 1024: { + slidesPerView: 2, + spaceBetween: 30 + }, + 768: { + slidesPerView: 1, + spaceBetween: 10 + }, + 640: { + slidesPerView: 1, + spaceBetween: 10 + }, + 320: { + slidesPerView: 1, + spaceBetween: 10 + } + } + }, option ); + + if ( option.thumbnails_nav ) { + var ioption = $( option.thumbnails_nav ).data( 'swiper' ); + + ioption.breakpoint = { + 1024: { + slidesPerView: 2, + spaceBetween: 30 + }, + 768: { + slidesPerView: 1, + spaceBetween: 10 + }, + 640: { + slidesPerView: 1, + spaceBetween: 10 + }, + 320: { + slidesPerView: 1, + spaceBetween: 10 + } + }; + + var iswiper = new Swiper( option.thumbnails_nav, ioption ); + + option.thumbs = { + swiper: iswiper + }; + + } + + var swiper = new Swiper( this, option ); + } + } ); + } + }; + play_swiper_sliders(); + $( document ).ajaxComplete( function () { + play_swiper_sliders(); + } ); + } + + //////// + $( '.opalestate-scroll-elements a' ).on( 'click', function ( e ) { + e.preventDefault(); + if ( $( $( this ).attr( 'href' ) ).length ) { + $( '.opalestate-scroll-elements a' ).removeClass( 'active' ); + $( this ).addClass( 'active' ); + + $( 'html, body' ).animate( { + scrollTop: $( $( this ).attr( 'href' ) ).offset().top - 80, + }, + 500, + 'linear' + ); + } + } ); + var header = $( '.keep-top-bars' ); + $( window ).scroll( function () { + var scroll = $( window ).scrollTop(); + if ( scroll >= window.innerHeight ) { + header.addClass( 'floating-keep-top' ); + } else { + header.removeClass( 'floating-keep-top' ); + } + } ); + + //// + + //// + $( '.opalestate-gallery' ).each( function () { // the containers for all your galleries + $( this ).magnificPopup( { + delegate: 'a', // the selector for gallery item + type: 'image', + gallery: { + enabled: true + } + } ); + var $_this = this; + $( '.show-first-photo' ).click( function () { + $( 'a', $_this ).first().click(); + } ); + $( '.show-last-photo' ).click( function () { + $( 'a', $_this ).last().click(); + } ); + } ); + + ////// + $( '.opalestate_rating' ).each( function () { + $( this ) + .hide() + .before( + '

            \ + \ + 1\ + 2\ + 3\ + 4\ + 5\ + \ +

            ' + ); + } ); + + $( 'body' ) + // Star ratings for comments + .on( 'click', '.comment-form-rating p.opalestate-stars a', function () { + var $star = $( this ), + $rating = $( this ).closest( '.comment-form-rating' ).find( '.opalestate_rating' ), + $container = $( this ).closest( '.stars' ); + + $rating.val( $star.text() ); + $star.siblings( 'a' ).removeClass( 'active' ); + $star.addClass( 'active' ); + $container.addClass( 'selected' ); + + return false; + } ) + .on( 'click', '#respond #submit', function () { + var $rating = $( this ).closest( '#respond' ).find( '.opalestate_rating' ); + var rating = $rating.val(); + + if ( $rating.length > 0 && !rating ) { + window.alert( 'Require rating!' ); + + return false; + } + } ); + + // sticky //// + $( '.opalestate-sticky-column' ).stick_in_parent(); + + //// + $( '.input-group-number' ).each( function () { + var _input = $( 'input', this ); + if ( parseInt( _input.val() ) <= 0 ) { + _input.val( 1 ); + } + $( '.btn-actions > span', this ).click( function () { + + var _check = function () { + return parseInt( _input.val() ) <= 0 ? 1 : parseInt( _input.val() ); + }; + + if ( $( this ).hasClass( 'btn-plus' ) ) { + _val = _check() + 1; + } else { + _val = _check() - 1; + } + + _input.val( _val ); + _input.change(); + } ); + + } ); + + $( 'select.form-control , .cmb2-wrap select, .form-row select' ).select2( { + width: '100%', + minimumResultsForSearch: -1 + } ); + + function opalCollapse() { + $( '.opal-collapse-button' ).on( 'click', function () { + var $el = $( this ), + data = $el.data( 'collapse' ), + $el_data = $( data ), + speed = 250; + + if ( $el.data( 'speed' ) && $el.data( 'speed' ) > 0 ) { + speed = $el.data( 'speed' ); + } + + if ( $el_data.is( ':visible' ) ) { + $el_data.slideUp( speed ); + $el.removeClass( 'show' ); + $el_data.removeClass( 'show' ); + } else { + $el.addClass( 'show' ); + $el_data.addClass( 'show' ); + $el_data.slideDown( speed ); + } + + return false; + } ); + } + + opalCollapse(); + + /************************/ + + $( '.opalestate-tab .tab-item' ).click( function ( event ) { + event.preventDefault(); + $( this ).parent().find( ' .tab-item' ).removeClass( 'active' ); + $( this ).addClass( 'active' ); + + $( $( this ).attr( 'href' ) ).parent().children( '.opalestate-tab-content' ).removeClass( 'active' ); + $( $( this ).attr( 'href' ) ).addClass( 'active' ); + } ); + + $( '.opalestate-tab' ).each( function () { + $( this ).find( '.tab-item' ).first().click(); + } ); + + /** + * Click to show body popup + */ + $( 'body' ).delegate( '.opalestate-popup .popup-head', 'click', function () { + var $this = $( this ).parent( '.opalestate-popup' ); + $( '.popup-head', $this ).click( function () { + $( '.opalestate-popup.active' ).removeClass( 'active' ); + $this.toggleClass( 'active' ); + } ); + $( '.popup-close', $this ).click( function () { + $( '.opalestate-popup' ).removeClass( 'active' ); + } ); + } ); + + /** + * Login form + **/ + $( 'body' ).delegate( '.opalestate-mfp-popup form.opalestate-login-form', 'submit', function () { + + var $form = $( this ); + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + dataType: 'json', + data: $( this ).serialize() + '&ajax=1&action=opalestate_login_form', // serializes the form's elements. + success: function ( data ) { + if ( data.status == true ) { + if ( data.redirect ) { + window.location.href = data.redirect; + } + } + if ( data.message ) { + $form.find( '.opalestate-notice' ).remove(); + $form.prepend( data.message ); + } + + } + } ); + return false; + } ); + + /** + * Login form + **/ + $( 'body' ).delegate( '.opalestate-mfp-popup form.opalestate-register-form', 'submit', function () { + + var $form = $( this ); + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + dataType: 'json', + data: $( this ).serialize() + '&ajax=1&action=opalestate_register_form', // serializes the form's elements. + success: function ( data ) { + if ( data.status == true ) { + if ( data.redirect ) { + window.location.href = data.redirect; + } + } + if ( data.message ) { + $form.find( '.opalestate-notice' ).remove(); + $form.prepend( data.message ); + } + + } + } ); + return false; + } ); + /** + * AJAX ACTION + */ + + $( '#opalestate_user_frontchangepass' ).submit( function ( e ) { + var $this = $( this ); + $( '.alert', $this ).remove(); + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + dataType: 'json', + data: $( this ).serialize() + '&action=opalestate_save_changepass', // serializes the form's elements. + success: function ( data ) { + if ( data.status == false ) { + $this.find( '.form-table' ) + .prepend( $( '

            ' + data.message + '

            ' ) ); + } else { + $this.find( '.form-table' ).prepend( $( '

            ' + data.message + '

            ' ) ); + $( 'input[type="text"]', $this ).val( '' ); + setTimeout( function () { + $( '.alert', $this ).remove(); + }, 1000 ); + } + } + } ); + + e.preventDefault(); // avoid to execute the actual submit of the form. + } ); + + $( 'body' ).delegate( '.opalestate-popup-button', 'click', function () { + var $target = $( this ).data( 'target' ); + $.magnificPopup.open( { + items: { + src: $target + } + } ); + return false; + } ); + + // open login form + $( document ).on( 'opalestate:login', function () { + if ( $( '#opalestate-user-form-popup' ) ) { + $.magnificPopup.open( { + items: { + src: '#opalestate-user-form-popup' + }, + mainClass: 'mfp-with-zoom', // this class is for CSS animation below + zoom: { + enabled: true + } + } ); + } + } ); + + $( 'body' ).delegate( '.opalestate-need-login', 'click', function () { + $( document ).trigger( 'opalestate:login', [ true ] ); + return false; + } ); + //// ajax favorite + $( 'body' ).delegate( '.property-toggle-favorite', 'click', function () { + var $this = $( this ); + if ( $( this ).hasClass( 'opalestate-need-login' ) ) { + return; + } + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + data: 'property_id=' + $( this ).data( 'property-id' ) + '&action=opalestate_toggle_status', // serializes + // the form's + // elements. + success: function ( data ) { + if ( data ) { + $this.replaceWith( $( data ) ); + } + } + } ); + } ); + + if ( $( '.opalestate-datepicker' ).length > 0 ) { + $( '.opalestate-datepicker' ).datepicker( { minDate: 0 } ); + } + // + + /** + * + */ + $( '.list-property-status li' ).click( function () { + $( '.opalestate-search-form [name=status]' ).val( $( this ).data( 'id' ) ); + $( '.list-property-status li' ).removeClass( 'active' ); + $( this ).addClass( 'active' ); + } ); + if ( $( '.opalestate-search-form [name=status]' ).val() > 0 ) { + var id = $( '.opalestate-search-form [name=status]' ).val(); + $( '.list-property-status li' ).removeClass( 'active' ); + $( '.list-property-status [data-id=' + id + ']' ).addClass( 'active' ); + } + + /*-----------------------------------------------------------------------------------*/ + $( '.opal-slide-ranger' ).each( function () { + var _this = this; + var unit = $( this ).data( 'unit' ); + var decimals = $( this ).data( 'decimals' ); + var min = $( '.slide-ranger-bar', this ).data( 'min' ); + var max = $( '.slide-ranger-bar', this ).data( 'max' ); + var mode = $( '.slide-ranger-bar', this ).data( 'mode' ); + var start = $( '.slide-ranger-bar', this ).data( 'start' ); + + var imin = $( '.slide-ranger-min-input', this ).val(); + var imax = $( '.slide-ranger-max-input', this ).val(); + var slider = $( '.slide-ranger-bar', this ).get( 0 ); + var unit_pos = $( this ).data( 'unitpos' ); + + var config_format = { + decimals: decimals, + thousand: ',', + }; + + if ( unit_pos == 'prefix' ) { + config_format.prefix = ' ' + unit + ' '; + } else { + config_format.postfix = ' ' + unit + ' '; + } + + var nummm = wNumb( config_format ); + var istart = [ imin, imax ]; + if ( mode && mode == 1 && start ) { + istart = [ start ]; + } + + noUiSlider.create( slider, { + range: { + 'min': [ min ], + 'max': [ max ] + }, + connect: true, + start: istart, + format: nummm, + direction: opalesateJS.rtl == 'true' ? 'rtl' : 'ltr', + + } ); + slider.noUiSlider.on( 'update', function ( values, handle ) { + var val = values[ handle ]; + if ( handle == 0 ) { + $( '.slide-ranger-min-label', _this ).text( val ); + $( '.slide-ranger-min-input', _this ).val( nummm.from( val ) ); + } else { + $( '.slide-ranger-max-label', _this ).text( val ); + $( '.slide-ranger-max-input', _this ).val( nummm.from( val ) ); + } + } ); + + slider.noUiSlider.on( 'end', function ( values, handle ) { + var val = values[ handle ]; + if ( handle == 0 ) { + $( '.slide-ranger-min-input', _this ).change(); + } else { + $( '.slide-ranger-max-input', _this ).change(); + } + } ); + + } ); + + //////***Search Search **/ + $( 'body' ).delegate( '#opalestate-save-search-form', 'submit', function () { + var params = window.location.search.substring( 1 ); + $.ajax( { + type: 'POST', + dataType: 'json', + url: opalesateJS.ajaxurl, + data: 'params=' + encodeURIComponent( params ) + '&' + $( this ).serialize() + + '&action=opalestate_ajx_save_search', + success: function ( data ) { + $( '#opalestate-save-search-form .alert' ).remove(); + $( '#opalestate-save-search-form input' ).val( '' ); + $( '#opalestate-save-search-form' ) + .append( '
            ' + + data.message + '
            ' ); + $( '#opalestate-save-search-form .alert' ).delay( 5000 ).queue( function () { + $( '#opalestate-save-search-form .alert' ).remove(); + } ); + } + } ); + return false; + } ); + + $( '.ajax-load-properties' ).delegate( '.pagination li', 'click', function () { + var $content = $( this ).parents( '.ajax-load-properties' ); + $.ajax( { + type: 'POST', + url: opalesateJS.ajaxurl, + data: location.search.substr( 1 ) + '&action=get_agent_property&paged=' + $( this ).data( 'paged' ) + + '&id=' + $content.data( 'id' ), + success: function ( data ) { + if ( data ) { + $content.html( data ); + } + } + } ); + return false; + } ); + + if ( $( '.opalestate-sticky' ).length > 0 ) { + $( '.opalestate-sticky' ).each( function () { + $( this ).stick_in_parent( $( this ).data() ); + } ); + } +} ); diff --git a/assets/map/apartment-icon.png b/assets/map/apartment-icon.png new file mode 100755 index 00000000..ffb825e9 Binary files /dev/null and b/assets/map/apartment-icon.png differ diff --git a/assets/map/close.png b/assets/map/close.png new file mode 100644 index 00000000..49404934 Binary files /dev/null and b/assets/map/close.png differ diff --git a/assets/map/cluster-icon.png b/assets/map/cluster-icon.png new file mode 100755 index 00000000..968bb0e7 Binary files /dev/null and b/assets/map/cluster-icon.png differ diff --git a/assets/map/hospital.png b/assets/map/hospital.png new file mode 100755 index 00000000..da7b50eb Binary files /dev/null and b/assets/map/hospital.png differ diff --git a/assets/map/libraries.png b/assets/map/libraries.png new file mode 100755 index 00000000..1f8d6d08 Binary files /dev/null and b/assets/map/libraries.png differ diff --git a/assets/map/market_icon.png b/assets/map/market_icon.png new file mode 100755 index 00000000..0db34bdf Binary files /dev/null and b/assets/map/market_icon.png differ diff --git a/assets/map/pharmacy.png b/assets/map/pharmacy.png new file mode 100755 index 00000000..086e8cc6 Binary files /dev/null and b/assets/map/pharmacy.png differ diff --git a/assets/map/school.png b/assets/map/school.png new file mode 100755 index 00000000..b955cbfd Binary files /dev/null and b/assets/map/school.png differ diff --git a/assets/map/supermarket.png b/assets/map/supermarket.png new file mode 100755 index 00000000..5d2a4ded Binary files /dev/null and b/assets/map/supermarket.png differ diff --git a/assets/map/transportation.png b/assets/map/transportation.png new file mode 100755 index 00000000..35b0d9a5 Binary files /dev/null and b/assets/map/transportation.png differ diff --git a/assets/mortgage.css b/assets/mortgage.css new file mode 100755 index 00000000..65917a3a --- /dev/null +++ b/assets/mortgage.css @@ -0,0 +1,105 @@ +.opalestate-mortgage-label { + width: 100%; + font-weight: 500; +} + +.opalestate-mortgage-chart-container { + overflow: hidden; +} + +.opalestate-mortgage-chart-container:after { + content: ""; + display: block; + clear: both; +} + +.opalestate-mortgage-chart-label { + font-size: 18px; +} + +.opalestate-mortgage-chart-container { + margin-bottom: 15px; +} + +.opalestate-mortgage-chart { + float: left; + width: 50%; +} + +.opalestate-mortgage-chart-svg { + margin-bottom: 15px; + position: relative; +} + +.opalestate-mortgage-chart-desc { + float: left; + width: 50%; +} + +.opalestate-mortgage-chart-notice ul { + padding: 0; + margin: 0; +} + +.opalestate-mortgage-chart-notice ul li { + font-size: 12px; + line-height: normal; + position: relative; + margin-bottom: 6px; + padding-left: 20px; + list-style: none; +} + +.opalestate-mortgage-chart-notice ul li span { + position: absolute; + top: 3px; + left: 0; + width: 8px; + height: 8px; + border-radius: 50%; + color: #7e7e7e; + font-weight: 400; +} + +.opalestate-mortgage-output { + font-size: 18px; + font-weight: 500; + color: #0a1938; +} + +.opalestate-mortgage-output-item { + margin-bottom: 6px; +} +.opalestate-monthly-value{ + color: #2f73e9; +} +.opalestate-mortgage-output label { + display: block; + font-size: 18px; + margin-bottom: 4px; + line-height: 1; +} + +.opalestate-mortgage-output small { + font-size: 15px; + text-transform: capitalize; +} + +.pie { + width: 120px; + background: #f06; + border-radius: 50%; +} + +.pie circle { + fill: none; + stroke: #02ce76; + stroke-width: 32; + animation: rotate 1.5s ease-in; +} + +@keyframes rotate { + to { + x + } +} diff --git a/assets/opalestate.css b/assets/opalestate.css new file mode 100755 index 00000000..22c41269 --- /dev/null +++ b/assets/opalestate.css @@ -0,0 +1,4598 @@ +/* +Theme Name: FullHouse +Theme URI: http://demovenustheme.com/wordpress/opalestate/ +Author: Opal Team +Author URI: https://wordpress.org/ +Description: In 2019, our default theme lets you create a responsive magazine website with a sleek, modern design. Feature your favorite homepage content in either a grid or a slider. Use the three widget areas to customize your website, and change your content's layout with a full-width page template and a contributor page to show off your authors. Creating a magazine website with WordPress has never been easier. +Version: 1.0 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Tags: black, green, white, light, dark, two-columns, three-columns, left-sidebar, right-sidebar, fixed-layout, responsive-layout, custom-background, custom-header, custom-menu, editor-style, featured-images, flexible-header, full-width-template, microformats, post-formats, rtl-language-support, sticky-post, theme-options, translation-ready, accessibility-ready +Text Domain: opalestate + +This theme, like WordPress, is licensed under the GPL. +Use it to make something cool, have fun, and share what you've learned with others. +*/ +@media (min-width: 768px) { + .opal-row, .row { + margin-left: -15px; + margin-right: -15px; + } + .opal-row .col-sm-1, .opal-row .col-sm-2, .opal-row .col-sm-3, .opal-row .col-sm-4, .opal-row .col-sm-5, .opal-row .col-sm-6, .opal-row .col-sm-7, .opal-row .col-sm-8, .opal-row .col-sm-9, .opal-row .col-sm-10, .opal-row .col-sm-11, .opal-row .col-sm-12, .row .col-sm-1, .row .col-sm-2, .row .col-sm-3, .row .col-sm-4, .row .col-sm-5, .row .col-sm-6, .row .col-sm-7, .row .col-sm-8, .row .col-sm-9, .row .col-sm-10, .row .col-sm-11, .row .col-sm-12 { + float: left; + } + .opal-row .col-sm-1, .row .col-sm-1 { + width: 8.33333%; + } + .opal-row .col-sm-2, .row .col-sm-2 { + width: 16.66667%; + } + .opal-row .col-sm-3, .row .col-sm-3 { + width: 25%; + } + .opal-row .col-sm-4, .row .col-sm-4 { + width: 33.33333%; + } + .opal-row .col-sm-5, .row .col-sm-5 { + width: 41.66667%; + } + .opal-row .col-sm-6, .row .col-sm-6 { + width: 50%; + } + .opal-row .col-sm-7, .row .col-sm-7 { + width: 58.33333%; + } + .opal-row .col-sm-8, .row .col-sm-8 { + width: 66.66667%; + } + .opal-row .col-sm-9, .row .col-sm-9 { + width: 75%; + } + .opal-row .col-sm-10, .row .col-sm-10 { + width: 83.33333%; + } + .opal-row .col-sm-11, .row .col-sm-11 { + width: 91.66667%; + } + .opal-row .col-sm-12, .row .col-sm-12 { + width: 100%; + } + .opal-row .col-sm-1, .opal-row .col-sm-2, .opal-row .col-sm-3, .opal-row .col-sm-4, .opal-row .col-sm-5, .opal-row .col-sm-6, .opal-row .col-sm-7, .opal-row .col-sm-8, .opal-row .col-sm-9, .opal-row .col-sm-10, .opal-row .col-sm-11, .opal-row .col-sm-12, .row .col-sm-1, .row .col-sm-2, .row .col-sm-3, .row .col-sm-4, .row .col-sm-5, .row .col-sm-6, .row .col-sm-7, .row .col-sm-8, .row .col-sm-9, .row .col-sm-10, .row .col-sm-11, .row .col-sm-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; + } + .opal-row:before, .opal-row:after, .row:before, .row:after { + content: " "; + display: table; + } + .opal-row:after, .row:after { + clear: both; + } +} +@media (min-width: 992px) { + .opal-row .col-md-1, .opal-row .col-md-2, .opal-row .col-md-3, .opal-row .col-md-4, .opal-row .col-md-5, .opal-row .col-md-6, .opal-row .col-md-7, .opal-row .col-md-8, .opal-row .col-md-9, .opal-row .col-md-10, .opal-row .col-md-11, .opal-row .col-md-12, .row .col-md-1, .row .col-md-2, .row .col-md-3, .row .col-md-4, .row .col-md-5, .row .col-md-6, .row .col-md-7, .row .col-md-8, .row .col-md-9, .row .col-md-10, .row .col-md-11, .row .col-md-12 { + float: left; + } + .opal-row .col-md-1, .row .col-md-1 { + width: 8.33333%; + } + .opal-row .col-md-2, .row .col-md-2 { + width: 16.66667%; + } + .opal-row .col-md-3, .row .col-md-3 { + width: 25%; + } + .opal-row .col-md-4, .row .col-md-4 { + width: 33.33333%; + } + .opal-row .col-md-5, .row .col-md-5 { + width: 41.66667%; + } + .opal-row .col-md-6, .row .col-md-6 { + width: 50%; + } + .opal-row .col-md-7, .row .col-md-7 { + width: 58.33333%; + } + .opal-row .col-md-8, .row .col-md-8 { + width: 66.66667%; + } + .opal-row .col-md-9, .row .col-md-9 { + width: 75%; + } + .opal-row .col-md-10, .row .col-md-10 { + width: 83.33333%; + } + .opal-row .col-md-11, .row .col-md-11 { + width: 91.66667%; + } + .opal-row .col-md-12, .row .col-md-12 { + width: 100%; + } + .opal-row .col-md-1, .opal-row .col-md-2, .opal-row .col-md-3, .opal-row .col-md-4, .opal-row .col-md-5, .opal-row .col-md-6, .opal-row .col-md-7, .opal-row .col-md-8, .opal-row .col-md-9, .opal-row .col-md-10, .opal-row .col-md-11, .opal-row .col-md-12, .row .col-md-1, .row .col-md-2, .row .col-md-3, .row .col-md-4, .row .col-md-5, .row .col-md-6, .row .col-md-7, .row .col-md-8, .row .col-md-9, .row .col-md-10, .row .col-md-11, .row .col-md-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; + } +} +@media (min-width: 1200px) { + .opal-row .col-lg-1, .opal-row .col-lg-2, .opal-row .col-lg-3, .opal-row .col-lg-4, .opal-row .col-lg-5, .opal-row .col-lg-6, .opal-row .col-lg-7, .opal-row .col-lg-8, .opal-row .col-lg-9, .opal-row .col-lg-10, .opal-row .col-lg-11, .opal-row .col-lg-12, .row .col-lg-1, .row .col-lg-2, .row .col-lg-3, .row .col-lg-4, .row .col-lg-5, .row .col-lg-6, .row .col-lg-7, .row .col-lg-8, .row .col-lg-9, .row .col-lg-10, .row .col-lg-11, .row .col-lg-12 { + float: left; + } + .opal-row .col-lg-1, .row .col-lg-1 { + width: 8.33333%; + } + .opal-row .col-lg-2, .row .col-lg-2 { + width: 16.66667%; + } + .opal-row .col-lg-3, .row .col-lg-3 { + width: 25%; + } + .opal-row .col-lg-4, .row .col-lg-4 { + width: 33.33333%; + } + .opal-row .col-lg-5, .row .col-lg-5 { + width: 41.66667%; + } + .opal-row .col-lg-6, .row .col-lg-6 { + width: 50%; + } + .opal-row .col-lg-7, .row .col-lg-7 { + width: 58.33333%; + } + .opal-row .col-lg-8, .row .col-lg-8 { + width: 66.66667%; + } + .opal-row .col-lg-9, .row .col-lg-9 { + width: 75%; + } + .opal-row .col-lg-10, .row .col-lg-10 { + width: 83.33333%; + } + .opal-row .col-lg-11, .row .col-lg-11 { + width: 91.66667%; + } + .opal-row .col-lg-12, .row .col-lg-12 { + width: 100%; + } + .opal-row .col-lg-1, .opal-row .col-lg-2, .opal-row .col-lg-3, .opal-row .col-lg-4, .opal-row .col-lg-5, .opal-row .col-lg-6, .opal-row .col-lg-7, .opal-row .col-lg-8, .opal-row .col-lg-9, .opal-row .col-lg-10, .opal-row .col-lg-11, .opal-row .col-lg-12, .row .col-lg-1, .row .col-lg-2, .row .col-lg-3, .row .col-lg-4, .row .col-lg-5, .row .col-lg-6, .row .col-lg-7, .row .col-lg-8, .row .col-lg-9, .row .col-lg-10, .row .col-lg-11, .row .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; + } +} + +/* + * Global variables + */ +/* main color which will be used for all main block styles... */ +/** + * Import component variables + */ +/** elements mixins **/ +/** +* Transition-timing-function property@mixin +*/ +/*background RGBA +============================================*/ +/*inline-block +============================================*/ +/****/ +/****/ +/****/ +/** elements mixins **/ +/** +* Transition-timing-function property@mixin +*/ +/*background RGBA +============================================*/ +/*inline-block +============================================*/ +/****/ +/****/ +/** list **/ +.property-date { + display: inline-block; +} + +.entry-summary-tabs { + margin-top: 62px; +} + +.property-meta { + flex-basis: 100%; +} + +.property-types-list, +.property-categories-list { + display: inline-block; + margin-right: 5px; +} + +.property-address { + display: inline-block; + margin-top: 12px; + margin-right: 15px; +} +.property-address .property-view-map i { + color: #7e7e7e; +} +.property-address .property-view-map a { + margin-right: 4px; +} + +.box-inner-summary { + padding: 30px; +} +@media screen and (max-width: 767px) { + .box-inner-summary { + padding: 30px 0; + } +} + +.opalestate-box { + padding-bottom: 30px; +} +@media screen and (min-width: 768px) { + .opalestate-box { + padding: 30px; + border: 1px solid #ebebeb; + } +} +.opalestate-box .opalestate_property:last-of-type { + margin-bottom: 0; +} + +.opalestate-sidebar-box { + margin-bottom: 30px; +} +@media screen and (min-width: 768px) { + .opalestate-sidebar-box { + padding: 30px; + border: 1px solid #ebebeb; + } +} +@media screen and (max-width: 768px) { + .opalestate-sidebar-box { + margin-top: 30px; + } +} + +.property-information ul.list-info { + padding: 0; + margin-bottom: 0; +} +.property-information ul.list-info li { + list-style: none; +} +.property-information ul.list-info li h6 { + margin-bottom: 0; + flex: 1; + color: #7e7e7e; +} +.property-information ul.list-info li a { + color: inherit; +} +.property-information ul.list-info li:not(:last-child) div[class*="property-label-"] { + border-bottom: 1px solid #ebebeb; +} +.property-information ul.list-info div[class*="property-label-"] { + padding: 4px 0; + overflow: hidden; + display: flex; + align-items: center; +} +.property-information ul.list-info div[class*="property-label-"] h6 { + line-height: 1; +} +.property-information ul.list-info div[class*="property-label-"] i { + width: 15px; + margin-right: 15px; +} + +.property-amenities .list-group-item-text, .property-facilities .list-group-item-text { + line-height: 23px; + margin-top: 21px; +} +.property-amenities .list-group-item-text i, .property-facilities .list-group-item-text i { + margin-right: 2px; +} +.property-amenities .list-group-item-text div[class*="col-"], .property-facilities .list-group-item-text div[class*="col-"] { + line-height: 40px; +} +.property-amenities .list-group-item-text div.active i, .property-facilities .list-group-item-text div.active i { + color: #02ce76; +} + +.property-amenities img { + width: 15px; + margin-right: 5px; +} + +.property-attachments i { + font-size: 36px; + margin-right: 15px; + float: left; +} +.property-attachments a { + vertical-align: top; + line-height: 1; + display: block; + text-transform: capitalize; + padding-bottom: 5px; +} +.property-attachments .list-group-item-text { + margin-top: 36px; +} + +.google-map-tabs { + position: relative; +} +.google-map-tabs .opalestate-tab-head { + margin: 0; + background: transparent; +} +.google-map-tabs .tab-item { + border: none; + padding: 5px 10px; + margin-right: 10px; + color: #FFF; + background-color: #02ce76; + font-weight: 400; +} +.google-map-tabs .tab-item.active, .google-map-tabs .tab-item:hover { + background-color: #2f73e9; + color: #FFF; +} +.google-map-tabs .opalestate-tab-wrap { + position: absolute; + top: 10px; + right: 50px; + z-index: 2; +} + +#property-search-places { + bottom: 25px; + left: 10px; + position: absolute; + z-index: 1; +} +#property-search-places .btn-map-search { + cursor: pointer; + background-color: #FFF; + text-align: center; + width: 40px; + height: 40px; + position: relative; +} +#property-search-places .btn-map-search i { + display: block; + line-height: 40px; +} +#property-search-places .btn-map-search i.fa-hospital-o { + color: #b3e180; +} +#property-search-places .btn-map-search i.fa-plus-square { + color: #ec8f73; +} +#property-search-places .btn-map-search i.fa-graduation-cap { + color: #8fbfe4; +} +#property-search-places .btn-map-search i.fa-shopping-basket { + color: #9d4cfa; +} +#property-search-places .btn-map-search i.fa-subway { + color: #fabd47; +} +#property-search-places .btn-map-search i.fa-bank { + color: #6eadfb; +} +#property-search-places .btn-map-search em { + background: #2f73e9; + margin-left: 10px; + font-size: 10px; + color: #FFF; + padding: 1px 3px; +} +#property-search-places .btn-map-search span { + width: 0; + display: block; + visibility: hidden; + -webkit-transition: 0.35s; + -o-transition: 0.35s; + transition: 0.35s; + position: absolute; + left: 50%; + top: 0; + background-color: #FFF; + line-height: 40px; + padding: 0 10px; + z-index: -1; + opacity: 0; + filter: alpha(opacity=0); + font-size: 12px; +} +#property-search-places .btn-map-search:hover span, #property-search-places .btn-map-search.active span { + visibility: visible; + width: 200px; + left: 100%; + z-index: 1; + opacity: 1; + filter: alpha(opacity=100); +} + +@media screen and (min-width: 992px) { + .agent-sidebar { + margin-top: -286px; + } +} + +.single-agent { + margin-top: 30px; +} + +.agent-address-map { + border-top: none; +} + +.agency-preview { + display: none; +} + +@media screen and (max-width: 1024px) { + .property-agency-contact { + margin-top: 30px; + } +} +.property-agency-contact p { + margin-bottom: 0; +} +.property-agency-contact .entry-title { + margin-bottom: 6px; +} +.property-agency-contact .opalestate-social-icons { + margin: 0 0 0 15px; +} +.property-agency-contact .opalestate-social-icons [class^="opalestate-social-"] { + margin: 4px 0 0; +} +.property-agency-contact .agency-top-meta { + display: flex; + flex-wrap: wrap; + padding-bottom: 12px; + margin-bottom: 20px; + position: relative; +} +.property-agency-contact .agency-top-meta::before, .property-agency-contact .agency-excerpt::before { + content: ""; + width: calc( 100% + 30px); + height: 1px; + background-color: #ebebeb; + bottom: 0; + position: absolute; + right: -30px; +} +@media screen and (max-width: 1024px) { + .property-agency-contact .agency-top-meta::before, .property-agency-contact .agency-excerpt::before { + width: 100%; + left: 0; + right: auto; + } +} +.property-agency-contact .agency-top-info { + flex: 1; +} +.property-agency-contact .agency-excerpt { + padding-bottom: 20px; + margin-bottom: 13px; + position: relative; +} + +/** + * Single property + */ +.opalestate-box-content { + margin: 30px 0 0; +} +@media screen and (min-width: 768px) { + .opalestate-box-content { + margin: 60px 0 0; + } +} + +.opalestate-rows .opal-row { + display: flex; + flex-flow: wrap; +} + +.outbox-title { + margin-bottom: 15px; + display: inline-block; + line-height: 1; +} + +.property-single-info { + display: flex; + flex-wrap: wrap; + align-items: flex-end; + justify-content: space-between; + margin-top: 40px; + margin-bottom: 50px; +} + +.group-items { + display: flex; + align-items: center; + flex-wrap: wrap; +} +@media screen and (min-width: 768px) { + .group-items { + flex: 1; + } +} +.group-items .entry-title { + margin-bottom: 0; +} +.group-items .property-status { + position: relative; + display: flex; + top: 0; + left: 0; +} +.group-items .property-status li { + line-height: 14px; +} +.group-items .property-status span { + margin-bottom: 0; +} + +.swiper-container [class*="swiper-button-"] { + display: block; + color: #02ce76; + width: 62px; + height: 62px; + text-align: center; + background-color: rgba(255, 255, 255, 0.8); + transition: all .5s ease-in-out; + background-size: 10px 20px; + opacity: 0; +} +.swiper-container [class*="swiper-button-"]:hover { + background-color: #FFF; +} +.swiper-container .swiper-button-next { + right: -62px; +} +.swiper-container .swiper-button-prev { + left: -62px; +} +.swiper-container:hover [class*="swiper-button-"] { + opacity: 1; +} +.swiper-container:hover .swiper-button-next { + right: 20px; +} +.swiper-container:hover .swiper-button-prev { + left: 20px; +} + +.swiper-pagination { + display: none !important; +} + +.opalestate-single-property.opalestate_property { + border: none; +} +.opalestate-single-property .owl-thumb-wrapper { + padding-top: 10px; +} +.opalestate-single-property .owl-thumb-wrapper .owl-item:not(:last-of-type) { + padding-right: 10px; +} +@media screen and (min-width: 768px) { + .opalestate-single-property .entry-summary { + border: 1px solid #ebebeb; + padding-bottom: 40px; + } +} +.opalestate-single-property .property-meta-list { + border-bottom: 1px solid #ebebeb; + padding: 30px 30px 0; +} +@media screen and (max-width: 767px) { + .opalestate-single-property .property-meta-list { + padding: 30px 0 0; + border: none; + } +} +.opalestate-single-property .property-meta-list i { + color: #02ce76; +} +.opalestate-single-property .property-meta-list li:not(:last-child) { + margin-right: 30px; +} +@media screen and (min-width: 768px) { + .opalestate-single-property .entry-content { + padding: 30px 30px 0; + } +} +.opalestate-single-property .box-heading { + line-height: 1; + margin-bottom: 16px; +} + +.opalestate-single-property--print .table-responsive table tr td:last-child, .opalestate-single-property--print .table-responsive table tr th:last-child { + display: none; +} +.opalestate-single-property--print .opalestate-tab-head { + display: none; +} +.opalestate-single-property--print .opalestate-tab-content, .opalestate-single-property--print .plan-name { + display: block; +} + +.opalestate-single-property--version-2 .entry-summary { + border: none; + padding-bottom: 0; +} +.opalestate-single-property--version-2 .single-property-sidebar .opalestate-box-content:first-of-type { + margin-top: 0; +} + +.opalestate-tab-content .opalestate-box-content:first-of-type { + margin-top: 28px; +} + +@media screen and (min-width: 768px) { + .property-tab-content { + border: 1px solid #ebebeb; + } +} + +.opalestate-single-property--version-3 .property-single-info { + margin-bottom: 0; + display: block; +} +.opalestate-single-property--version-3 .single-price-content .property-price { + text-align: left; + margin-bottom: 7px; +} +.opalestate-single-property--version-3 .single-price-content .property-price span { + display: inline; +} + +.opalestate-single-property--version-5 .property-single-info { + margin-bottom: 0; + display: block; +} +.opalestate-single-property--version-5 .single-price-content .property-price { + text-align: left; + margin-bottom: 7px; +} +.opalestate-single-property--version-5 .single-price-content .property-price span { + display: inline; +} + +.opalestate-yelp-bussines_wrapper:not(:last-of-type) { + margin-bottom: 30px; +} + +.opalestate-yelp-unit { + display: flex; + flex-wrap: wrap; +} +.opalestate-yelp-unit:not(:last-of-type) { + margin-bottom: 30px; +} + +.opalestate-yelp-title { + line-height: 1; + padding-bottom: 20px; + border-bottom: 1px solid #ebebeb; + margin-bottom: 30px; +} + +.opalestate-yelp-icon { + display: none; + width: 15px; + margin-right: 15px; +} + +.opalestate-yelp-category { + display: inline-block; + margin-bottom: 0; + line-height: 1; +} + +.opalestate-yelp-unit__name { + line-height: 1; + margin-bottom: 9px; + margin-right: 15px; +} + +.opalestate-yelp-unit-distance { + display: none; + line-height: 1; + margin: 10px 0; +} + +.opalestate-yelp-unit__info { + flex: 1; +} + +.opalestate-yelp-unit__address { + line-height: 1; +} + +.opalestate-yelp-unit__avatar { + width: 50px; + height: 50px; + margin-right: 20px; +} +.opalestate-yelp-unit__avatar img { + width: 100%; + height: 100%; +} + +.opalestate-yelp-unit__ratings .opalestate-rating__stars { + margin-left: auto; +} +.opalestate-yelp-unit__ratings .opalestate-rating__stars span::before { + color: #d32323; +} + +.walkscores-logo { + float: right; + line-height: 24px; + margin-bottom: 15px; +} + +.walk_details { + display: flex; + align-items: center; + flex-wrap: wrap; +} +.walk_details:not(:last-of-type) { + margin-bottom: 30px; +} + +.text-holder { + flex: 1; +} +.text-holder h6 { + margin-bottom: 0; +} + +.number-holder { + margin-right: 10px; +} + +.scores-label { + margin-bottom: 0; + line-height: 24px; + width: 60px; + height: 60px; + text-align: center; + border-radius: 50%; + border: 2px solid #2f73e9; + color: #2f73e9; +} + +.walk-more-details { + text-transform: capitalize; +} + +.single-price-content .property-price { + padding-top: 17px; +} +.single-price-content .property-price span { + line-height: 1; +} +@media screen and (min-width: 768px) { + .single-price-content .property-price { + text-align: right; + } + .single-price-content .property-price .property-regular-price, .single-price-content .property-price .property-saleprice { + font-size: 36px; + } + .single-price-content .property-price .property-regular-price.has-saleprice { + font-size: 24px; + } + .single-price-content .property-price .property-before-price-label, .single-price-content .property-price .property-price-label { + display: block; + } +} +.single-price-content .property-price .property-price-label { + margin-top: 12px; +} +.single-price-content .property-price .property-before-price-label { + margin-bottom: 12px; +} +.single-price-content .call-to-price { + font-size: 18px; + font-weight: 500; + color: #0a1938; +} + +.property-meta-top { + line-height: 52px; +} +.property-meta-top .property-meta-top__list { + margin-bottom: 0; + align-items: center; +} +.property-meta-top .property-meta-top__list .property-meta-top__button { + width: 52px; + text-align: center; + margin-right: 0; +} +.property-meta-top .list-inline__print span { + display: none; +} +@media screen and (max-width: 767px) { + .property-meta-top .list-inline__sku { + flex-basis: 100%; + } +} +@media screen and (min-width: 768px) { + .property-meta-top { + border-bottom: 1px solid #ebebeb; + padding-left: 30px; + } + .property-meta-top .property-meta-top__list { + justify-content: flex-end; + } + .property-meta-top .property-meta-top__list li:first-child:not(.property-meta-top__button) { + flex: 1; + } + .property-meta-top .property-meta-top__button { + border-left: 1px solid #ebebeb; + } +} + +.property-sku { + font-weight: 500; + color: #0a1938; +} + +.opalestate-reviews { + padding-top: 0; + padding-bottom: 0; +} +.opalestate-reviews .comment-form-comment { + margin-bottom: 10px; +} +.opalestate-reviews #respond { + padding: 0; +} + +.opalestate-rating-percent__item { + display: flex; + flex-wrap: wrap; + margin: 11px 0; +} +.opalestate-rating-percent__item:last-of-type { + margin-bottom: 0; +} +.opalestate-rating-percent__item:first-of-type { + margin-top: 0; +} + +.opalestate-rating-percent__label { + line-height: 1; + margin-right: 15px; + margin-bottom: 0; +} + +.opalestate-process-bar { + display: flex; + height: 5px; + overflow: hidden; + font-size: 13px; + background-color: #eeeeee; + flex: 1; +} + +.opalestate-process-bar__item { + text-align: center; + background-color: #2f73e9; +} + +.opalestate-process-text { + display: block; + line-height: 1; + margin-left: 17px; + width: 34px; +} + +.opalestate-rating-header { + display: flex; + flex-wrap: wrap; + font-size: 13px; + font-weight: 500; + margin-bottom: 58px; +} +@media screen and (min-width: 768px) { + .opalestate-rating-header { + border-bottom: 1px solid #ebebeb; + } +} +.opalestate-rating-header > div { + padding-bottom: 26px; +} +@media screen and (max-width: 767px) { + .opalestate-rating-header > div { + flex-basis: 100%; + padding: 30px 0 0; + border: none; + } +} + +.opalestate-rating-percent { + padding-right: 30px; + flex-basis: 38%; + border-right: 1px solid #ebebeb; + padding-top: 30px; +} + +.opalestate-overall { + padding-left: 30px; + flex-basis: 62%; + padding-top: 25px; +} + +.opalestate-overall__info { + display: flex; + flex-wrap: wrap; + margin-bottom: 21px; +} + +.opalestate-overall__point { + margin-right: 40px; +} +.opalestate-overall__point .point-number { + margin-bottom: 0; + line-height: 1; + color: #2f73e9; +} + +.opalestate-overall__star { + display: flex; + flex-wrap: wrap; + align-items: center; + flex: 1; +} +.opalestate-overall__star .opalestate-overall__heading { + flex-basis: 100%; + margin-bottom: 11px; +} +.opalestate-overall__star .opalestate-rating, .opalestate-overall__star .opalestate-overall__rating-count { + margin-right: 5px; +} + +.opalestate-overall-features { + display: flex; + flex-wrap: wrap; +} + +.opalestate-overall-features__item { + line-height: 1; +} +.opalestate-overall-features__item:not(:last-of-type) { + margin-right: 53px; +} + +.opalestate-overall-features__label { + margin-bottom: 0; + text-transform: uppercase; + margin-bottom: 11px; +} + +.opalestate-overall-features__percent { + color: #0a1938; +} + +.commentlist { + padding: 0; + margin-bottom: 28px; + margin-top: 58px; +} +.commentlist > li { + padding-bottom: 22px; + display: block; +} +.commentlist > li:not(:last-of-type) { + margin-bottom: 30px; + border-bottom: 1px solid #ebebeb; +} + +.opalestate-noreviews { + margin-bottom: 25px; +} + +.comment_container { + display: flex; + flex-wrap: wrap; + align-items: flex-start; +} +.comment_container p { + margin-bottom: 0; +} +.comment_container .avatar { + width: 50px; + border-radius: 50%; + margin-right: 28px; +} +.comment_container .comment-text { + flex: 1; +} +.comment_container .meta { + margin-bottom: 15px; + line-height: 1; +} +.comment_container .opalestate-rating { + display: inline-block; +} + +.opalestate-review__ratings { + margin-bottom: 31px; +} + +.opalestate-review__author { + font-weight: 500; + color: #0a1938; +} + +.comment-form-rating { + display: inline-block; +} +@media screen and (min-width: 480px) { + .comment-form-rating { + width: 33.3333%; + } +} + +.property-360-virtual-session iframe { + width: 100%; + min-height: 500px; + display: block; +} + +.property-video-session iframe { + display: block; + height: auto; +} +@media screen and (min-width: 768px) { + .property-video-session iframe { + width: 100%; + min-height: 400px; + } +} + +/* + * Preview layout + */ +.property-preview-custom-size { + position: relative; + overflow: hidden; + height: 580px; +} +.property-preview-custom-size .property-preview-map, .property-preview-custom-size .opalestate-tab-content, .property-preview-custom-size iframe { + height: 100%; + width: 100%; + border: none; +} + +.property-preview .swiper-pagination-images { + margin-top: 10px; +} + +.property-preview-street-map { + height: 100%; +} + +.property-abs-info { + position: absolute; + padding: 15px; + bottom: 10%; + left: 9%; + background: #FFF; + z-index: 99; +} + +.gallery-metro-preview { + display: flex; + height: 100%; +} +.gallery-metro-preview a { + display: block; + width: 100%; + height: 100%; + background-size: cover; + background-repeat: no-repeat; + background-position: center center; +} +.gallery-metro-preview .no-image { + background-color: #2f73e9; +} +.gallery-metro-preview span { + display: block; + background-color: #000; + width: 100%; + height: 100%; + opacity: 0.7; + filter: alpha(opacity=70); + color: #FFF; + position: relative; +} +.gallery-metro-preview .metro-big { + width: 50%; +} +.gallery-metro-preview .metro-group-small { + width: 50%; + display: flex; + flex-wrap: wrap; +} +.gallery-metro-preview .metro-small { + width: 33%; + height: auto; + text-align: center; +} + +.opalestate-swiper-wrap { + position: relative; +} + +.swiper-slide .thumb-nav { + width: 100%; + height: 100px; + background-size: cover; + background-repeat: no-repeat; + background-position: center center; +} + +.property-mark-pics-preview .property-heading-top { + position: absolute; + bottom: 0; + left: 50%; + transform: translateX(-50%); +} +.property-mark-pics-preview .property-single-info { + margin-bottom: 46px; +} +.property-mark-pics-preview .property-thumbnail { + position: relative; +} +.property-mark-pics-preview .property-thumbnail::before { + content: ""; + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.4); + transition: all .5s ease-in-out; +} +.property-mark-pics-preview .entry-title, .property-mark-pics-preview a, .property-mark-pics-preview .property-single-info, .property-mark-pics-preview .property-price > span:first-child { + color: #FFF; +} + +.property-apartments-session { + padding-top: 6px; +} + +.table-responsive { + overflow-x: auto; + min-height: 0.01%; +} +.table-responsive table { + table-layout: unset; + text-align: center; + margin-bottom: 0; +} +.table-responsive table th { + padding: 14px 3px; + border-style: solid; + border-color: #ebebeb; + border-width: 0 0 1px 0; + font-weight: 500; +} +.table-responsive table td { + border: none; + padding: 12px 3px 10px; +} +.table-responsive table tbody tr:nth-of-type(2n+2) { + background-color: #f8f8f8; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + border: 1px solid #ebebeb; + position: relative; + z-index: 30; + } + .table-responsive table { + width: 730px; + } +} + +.agency-box-top .agency-grid-style .agency-info { + border-bottom: none; +} + +.opalestate_single_agency { + padding-bottom: 30px; +} + +.archive .opalestate-head { + margin-bottom: 80px; +} + +.opalestate-head { + position: relative; + background-color: #02ce76; + display: flex; + align-items: center; + min-height: 640px; +} +.opalestate-head .opalestate-heading { + color: #FFF; + text-align: center; +} +.opalestate-head .opalestate-heading p { + margin-bottom: 50px; +} +.opalestate-head .opalestate-heading a { + color: #FFF; +} +.opalestate-head .opalestate-heading a:hover { + color: #2f73e9; +} +.opalestate-head .opalestate-head-title { + color: #FFF; + margin-bottom: 19px; +} +.opalestate-head .search-agent-title { + display: none; +} +.opalestate-head .opalestate-head-form { + padding: 0 30px; + margin-bottom: 21px; +} + +.opalestate-single-agent { + min-height: 500px; + align-items: flex-end; +} +.opalestate-single-agent .opalestate-heading { + text-align: left; +} +.opalestate-single-agent .opalestate-heading > span { + margin-bottom: 13px; + display: inline-block; +} +.opalestate-single-agent .opalestate-head-title { + margin-bottom: 29px; +} + +.opalesate-archive-top { + margin-bottom: 60px; + padding: 12px 0; + border-style: solid; + border-width: 1px 0 1px; + border-color: #ebebeb; + position: relative; +} +.opalesate-archive-top .opalestate-results { + line-height: 45px; +} +.opalesate-archive-top .opalestate-sortable { + display: inline-block; +} +.opalesate-archive-top .opalestate-sortable .form-control, .opalesate-archive-top .opalestate-sortable .select2-selection--single { + padding-top: 8px; +} + +.opalesate-archive-bottom { + position: relative; +} + +.display-mode { + display: inline-block; +} +.display-mode .btn:not(:disabled):not(.disabled) { + padding: 0; + background-color: transparent; + color: #7e7e7e; + margin-left: 10px; + font-size: 18px; +} +.display-mode .btn:not(:disabled):not(.disabled).active, .display-mode .btn:not(:disabled):not(.disabled):hover { + background-color: transparent; + color: #02ce76; +} + +.page-template-user-management header, .page-template-user-management footer, .page-template-user-management #colophon { + display: none; +} +.page-template-user-management article header { + display: block !important; +} + +.button-actions { + position: absolute; + top: 0; + right: 0; + color: #FFF; + z-index: 1; + display: flex; +} +.button-actions a { + background-color: #2f73e9; + color: #FFF; +} +.button-actions a:hover { + cursor: pointer; + background-color: #02ce76; + color: #FFF; +} + +.my-properties .property-status { + position: relative; + top: 0; + left: 0; +} +.my-properties .property-meta-list { + padding: 0; +} +.my-properties .my-properties-bottom { + display: none; +} +.my-properties .abs-col-item { + padding-top: 10px; +} +.my-properties .entry-title { + margin: 0; +} + +.search-agents-wrap .opalestate-search-agents-form { + padding-bottom: 30px; +} + +.agent-grid-style { + margin-bottom: 30px; + background-color: #FFF; +} +.agent-grid-style .agent-body { + border-style: solid; + border-width: 0 1px 1px 1px; + border-color: #ebebeb; + padding: 30px 30px 15px; +} +.agent-grid-style .agent-job { + line-height: 1; + padding-bottom: 14px; + border-bottom: 1px solid #ebebeb; +} +.agent-grid-style .trusted-label { + position: absolute; + right: 20px; + background-color: #FFF; + border-radius: 50%; + bottom: 0; + transform: translateY(50%); + border: 1px solid #ebebeb; + width: 48px; + line-height: 48px; +} + +.agent-list-style { + padding: 30px; + border: 1px solid #ebebeb; + margin-bottom: 30px; +} +.agent-list-style .team-info { + margin: 15px 0 0; +} + +.maps-container-fixed { + position: relative; + width: 100%; +} +@media (min-width: 1024px) { + .maps-container-fixed { + position: fixed; + z-index: 0; + width: 50%; + top: 0; + min-height: 600px; + } +} + +/** Shortcodes **/ +.opalestate-search-properties .search-properies-form { + margin-top: 30px; +} + +.opalestate-my-account-form { + position: relative; + background: #FFF; + padding: 30px; + width: auto; + max-width: 550px; + margin: 20px auto; +} +.opalestate-my-account-form .submit a { + display: block; + margin-top: 10px; +} +.opalestate-my-account-form .opalestate-button { + padding: 17px 35px 14px 35px; + width: 100%; +} +.opalestate-my-account-form h3 { + display: none; +} + +.opalesate-properties-results { + min-height: 800px; +} + +.membership-packages { + padding-top: 40px; + padding-bottom: 50px; +} + +.pricing.pricing-v3 { + border: 1px solid #ebebeb; + border-radius: 5px; + padding: 0; + margin-bottom: 30px; + overflow: hidden; +} +.pricing.pricing-v3 .pricing-header { + text-align: center; + background: #2f73e9; + color: #FFF; + position: relative; + padding: 15px 0px 0px; +} +.pricing.pricing-v3 .plan-price { + color: #FFF; + line-height: 2.3rem; + margin-top: 15px; +} +.pricing.pricing-v3 .plan-price p { + display: inline-block; +} +.pricing.pricing-v3 .pricing-body { + padding: 15px 30px; +} +.pricing.pricing-v3 .plan-figure { + font-size: 36px; + color: #FFF; + display: block; + font-weight: bold; +} +.pricing.pricing-v3 .plain-info > div { + padding: 10px 0; + font-size: 14px; +} +.pricing.pricing-v3 .plain-info .item-info { + border-bottom: 1px solid #ebebeb; + padding-bottom: 15px; + margin-bottom: 15px; + color: #0a1938; + font-weight: 500; + text-transform: uppercase; +} +.pricing.pricing-v3 .plain-info .item-info:last-child { + margin-bottom: 0; +} +.pricing.pricing-v3 .plain-info i { + margin-right: 10px; +} +.pricing.pricing-v3 .membership-form-wrapper { + color: #FFF; +} +.pricing.pricing-v3 .membership-add-to-purchase { + width: 100%; + border: 0; + text-align: center; + background-color: #999; + line-height: 42px; + text-transform: capitalize; +} +.pricing.pricing-v3 .membership-add-to-purchase:hover { + background-color: gray; +} +.pricing.pricing-v3 .pricing-footer { + padding: 0 30px 30px; + text-align: center; +} +.pricing.pricing-v3 .plan-title { + color: #FFF; + font-size: 18px; + margin: 0; + border: none; + font-weight: 500; + letter-spacing: -0.5px; + position: relative; +} + +.package-hightlighted .plan-subtitle { + background-color: #02ce76; + color: #000; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 2px; + position: absolute; + bottom: -10px; + display: block !important; + margin: 0 auto; + max-width: 150px; + left: 0; + right: 0; + font-weight: 500; +} +.package-hightlighted .pricing.pricing-v3 .membership-add-to-purchase { + background-color: #02ce76; +} +.package-hightlighted .pricing.pricing-v3 .membership-add-to-purchase:hover { + background-color: #2f73e9; +} + +.site-header-account .account-label { + margin-left: 5px; +} +.site-header-account .opalestate-popup .popup-body { + padding: 0; + box-shadow: none; + background-color: transparent; +} +.site-header-account .btn { + margin-bottom: 15px; +} +.site-header-account .opalestate-social-login__buttons a { + padding: 0 10px; +} +.site-header-account .opalestate-social-login__buttons i { + margin-right: 10px; + padding-right: 10px; +} + +.mfp-with-zoom .mfp-container, +.mfp-with-zoom.mfp-bg { + opacity: 0; + -webkit-backface-visibility: hidden; + /* ideally, transition speed should match zoom duration */ + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} + +.mfp-with-zoom .white-popup { + top: 20px; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; +} + +.mfp-with-zoom.mfp-ready .white-popup { + top: 0; +} + +.mfp-with-zoom.mfp-ready .mfp-container { + opacity: 1; +} + +.mfp-with-zoom.mfp-ready.mfp-bg { + opacity: 0.8; +} + +.mfp-with-zoom.mfp-removing .mfp-container, +.mfp-with-zoom.mfp-removing.mfp-bg { + opacity: 0; +} + +.white-popup { + position: relative; + background: #FFF; + padding: 30px; + width: auto; + max-width: 500px; + margin: 20px auto; +} +.white-popup .mfp-close { + top: 15px; +} +.white-popup .submit a { + display: block; + margin-top: 10px; +} +.white-popup .opalestate-button { + padding: 17px 35px 14px 35px; + width: 100%; +} + +.opalestate-social-login__buttons { + list-style: none; + padding: 0; + margin: 0; +} +.opalestate-social-login__buttons a { + display: block; + padding: 0 15px; + color: #FFF; +} +.opalestate-social-login__buttons a:hover { + color: #FFF; +} +.opalestate-social-login__buttons li:not(:last-child) { + margin-bottom: 15px; +} +.opalestate-social-login__buttons i { + margin-right: 15px; + padding: 16px 15px 14px 0; + position: relative; + text-align: center; + width: 35px; +} +.opalestate-social-login__buttons i::after { + content: ""; + position: absolute; + top: 0; + right: 0; + height: 100%; + border-left: 1px solid rgba(0, 0, 0, 0.1); + border-right: 1px solid rgba(255, 255, 255, 0.1); +} + +.opalestate-social-login-facebook-btn { + background-color: #3C5A99; +} + +.opalestate-social-login-google-btn { + background-color: #d34836; +} + +.sk-folding-cube { + margin: 20px auto; + width: 40px; + height: 40px; + position: relative; + -webkit-transform: rotateZ(45deg); + transform: rotateZ(45deg); +} + +.sk-folding-cube .sk-cube { + float: left; + width: 50%; + height: 50%; + position: relative; + -webkit-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); +} + +.sk-folding-cube .sk-cube:before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: #ef114c; + -webkit-animation: sk-foldCubeAngle 2.4s infinite linear both; + animation: sk-foldCubeAngle 2.4s infinite linear both; + -webkit-transform-origin: 100% 100%; + -ms-transform-origin: 100% 100%; + transform-origin: 100% 100%; +} + +.sk-folding-cube .sk-cube2 { + -webkit-transform: scale(1.1) rotateZ(90deg); + transform: scale(1.1) rotateZ(90deg); +} + +.sk-folding-cube .sk-cube3 { + -webkit-transform: scale(1.1) rotateZ(180deg); + transform: scale(1.1) rotateZ(180deg); +} + +.sk-folding-cube .sk-cube4 { + -webkit-transform: scale(1.1) rotateZ(270deg); + transform: scale(1.1) rotateZ(270deg); +} + +.sk-folding-cube .sk-cube2:before { + -webkit-animation-delay: 0.3s; + animation-delay: 0.3s; +} + +.sk-folding-cube .sk-cube3:before { + -webkit-animation-delay: 0.6s; + animation-delay: 0.6s; +} + +.sk-folding-cube .sk-cube4:before { + -webkit-animation-delay: 0.9s; + animation-delay: 0.9s; +} + +@-webkit-keyframes sk-foldCubeAngle { + 0%, 10% { + -webkit-transform: perspective(140px) rotateX(-180deg); + transform: perspective(140px) rotateX(-180deg); + opacity: 0; + } + 25%, 75% { + -webkit-transform: perspective(140px) rotateX(0deg); + transform: perspective(140px) rotateX(0deg); + opacity: 1; + } + 90%, 100% { + -webkit-transform: perspective(140px) rotateY(180deg); + transform: perspective(140px) rotateY(180deg); + opacity: 0; + } +} +@keyframes sk-foldCubeAngle { + 0%, 10% { + -webkit-transform: perspective(140px) rotateX(-180deg); + transform: perspective(140px) rotateX(-180deg); + opacity: 0; + } + 25%, 75% { + -webkit-transform: perspective(140px) rotateX(0deg); + transform: perspective(140px) rotateX(0deg); + opacity: 1; + } + 90%, 100% { + -webkit-transform: perspective(140px) rotateY(180deg); + transform: perspective(140px) rotateY(180deg); + opacity: 0; + } +} +.cmb2-element .ui-datepicker { + width: 350px !important; +} +.cmb2-element .ui-datepicker .ui-datepicker-month, .cmb2-element .ui-datepicker .ui-datepicker-year { + display: inline-block; +} + +.noUi-target, .noUi-target * { + -webkit-touch-callout: none; + -webkit-user-select: none; + -ms-touch-action: none; + -ms-user-select: none; + -moz-user-select: none; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.noUi-target { + position: relative; + direction: ltr; +} + +.noUi-base { + width: 100%; + height: 100%; + position: relative; + border-radius: 3px; +} + +.noUi-origin { + position: absolute; + right: 0; + top: 0; + left: 0; + bottom: 0; +} + +.noUi-handle { + position: relative; + z-index: 1; +} + +.noUi-stacking .noUi-handle { + z-index: 10; +} + +.noUi-state-tap .noUi-origin { + -webkit-transition: left .3s, top .3s; + transition: left 0.3s, top 0.3s; +} + +.noUi-state-drag * { + cursor: inherit !important; +} + +.noUi-base { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.noUi-horizontal { + height: 6px; + border-radius: 3px; +} +.noUi-horizontal .noUi-base .noUi-origin .noUi-handle { + margin-left: -18px; +} +.rtl .noUi-horizontal .noUi-base .noUi-origin .noUi-handle { + margin-right: -18px; + margin-left: inherit; +} +.noUi-horizontal .noUi-base .noUi-origin:first-child .noUi-handle { + margin-left: 0px; +} +.rtl .noUi-horizontal .noUi-base .noUi-origin:first-child .noUi-handle { + margin-right: 0px; + margin-left: inherit; +} + +.noUi-horizontal[data-mode="1"] .noUi-base { + background: #2f73e9; +} +.noUi-horizontal[data-mode="1"] .noUi-base .noUi-origin { + background: #e9e9f6; +} +.noUi-horizontal[data-mode="1"] .noUi-base .noUi-origin:first-child .noUi-handle { + margin-left: -9px; +} +.rtl .noUi-horizontal[data-mode="1"] .noUi-base .noUi-origin:first-child .noUi-handle { + margin-right: -9px; + margin-left: inherit; +} + +.noUi-horizontal[data-mode="2"] .noUi-base { + background: #e9e9f6; +} +.noUi-horizontal[data-mode="2"] .noUi-base .noUi-origin { + background: transparent; +} + +.noUi-horizontal .noUi-handle { + height: 18px; + width: 18px; + left: 0px; + top: -6px; +} +.noUi-horizontal .noUi-handle.noUi-handle-upper { + margin-left: -18px; +} +.rtl .noUi-horizontal .noUi-handle.noUi-handle-upper { + margin-right: -18px; + margin-left: inherit; +} + +.noUi-vertical { + width: 18px; +} + +.noUi-vertical .noUi-handle { + width: 28px; + height: 34px; + left: -6px; + top: -17px; +} + +.noUi-background { + background: #dadada; + border-radius: 3px; +} + +.noUi-connect { + background: #2f73e9; + border-radius: 3px; + height: 100%; + position: absolute; +} + +.noUi-dragable { + cursor: w-resize; +} + +.noUi-vertical .noUi-dragable { + cursor: n-resize; +} + +.noUi-handle { + border-radius: 50%; + background: #FFF; + cursor: default; + border: 1px solid rgba(0, 0, 0, 0.1); +} + +.noUi-active { + box-shadow: inset 0 0 1px #FFF, inset 0 1px 7px #DDD, 0 3px 6px -3px #BBB; +} + +[disabled] .noUi-connect, [disabled].noUi-connect { + background: #B8B8B8; +} + +[disabled] .noUi-handle { + cursor: not-allowed; +} + +.opalestate-rating-detail-container { + display: none; +} + +.opalestate-tooltip { + display: inline-block; + line-height: 1; +} + +.opalestate-rating-detail { + padding: 0; + margin: 0; + list-style: none; + text-align: center; + line-height: 2; +} +.opalestate-rating-detail li { + padding: 5px 0; +} +.opalestate-rating-detail li label { + margin-bottom: 0; +} +.opalestate-rating-detail li:not(:last-child) { + border-bottom: 1px solid #ebebeb; +} + +body .tooltipster-sidetip .tooltipster-box { + border: none; + border-radius: 5px; + background: white; + box-shadow: 0px 2px 8px 4px rgba(0, 0, 0, 0.12); +} +body .tooltipster-sidetip.tooltipster-bottom .tooltipster-box { + margin-top: 6px; +} +body .tooltipster-sidetip.tooltipster-left .tooltipster-box { + margin-right: 6px; +} +body .tooltipster-sidetip.tooltipster-right .tooltipster-box { + margin-left: 6px; +} +body .tooltipster-sidetip.tooltipster-top .tooltipster-box { + margin-bottom: 6px; +} +body .tooltipster-sidetip .tooltipster-content { + color: #7e7e7e; + background-color: #FFF; +} +body .tooltipster-sidetip .tooltipster-arrow { + height: 6px; + margin-left: -6px; + width: 12px; +} +body .tooltipster-sidetip.tooltipster-left .tooltipster-arrow, +body .tooltipster-sidetip.tooltipster-right .tooltipster-arrow { + height: 12px; + margin-left: 0; + margin-top: -6px; + width: 6px; +} +body .tooltipster-sidetip .tooltipster-arrow-background { + display: none; +} +body .tooltipster-sidetip .tooltipster-arrow-border { + border: 6px solid transparent; +} +body .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border { + border-bottom-color: white; +} +body .tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border { + border-left-color: white; +} +body .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border { + border-right-color: white; +} +body .tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border { + border-top-color: white; +} +body .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped { + top: -6px; +} +body .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped { + left: -6px; +} + +/***/ +/** + * jQuery toast plugin created by Kamran Ahmed copyright MIT license 2014 + */ +.jq-toast-wrap { + display: block; + position: fixed; + width: 350px; + pointer-events: none !important; + margin: 0; + padding: 0; + letter-spacing: normal; + z-index: 9000 !important; +} + +.jq-toast-wrap * { + margin: 0; + padding: 0; +} + +.jq-toast-wrap.bottom-left { + bottom: 20px; + left: 20px; +} + +.jq-toast-wrap.bottom-right { + bottom: 20px; + right: 40px; +} + +.jq-toast-wrap.top-left { + top: 20px; + left: 20px; +} + +.jq-toast-wrap.top-right { + top: 20px; + right: 40px; +} + +.jq-toast-single { + display: block; + width: 100%; + padding: 10px; + margin: 0px 0px 5px; + border-radius: 4px; + font-size: 12px; + line-height: 17px; + position: relative; + pointer-events: all !important; + background-color: #444444; + color: white; +} + +.jq-toast-single h2 { + font-size: 14px; + margin: 0px 0px 7px; + background: none; + color: inherit; + line-height: inherit; + letter-spacing: normal; +} + +.jq-toast-single a { + color: #eee; + text-decoration: none; + font-weight: bold; + border-bottom: 1px solid white; + padding-bottom: 3px; + font-size: 12px; +} + +.jq-toast-single ul { + margin: 0px 0px 0px 15px; + background: none; + padding: 0px; +} + +.jq-toast-single ul li { + list-style-type: disc !important; + line-height: 17px; + background: none; + margin: 0; + padding: 0; + letter-spacing: normal; +} + +.close-jq-toast-single { + position: absolute; + top: 3px; + right: 7px; + font-size: 14px; + cursor: pointer; +} + +.jq-toast-loader { + display: block; + position: absolute; + top: -2px; + height: 5px; + width: 0%; + left: 0; + border-radius: 5px; + background: red; +} + +.jq-toast-loaded { + width: 100%; +} + +.jq-has-icon { + padding: 10px 10px 10px 50px; + background-repeat: no-repeat; + background-position: 10px; +} + +.jq-icon-info { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII="); + background-color: #31708f; + color: #d9edf7; + border-color: #bce8f1; +} + +.jq-icon-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII="); + background-color: #8a6d3b; + color: #fcf8e3; + border-color: #faebcc; +} + +.jq-icon-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII="); + background-color: #a94442; + color: #f2dede; + border-color: #ebccd1; +} + +.jq-icon-success { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg=="); + color: #dff0d8; + background-color: #3c763d; + border-color: #d6e9c6; +} + +/* + * + */ +.opalestate-search-form:not([class*="opalestate-search-form--vertical"]) { + background-color: #FFF; + padding: 15px 30px; +} +.opalestate-search-form:not([class*="opalestate-search-form--vertical"]).opalestate-search-agents-form { + border: 1px solid #ebebeb; + margin-bottom: 30px; +} +.opalestate-search-form .btn-search, .opalestate-search-form .status-item, .opalestate-search-form .opalestate-collapse-btn { + margin-top: 45px; +} +.opalestate-search-form.hidden-labels .opalestate-label { + display: none; +} +.opalestate-search-form.hidden-labels .input-search-city .opalestate-popup { + top: 20%; +} +.opalestate-search-form.hidden-labels .select2-container, .opalestate-search-form.hidden-labels .btn-search, .opalestate-search-form.hidden-labels .form-control, .opalestate-search-form.hidden-labels .opal-collapse-button, .opalestate-search-form.hidden-labels .input-group-number { + margin: 15px 0; +} +.opalestate-search-form.hidden-labels .opal-slide-ranger .slide-ranger-label { + display: block; + line-height: 2; +} +.opalestate-search-form.hidden-labels .map-remove { + top: 10px; +} +.opalestate-search-form .opalestate-label { + font-weight: 500; + display: block; + color: #0a1938; + line-height: 1; + margin-top: 15px; + margin-bottom: 15px; +} +.opalestate-search-form h6 { + margin: 0; +} +.opalestate-search-form .searchbox-top { + border-bottom: solid 1px #ebebeb; + margin-bottom: 15px; + text-transform: uppercase; +} +.opalestate-search-form .select2-container, .opalestate-search-form .btn-search, .opalestate-search-form .form-control, .opalestate-search-form .list-property-status, .opalestate-search-form .opal-collapse-button, .opalestate-search-form .input-group-number { + margin-bottom: 15px; +} +.opalestate-search-form .opal-slide-ranger { + padding: 8px 0; +} +.opalestate-search-form .opal-slide-ranger .slide-ranger-label { + display: block; + line-height: 1; +} +.opalestate-search-form .list-property-status .status-item { + cursor: pointer; + text-align: center; + flex: 1; + padding: 9px 0 6px; + color: #FFF; + background-color: #02ce76; + transition: all ease-in-out 0.5s; +} +.opalestate-search-form .list-property-status .status-item:hover, .opalestate-search-form .list-property-status .status-item.active { + background-color: #2f73e9; +} +.opalestate-search-form .btn-search { + width: 100%; + text-align: center; +} +.opalestate-search-form .btn-search i { + margin-right: 5px; +} +@media screen and (max-width: 768px) { + .opalestate-search-form .opal-slide-ranger { + margin: 15px 0; + } +} + +.opalestate-archive-agency .opalestate-search-form:not([class*="opalestate-search-form--vertical"]), +.opalestate-archive-search-block .opalestate-search-form:not([class*="opalestate-search-form--vertical"]), +.post-type-archive-opalestate_agent .opalestate-search-form:not([class*="opalestate-search-form--vertical"]) { + margin: 0 -30px; +} + +.map-remove { + display: none; + position: absolute; + right: 50px; + top: 40px; +} + +.opalestate-search-opal-map.active .map-remove { + display: block; +} +.opalestate-search-opal-map.active .map-remove:focus, .opalestate-search-opal-map.active .map-remove:hover { + cursor: pointer; +} +.opalestate-search-opal-map.active input[value=""] + .map-remove { + display: none; +} + +[class*="opalestate-search-form--vertical"] .btn-search { + margin-top: 15px; +} +[class*="opalestate-search-form--vertical"] .opalestate-label { + margin-top: 10px; + margin-bottom: 10px; +} + +.search-more-options { + position: relative; + margin: 15px 0 5px; + line-height: 1; +} + +a.opal-collapse-button { + display: block; + font-weight: 600; +} +a.opal-collapse-button:before { + font-family: "Font Awesome 5 Free"; + content: '\f0fe'; + padding-right: 5px; + color: #2f73e9; + transition: all 0.5s ease; +} +a.opal-collapse-button.show { + color: #2f73e9; +} +a.opal-collapse-button.show:before { + content: '\f146'; +} + +.more-options-container { + margin-top: 15px; +} + +.more-options-items { + display: inline-block; + width: 100%; +} + +.opal-collapse-container { + width: 100%; + display: none; +} + +button.opal-collapse-button { + transition: all 0.5s; + width: 100%; +} +button.opal-collapse-button i::before { + display: block; + transition: all 0.5s; +} +button.opal-collapse-button:hover, button.opal-collapse-button.show { + outline: none; +} +button.opal-collapse-button:focus { + outline: none; +} +button.opal-collapse-button.show i::before { + transform: rotate(180deg); +} + +.more-options-item { + width: 25%; + float: left; + margin-bottom: 15px; +} +@media (max-width: 767px) { + .more-options-item { + width: 100%; + } +} + +.input-search-city { + position: relative; +} +.input-search-city .opalestate-popup { + position: absolute; + top: 40px; + right: 16px; +} + +.form-item--types .group-item { + display: block; + position: relative; + padding-left: 0px; + margin-bottom: 15px; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + line-height: 1; +} +.form-item--types .group-item .custom-checkbox-label { + z-index: -1; +} +.form-item--types .group-item input[type="checkbox"] { + position: absolute; + opacity: 0; + cursor: pointer; +} +.form-item--types .group-item input[type="checkbox"]:checked ~ .custom-checkbox-label { + background-color: #2f73e9; +} +.form-item--types .group-item input[type="checkbox"]:checked ~ .custom-checkbox-label::after { + display: block; +} +.form-item--types .group-item:hover input ~ .custom-checkbox-label { + background-color: #ccc; +} + +.opalestate-search-form--vertical .more-options-item { + float: none; + width: 100%; +} + +.more-options-label { + display: inline-block; + position: relative; + padding-left: 23px; + margin-bottom: 0px; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.more-options-label input[type="checkbox"] { + position: absolute; + opacity: 0; + cursor: pointer; +} +.more-options-label input[type="checkbox"]:checked ~ .custom-checkbox-label { + background-color: #02ce76; +} +.more-options-label input[type="checkbox"]:checked ~ .custom-checkbox-label::after { + display: block; +} +.more-options-label:hover input ~ .custom-checkbox-label { + background-color: #ccc; +} + +.custom-checkbox-label { + position: absolute; + top: 0; + left: 0; + height: 15px; + width: 15px; + background-color: #eee; +} +.custom-checkbox-label::after { + content: ""; + position: absolute; + display: none; + left: 5px; + top: 2px; + width: 5px; + height: 8px; + border: solid #FFF; + border-width: 0 2px 2px 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} + +.search-status-bar--2 .list-property-status { + padding: 0; + margin: 0; +} +.search-status-bar--2 .list-property-status .status-item { + font-size: 100%; + padding: 8px 35px 5px 35px; + color: #0a1938; + border-width: 1px 0 1px; + margin-right: 0; + margin-top: 15px; + border-style: solid; + border-color: transparent; + position: relative; + font-weight: 500; + flex: unset; + background-color: transparent; +} +.search-status-bar--2 .list-property-status .status-item:last-child { + margin-right: 0; +} +@media screen and (max-width: 767px) { + .search-status-bar--2 .list-property-status .status-item { + margin-right: 30px; + } +} +.search-status-bar--2 .list-property-status .status-item.active, .search-status-bar--2 .list-property-status .status-item:hover { + background-color: transparent; + color: #2f73e9; + border-color: #2f73e9; +} +.search-status-bar--2 .list-property-status .status-item.active::after { + content: ""; + border-top: 8px solid; + border-right: 9px solid transparent; + border-left: 9px solid transparent; + border-bottom: 0; + position: absolute; + top: 100%; + left: 50%; + transform: translateX(-50%); +} + +.opalestate-search-form--vertical .select2-container, .opalestate-search-form--vertical .input-group-number { + margin-top: 0; +} +.opalestate-search-form--vertical .opalestate-label { + display: inline-block; +} + +.opalestate-search-form--vertical-2 { + padding-top: 0; + padding-bottom: 0; +} +.opalestate-search-form--vertical-2 .opalestate-label { + display: none; +} +.opalestate-search-form--vertical-2 .input-group-number { + margin-top: 15px; +} +.opalestate-search-form--vertical-2 h6 { + margin-bottom: 5px; +} +.opalestate-search-form--vertical-2 .input-search-city .opalestate-popup { + top: 20%; +} +.opalestate-search-form--vertical-2 .opal-form-content .form-item:not(:last-of-type) { + border-bottom: 1px solid #ebebeb; + padding-bottom: 15px; + margin-bottom: 30px; +} +.opalestate-search-form--vertical-2 .more-options-items .more-options-item { + width: 100%; +} + +.input-group-number { + display: inline-flex; + align-items: center; + border: 1px solid #ebebeb; + padding: 0.65rem 1rem; + height: 50px; + width: 100%; + position: relative; + background-color: #FFF; +} +.input-group-number i[class*="icon-property-"] { + margin-right: 1rem; +} +.input-group-number .form-control { + padding: 0; + margin: 0; + height: auto; + border: none; + flex: 1; + background-color: transparent; +} +.input-group-number .form-control:focus { + background-color: transparent; +} +.input-group-number .btn-actions { + position: absolute; + right: 0; + top: 0; + line-height: 50px; +} +.input-group-number .btn-actions span { + padding-left: 1rem; + padding-right: 1rem; + border-left: 1px solid #ebebeb; +} +.input-group-number .btn-actions span:hover { + color: #02ce76; + cursor: pointer; +} + +.opalestate-search-form--advanced-6 { + display: flex; +} +.opalestate-search-form--advanced-6 .opalestate-search-form__item:not(:first-child) { + flex: 1; +} +.opalestate-search-form--advanced-6 .opalestate-search-form__item:first-child { + flex-basis: 12%; +} +.opalestate-search-form--advanced-6 .opalestate-search-form__item:first-child .select2-selection--single { + padding-left: 10px; + border-right: 0; +} +.opalestate-search-form--advanced-6 .opalestate-search-form__item:first-child .select2-selection--single .select2-selection__rendered { + padding: 0; +} +.opalestate-search-form--advanced-6 .btn-search { + width: 128px; +} + +.search-agent-title { + margin-bottom: 0; +} + +.select2-container.select2-container--default .select2-selection--single { + display: block; + width: 100%; + height: 50px; + padding: 0.65rem 1rem; + font-size: 15px; + line-height: 50px; + color: #555555; + background-color: #fff; + border: 1px solid #ebebeb; + background-clip: padding-box; + border-radius: 0; +} +.select2-container.select2-container--default .select2-selection--single .select2-selection__arrow { + height: 50px; + width: 40px; +} +.select2-container .select2-dropdown { + border-color: #ebebeb; +} + +.property-options { + position: absolute; + bottom: 10px; + right: 10px; +} +.property-options .opalestate-ajax-gallery { + width: 35px; + line-height: 35px; + text-align: center; + display: inline-block; + color: #FFF; + background-color: #02ce76; + border-radius: 50%; +} +.property-options .opalestate-ajax-gallery:hover { + background-color: #2f73e9; +} + +.author-avatar img { + border-radius: 50%; +} + +.opalestate_property { + margin-bottom: 30px; + background-color: #FFF; + border: solid 1px #ebebeb; + position: relative; +} +.opalestate_property.opalestate-single-property, .opalestate_property[class*="property-featured"] { + border: none; + margin-bottom: 0; + background: transparent; +} +.opalestate_property header { + position: relative; +} + +.property-box-image { + overflow: hidden; + position: relative; +} +.property-box-image a::after { + content: ""; + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.3); + top: 0; + left: 0; +} + +.property-price .property-regular-price, .property-price .property-saleprice { + font-size: 18px; + letter-spacing: -0.5px; + font-weight: 500; + color: #2f73e9; +} +.property-price .property-regular-price.has-saleprice { + font-size: 15px; + opacity: 0.8; +} + +/** ----list---- **/ +.property-list { + display: flex; + flex-wrap: wrap; +} +.property-list header { + flex-basis: 35.065%; +} +.property-list .property-box-image { + height: 100%; +} +.property-list .property-box-image img { + height: 100%; +} +.property-list .entry-title { + margin: 7px 0 0px; +} +.property-list .property-address { + margin: 6px 0 23px; +} +.property-list .abs-col-item { + flex: 1; + padding-left: 30px; + position: relative; + display: flex; + flex-wrap: wrap; +} +.property-list .property-meta-list { + align-self: flex-end; + flex-basis: 100%; + padding: 15px 0 0; + margin-top: 15px; + border-top: 1px solid #ebebeb; +} +.property-list .property-meta-list li { + margin-bottom: 15px; +} +.property-list .property-meta-list li:not(:last-child) { + margin-right: 30px; +} +.property-list .entry-summary { + flex-basis: 25%; + padding: 0 30px; +} +.property-list .property-meta-bottom { + display: flex; + position: absolute; + top: 10px; + right: 10px; +} +.property-list .property-meta-bottom .property-toggle-favorite { + display: block; + width: 22px; + line-height: 22px; + border-radius: 50%; + color: #FFF; + text-align: center; + cursor: pointer; + font-size: 12px; + background-color: rgba(0, 0, 0, 0.3); +} +.property-list .property-meta-bottom .property-toggle-favorite:hover { + background-color: #2f73e9; +} +.property-list .author-avatar { + width: 22px; +} +.property-list .author-link { + display: block; + line-height: 1; +} +.property-list .author-name { + display: none; +} +.property-list .meta-item:not(:last-of-type) { + margin-right: 5px; +} +.property-list .property-group-label { + top: 10px; + left: 10px; +} +@media screen and (max-width: 992px) { + .property-list { + padding: 15px; + } + .property-list header { + flex-basis: 100%; + } + .property-list .abs-col-item { + padding: 15px 0 0; + } + .property-list .entry-summary { + flex-basis: 33.3333%; + padding-top: 15px; + padding-right: 0; + } +} +@media screen and (max-width: 767px) { + .property-list .entry-summary { + flex-basis: 100%; + padding: 15px 0 0; + } +} + +.property-list-style-v1 header { + padding-bottom: 0; +} +.property-list-style-v1 .property-list { + padding: 10px; +} + +@media screen and (min-width: 768px) { + .container-cols-3 .abs-col-item { + border-right: 1px solid #ebebeb; + } +} + +.property-list-style-v2 .property-list { + padding: 0; +} +.property-list-style-v2 .abs-col-item { + padding: 0 30px; + border: none; +} +.property-list-style-v2 .entry-content { + width: 100%; +} +.property-list-style-v2 .entry-title { + margin: 16px 0 0px; +} +.property-list-style-v2 .property-address { + margin: 6px 0 0px; +} +.property-list-style-v2 .property-meta-list { + padding: 0; + margin-top: 9px; +} +.property-list-style-v2 .property-meta-list li { + margin-top: 19px; + margin-bottom: 8px; +} +.property-list-style-v2 .property-meta-list li:not(:last-child) { + margin-right: 30px; +} +.property-list-style-v2 .property-meta-list .label-property { + display: none; +} + +ul.property-meta-list { + padding: 30px 20px 0; + margin: 0; +} +ul.property-meta-list li { + line-height: 1; + margin-bottom: 30px; +} +ul.property-meta-list i { + margin-right: 5px; + width: 20px; + display: inline-block; + font-style: unset; +} + +i[class*="icon-property-"] { + font-family: FontAwesome; +} + +.icon-property-areasize:before { + content: "\f047"; +} + +.icon-property-bedrooms:before { + content: "\f236"; +} + +.icon-property-bathrooms:before { + content: "\f2cd"; +} + +.icon-property-parking:before { + content: "\f1b9"; +} + +.icon-property-builtyear:before { + content: "\f073"; +} + +.icon-property-plotsize:before { + content: "\f278"; +} + +.icon-property-orientation:before { + content: "\f14e"; +} + +.icon-property-livingrooms:before { + content: "\f26c"; +} + +.icon-property-kitchens:before { + content: "\f0f5"; +} + +.icon-property-amountrooms:before { + content: "\f1ad"; +} + +/** Grid **/ +.property-grid .entry-content { + padding: 0 20px 15px; +} +.property-grid .entry-title { + margin: 0 0 6px; +} +.property-grid .property-address { + margin: 0; +} +.property-grid .property-address span.property-view-map { + color: #7e7e7e; +} +.property-grid .property-meta-list.list-inline li { + flex-basis: 50%; + margin-right: 0; +} +.property-grid .property-price .property-regular-price, .property-grid .property-price .property-saleprice { + letter-spacing: -0.5px; + color: #2f73e9; +} +@media screen and (min-width: 768px) { + .property-grid .property-price .property-regular-price, .property-grid .property-price .property-saleprice { + font-size: 24px; + } +} +.property-grid .property-price .property-regular-price.has-saleprice { + font-size: 15px; +} +.property-grid .entry-content-bottom { + display: flex; + align-items: center; + border-top: 1px solid #ebebeb; +} +.property-grid .entry-content-bottom > *:not(:first-child) { + position: relative; + padding: 11px 0; + border-left: 1px solid #ebebeb; +} +.property-grid .entry-content-bottom > *:first-child { + margin-left: 20px; + flex: 1; +} +.property-grid .property-toggle-favorite { + width: 52px; + text-align: center; +} +@media screen and (max-width: 767px) { + .property-grid .entry-content { + padding: 30px 15px 15px; + } + .property-grid .property-meta-list { + padding: 23px 15px 17px 15px; + } + .property-grid .property-meta-bottom { + margin-left: 15px; + } + .property-grid .property-group-label { + left: 15px; + } +} + +.property-grid .author-link, .property-featured .author-link { + line-height: 1; + display: flex; + align-items: center; +} +.property-grid .author-link:hover, .property-featured .author-link:hover { + color: #2f73e9; +} +.property-grid .author-avatar, .property-featured .author-avatar { + width: 35px; + margin-right: 8px; +} +.property-grid .author-name, .property-featured .author-name { + font-size: 13px; + font-weight: 500; +} + +/** Grid Layout 1**/ +.property-grid-v1 .author-link { + position: absolute; + bottom: 10px; + left: 20px; + color: #FFF; +} + +/** Grid Layout 2**/ +.property-grid-v2 .property-group-label { + top: 10px; +} +.property-grid-v2 .author-name { + display: none; +} +.property-grid-v2 .property-meta-list.list-inline li { + flex-basis: unset; +} +.property-grid-v2 .property-meta-list.list-inline li:not(:last-child) { + margin-right: 25px; +} +.property-grid-v2 .entry-content-bottom .author-link { + padding: 0; + width: 52px; + justify-content: center; +} +.property-grid-v2 .author-avatar { + margin: 0; + width: 30px; + padding: 11px 0; +} + +/** Grid Layout 3**/ +.property-grid-v3 .property-meta-bottom { + position: absolute; + bottom: 15px; + padding-left: 15px; + width: 100%; +} +.property-grid-v3 .entry-title { + margin: 17px 0 6px; +} +.property-grid-v3 header { + padding: 5px 5px 0; +} +.property-grid-v3 .entry-summary { + margin-bottom: 20px; +} +.property-grid-v3 .property-price { + color: #FFF; + line-height: 1; +} +.property-grid-v3 .property-price .property-regular-price, .property-grid-v3 .property-price .property-saleprice { + color: #FFF; + font-size: 18px; +} +.property-grid-v3 .property-price .property-price-label { + font-size: 13px; +} +.property-grid-v3 .property-price .property-regular-price.has-saleprice { + font-size: 15px; +} +.property-grid-v3 .entry-content { + padding: 0 20px; +} +.property-grid-v3 .property-meta-list.list-inline { + padding: 0; +} +.property-grid-v3 .property-meta-list.list-inline .info-meta .label-property { + display: none; +} +.property-grid-v3 .property-meta-list.list-inline li { + flex-basis: unset; +} +.property-grid-v3 .property-meta-list.list-inline li:not(:last-child) { + margin-right: 30px; +} +.property-grid-v3 .entry-content-bottom { + border: none; + padding: 10px 20px; + background-color: #f4f4f4; +} +.property-grid-v3 .entry-content-bottom > *:not(:first-child) { + border: none; + padding: 0; + width: 30px; + background-color: rgba(126, 126, 126, 0.2); + border-radius: 3px; + color: #fff; +} +.property-grid-v3 .entry-content-bottom > *:not(:first-child):hover { + background-color: #2f73e9; +} +.property-grid-v3 .entry-content-bottom > *:first-child { + margin-left: 0; +} +.property-grid-v3 .author-avatar { + width: 30px; +} + +.property-mark-hover-item .property-grid__header { + min-height: 245px; +} +.property-mark-hover-item .list-inline { + padding: 0; +} +.property-mark-hover-item header::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(0, 0, 0, 0.95))); + background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.95)); + z-index: 1; +} +.property-mark-hover-item .property-price-wrapper, .property-mark-hover-item .property-areasize { + display: inline-block; + margin-right: 30px; +} +.property-mark-hover-item .entry-content { + position: absolute; + bottom: 0; + left: 0; + z-index: 2; + padding: 0 15px 15px; + color: #FFF; +} +.property-mark-hover-item .entry-title { + color: inherit; +} +.property-mark-hover-item .entry-title a { + color: inherit; +} +.property-mark-hover-item .property-price .property-regular-price, .property-mark-hover-item .property-price .property-saleprice { + font-size: 18px; + color: inherit; +} + +/** Featured Property **/ +.property-featured { + display: flex; + flex-wrap: wrap; +} +.property-featured .featured-info { + background-color: #0a1938; + color: #FFF; + flex-basis: 50%; + padding: 52px 75px 49px 100px; +} +@media screen and (max-width: 992px) { + .property-featured .featured-info { + flex-basis: 100%; + } +} +@media screen and (max-width: 1024px) { + .property-featured .featured-info { + padding: 30px; + } +} +.property-featured .author-link { + position: absolute; + bottom: 10px; + left: 15px; + color: #FFF; +} +.property-featured .property-view-map { + color: #FFF; +} +.property-featured .property-view-map i { + color: #FFF; +} +.property-featured .property-view-map a { + color: #FFF; +} +.property-featured header { + flex-basis: 100%; +} +@media screen and (min-width: 992px) { + .property-featured header { + flex-basis: 50%; + } +} +.property-featured ul.property-meta-list { + padding: 0; +} +.property-featured ul.property-meta-list > li { + margin-right: 0; + width: 50%; +} +.property-featured ul.property-meta-list i { + color: #02ce76; + width: auto; +} +.property-featured ul.property-meta-list .icon-box { + font-size: 30px; + width: auto; +} +.property-featured ul.property-meta-list .info-meta span { + display: block; + margin-bottom: 5px; +} +.property-featured .entry-title { + margin-top: 14px; + margin-bottom: 8px; +} +.property-featured .entry-title a { + color: #FFF; +} +.property-featured .entry-title a:hover { + color: #2f73e9; +} +.property-featured .property-address { + margin: 0 0 20px; +} +.property-featured .property-description { + margin-bottom: 30px; +} +.property-featured .property-price .property-regular-price, .property-featured .property-price .property-saleprice { + font-size: 24px; + color: #FFF; +} +.property-featured .property-price .property-regular-price.has-saleprice { + font-size: 18px; +} +.property-featured .property-toggle-favorite { + display: none; + width: 22px; + line-height: 22px; + border-radius: 3px; + color: #FFF; + text-align: center; + cursor: pointer; + font-size: 12px; + background-color: #0a1938; + position: absolute; + right: 10px; + top: 10px; +} +.property-featured .property-toggle-favorite:hover { + background-color: #2f73e9; +} +@media (min-width: 1200px) { + .property-featured .featured-info { + margin-top: 50px; + } + .property-featured header { + flex-basis: calc(50% + 50px); + margin-bottom: 50px; + margin-left: -50px; + } +} + +header:hover .property-bg-thumbnail a { + transform: scale(1.1); +} + +.property-bg-thumbnail { + height: 100%; + overflow: hidden; +} +.property-bg-thumbnail a { + background-repeat: no-repeat; + background-size: cover; + position: relative; + display: block; + height: 100%; + min-height: 340px; + transform: scale(1); + transition: opacity 0.5s ease, transform 1s cubic-bezier(0, 0, 0.44, 1.18), -webkit-transform 1s cubic-bezier(0, 0, 0.44, 1.18); + background-position: center center; +} +.property-bg-thumbnail a::before { + content: ""; + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.3); + top: 0; + left: 0; +} + +.opalestate-pagination { + text-align: center; + margin: 30px 0; +} +.opalestate-pagination ul { + margin: 0 auto; +} +.opalestate-pagination ul li { + list-style: none; + display: inline-block; +} +.opalestate-pagination ul li .page-numbers { + padding: 5px 15px; + display: block; +} +.opalestate-pagination ul li .page-numbers:hover, .opalestate-pagination ul li .page-numbers.current { + background: #02ce76; + color: #FFF; +} + +.opalestate_agency { + margin-bottom: 30px; +} + +.trusted-label { + font-size: 23px; + color: #2f73e9; + text-align: center; + line-height: 1; +} + +.team-header .trusted-label { + position: absolute; + right: 20px; + background-color: #FFF; + border-radius: 50%; + bottom: 0; + transform: translateY(50%); + border: 1px solid #ebebeb; + width: 48px; + line-height: 48px; +} + +.agency-box-title { + display: inline-block; + margin-right: 10px; + line-height: 1; +} + +.agency-address { + margin-bottom: 0; +} + +.agency-box-meta [class*="agency-box-"] i { + width: 15px; + margin-right: 12px; + display: inline-block; +} +.agency-box-meta a { + color: inherit; +} +.agency-box-meta a:hover { + color: #2f73e9; +} + +.agency-grid-style .agency-body-content { + background-color: #f8f8f8; +} +.agency-grid-style .agency-logo { + width: 80px; + height: 80px; + border-radius: 5px; + overflow: hidden; + margin-right: 30px; +} +.agency-grid-style .agency-info { + padding: 30px; + display: flex; + flex-wrap: wrap; + border-bottom: 1px solid #ebebeb; +} +.agency-grid-style .agency-content { + flex: 1; +} +.agency-grid-style .agency-box-meta { + padding: 30px; +} +.agency-grid-style .agency-box-meta [class*="agency-box-"] { + line-height: 1; +} +.agency-grid-style .agency-box-meta [class*="agency-box-"]:not(:last-of-type) { + margin-bottom: 13px; +} +.agency-grid-style .agency-box-title { + margin-bottom: 9px; + margin-right: 0; + display: block; +} +.agency-grid-style .agency-address { + font-size: 13px; +} + +.agency-list-style .agency-inner { + display: flex; + flex-wrap: wrap; + padding: 30px 0; + border: 1px solid #ebebeb; +} +.agency-list-style .agent-box-image { + height: 100%; +} +.agency-list-style .agent-box-image img { + height: 100%; +} +.agency-list-style .agency-header { + margin: 0 30px; +} +.agency-list-style .agency-body-content { + flex: 1; + padding: 30px 0 0; +} +.agency-list-style .agency-logo { + width: 48px; + height: 48px; + border-radius: 50%; + border: 1px solid #ebebeb; + overflow: hidden; + position: absolute; + bottom: 0; + right: 30px; + transform: translateY(50%); +} +.agency-list-style .agency-info { + position: relative; + padding: 0 30px 18px; + border-bottom: 1px solid #ebebeb; + margin-bottom: 17px; +} +@media screen and (max-width: 767px) { + .agency-list-style .agency-box-meta { + padding: 0 30px; + } +} +.agency-list-style .agency-box-title { + margin-bottom: 0px; +} +@media screen and (min-width: 768px) { + .agency-list-style .agency-body-content { + padding: 0 0 0 10px; + } + .agency-list-style .agency-header { + max-width: 240px; + } + .agency-list-style .agency-info { + padding: 0 0 18px; + } +} + +.floating-keep-top { + position: fixed; + top: 0; + width: 100%; + background: #FFF; + z-index: 999; + transition: all 1s ease-in-out; +} + +.admin-bar .floating-keep-top { + top: 32px; +} + +.hide { + display: none !important; +} + +.highlight-text { + font-weight: 500; +} + +ul.property-status { + padding: 0; + margin: 0; + display: inline-block; +} +ul.property-status li { + list-style: none; + display: inline-block; +} +ul.property-status li:not(:last-child) { + margin-right: 5px; +} + +.keep-top-bars { + top: -70px; + transition: all 1s ease-in-out; + border-bottom: 1px solid #ebebeb; +} +.keep-top-bars ul { + margin: 0; + align-items: center; +} +.keep-top-bars ul:not(.opalestate-scroll-elements) { + padding: 10px 0; +} +.keep-top-bars ul li:not(:last-child) { + margin-right: 50px; +} +.keep-top-bars.floating-keep-top { + border-bottom: none; + box-shadow: 0px 2px 8px 4px rgba(0, 0, 0, 0.12); +} +.keep-top-bars .single-property-buttons { + flex: 1; + text-align: right; +} +.keep-top-bars .single-property-buttons a { + position: relative; + margin-left: 20px; + text-transform: capitalize; +} +.keep-top-bars .single-property-buttons a i { + margin-right: 18px; + padding-right: 20px; +} +.keep-top-bars .single-property-buttons a::before { + content: ""; + width: 52px; + position: absolute; + top: 0; + left: 0; + height: 100%; + background-color: transparent; + box-shadow: 0px 2px 8px 4px rgba(0, 0, 0, 0.12); +} + +.opalestate-scroll-elements a:not(.btn-primary) { + display: block; + padding: 21px 0 17px; + border-bottom: 3px solid transparent; + color: inherit; + transition: all .5s ease-in-out; +} +.opalestate-scroll-elements a:not(.btn-primary):focus, .opalestate-scroll-elements a:not(.btn-primary):hover { + border-color: #2f73e9; + color: inherit; +} + +.opalestate-rating__stars { + position: relative; + overflow: hidden; + height: 15px; + font-size: 15px; + width: calc(15px*5 - 5px); + line-height: 1; +} +.opalestate-rating__stars::before { + font-family: 'FontAwesome'; + font-size: inherit; + text-rendering: auto; + content: "\f005\f005\f005\f005\f005"; + opacity: 0.5; + position: absolute; + top: 0; + left: 0; +} +.opalestate-rating__stars span { + position: relative; + overflow: hidden; + display: block; + height: 100%; + color: transparent; + padding-top: 20px; +} +.opalestate-rating__stars span::before { + font-family: 'FontAwesome'; + font-size: inherit; + text-rendering: auto; + content: "\f005\f005\f005\f005\f005"; + color: #f6be15; + position: absolute; + top: 0; + left: 0; + width: calc(15px*5); +} + +p.stars a { + position: relative; + height: 1em; + width: 1em; + text-indent: -999em; + display: inline-block; + text-decoration: none; +} +p.stars a::before { + display: block; + position: absolute; + top: 0; + left: 0; + width: 1em; + height: 1em; + line-height: 1; + font-family: "FontAwesome"; + content: "\f006"; + text-indent: 0; +} +p.stars a:hover ~ a::before { + content: "\f006"; +} +p.stars:hover a::before { + content: '\f005'; +} +p.stars.selected a.active::before { + content: '\f005'; +} +p.stars.selected a.active ~ a::before { + content: '\f006'; +} +p.stars.selected a:not(.active)::before { + content: '\f005'; +} + +.opalestate-mortgage-chart-svg { + display: inline-block; + overflow: hidden; + margin-bottom: 0; +} +.opalestate-mortgage-chart-svg::after { + content: ""; + position: absolute; + width: 60px; + height: 60px; + transform: translate(-50%, -50%); + border-radius: 50%; + top: 50%; + left: 50%; + background-color: #fff; +} + +.opalestate-loan-amount { + display: none; +} + +.opal-form-group { + margin-top: 16px; +} +.opal-form-group label { + margin-bottom: 0; + cursor: pointer; + display: block; + padding-left: 25px; +} + +/** +* SOCIAL ICONS +**/ +.opalestate-social-icons { + margin: 15px -30px 0 -30px; + border-top: 1px solid #ebebeb; + padding: 0 30px; +} +.opalestate-social-icons [class^="opalestate-social-"] { + font-size: 13px; + color: #7e7e7e; + display: inline-block; + margin: 10px 5px 0 0; + overflow: hidden; + text-decoration: none; + text-align: center; + vertical-align: top; + line-height: 32px; + width: 34px; + height: 34px; + background: #ebebeb; + transition: all 0.2s ease-out 0s; + border-radius: 50%; +} +.opalestate-social-icons [class^="opalestate-social-"]:last-of-type { + margin-right: 0; +} +.opalestate-social-icons [class^="opalestate-social-"]:hover { + border-color: #2f73e9; + color: #2f73e9; +} +.opalestate-social-icons .opalestate-social-white { + background: #FFFFFF; + color: #7e7e7e; + border: 1px solid #ebebeb; +} +.opalestate-social-icons .opalestate-social-outline { + background: transparent; + color: #000; + border: 1px solid #000; +} +.opalestate-social-icons .opalestate-social-outline-light { + background: transparent; + color: #FFF; + border: 1px solid #FFFFFF; +} +.opalestate-social-icons .opalestate-social-outline-light:hover { + background: #FFF; + color: #000; + border-color: #000; +} +.opalestate-social-icons:first-child [class*="opalestate-social-"] { + margin-top: 0; +} +.opalestate-social-icons:last-child [class*="opalestate-social-"] { + margin-bottom: 0; +} +.opalestate-social-icons.opalestate-sicolor [class*="opalestate-social-"] { + color: #FFFFFF; +} + +/** + * Tabs + */ +.opalestate-tab-head { + background-color: #2f73e9; +} + +.tab-item { + color: #FFF; + border-bottom: 3px solid transparent; + transition: all .5s ease-in-out; + padding: 14px 18px 15px; + font-weight: 500; +} +.tab-item.active, .tab-item:hover { + border-color: #02ce76; + color: #FFF; +} + +.opalestate-tab-content { + display: none; + clear: both; +} +.opalestate-tab-content.active { + display: block; +} + +.opalmembership-login-form-wrapper { + text-align: center; +} + +.list-tabs { + margin-bottom: 15px; + background-color: #FFF; + padding: 0; +} +.list-tabs ul { + padding: 0; + margin: 0; +} +.list-tabs ul li { + text-transform: uppercase; + display: inline-block; + position: relative; +} +.list-tabs ul li a { + display: block; + padding: 5px 20px; +} +.list-tabs ul li.active a, .list-tabs ul li:hover a { + color: #FFF; + background-color: #2f73e9; +} + +/** + * end Tabs + */ +.property-group-label, +.agency-label { + position: absolute; + z-index: 1; + top: 15px; + left: 20px; + line-height: 1; +} + +.property-group-status { + position: absolute; + z-index: 1; + top: 15px; + right: 20px; + line-height: 1; +} + +.property-group-status + .property-meta-bottom { + top: 45px; + right: 20px; + z-index: 9; +} + +.agency-header { + position: relative; +} + +.label { + display: inline-block; + padding: 3px 10px; + line-height: 14px; + font-size: 10px; + font-weight: 500; + margin-bottom: 0; + text-transform: uppercase; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + color: #FFF; +} + +.property-label, +.property-status-item { + margin: 0; + padding: 0; + list-style: none; + line-height: 14px; +} +.property-label.property-status-for-rent, .property-label.property-status-for-sale, +.property-status-item.property-status-for-rent, +.property-status-item.property-status-for-sale { + background-color: #2f73e9; +} +.property-label .property-label-item:not(last-child), +.property-status-item .property-label-item:not(last-child) { + margin-right: 5px; +} + +.property-label-rented { + background-color: #2048f6; + color: #FFF; +} + +.property-label-sold { + background-color: #fee882; + color: #FFF; +} + +.label-featured { + background-color: #02ce76; + color: #FFF; + margin-bottom: 5px; +} + +.single .label-featured { + margin-bottom: 0; + margin-right: 5px; +} + +.label-danger { + background-color: #2f73e9; + color: #FFF; +} + +.property-meta-list > li { + vertical-align: middle; +} +.property-meta-list .icon-box { + display: inline-block; +} +.property-meta-list .info-meta { + display: inline-block; +} + +.map-info-preview { + position: relative; + padding: 30px; + background-color: #FFFFFF; + margin-bottom: 15px; + max-width: 300px; + box-shadow: 0px 2px 8px 4px rgba(0, 0, 0, 0.12); +} +.map-info-preview:before { + position: absolute; + width: 0; + height: 0; + content: ''; + z-index: 2; + border-top: 25px solid #FFF; + border-left: 20px solid transparent; + border-right: 20px solid transparent; + transform: translateX(-50%); + left: 50%; + bottom: -14px; + margin-left: -34px; +} +.map-info-preview a img { + max-width: 240px; + width: 240px; +} +.map-info-preview .media-top { + position: relative; +} +.map-info-preview .property-status { + top: 10px; + left: 10px; + position: absolute; + line-height: 1; +} +.map-info-preview .label-property { + visibility: hidden; +} +.map-info-preview .info-container .prop-title { + text-transform: uppercase; + margin: 15px 0 8px; +} +.map-info-preview .info-container p { + line-height: 22px; +} +.map-info-preview .property-meta-list.list-inline { + border-top: 1px solid #ebebeb; + padding: 0; + display: flex; + flex-wrap: wrap; +} +.map-info-preview .property-meta-list.list-inline > li { + flex-basis: 50%; + padding: 0; + margin: 15px 0 0; +} +.map-info-preview .property-meta-list.list-inline > li i { + width: 20px; +} +.map-info-preview .arrow-down { + border-style: solid; + border-width: 10px 10px 0; + bottom: -13px; + height: 0; + left: 112px; + position: absolute; + width: 0; + border-color: #2f73e9; + display: none; +} + +.opalestate-map-preview-wrap .gm-style img { + max-width: inherit !important; +} + +.infoBox > img { + position: absolute !important; + z-index: 99; + right: -5px; + top: -10px; +} + +.opalestate-popup { + position: relative; +} +.opalestate-popup .popup-head { + position: relative; +} +.opalestate-popup .popup-head > span { + cursor: pointer; +} +.opalestate-popup .popup-head .notify { + background-color: #00bcd4; + padding: 1px 6px; + border-radius: 50%; + position: absolute; + top: -10px; + right: 0px; + font-size: 8px; + color: #FFF; +} +.opalestate-popup .popup-head .notify.active { + top: auto; + bottom: -10px; + padding: 5px; + background-color: #2f73e9; +} +.opalestate-popup .popup-body { + display: none; + position: absolute; + z-index: 999; + min-width: 450px; + top: 30px; + margin: 0 0 0 -194px; + padding: 30px; + background-color: #FFF; + box-shadow: 0px 2px 8px 4px rgba(0, 0, 0, 0.12); +} +.opalestate-popup .popup-body h6 { + margin-bottom: 15px; +} +.opalestate-popup .popup-body label { + text-transform: uppercase; +} +.opalestate-popup .popup-body button { + margin-top: 20px; +} +.opalestate-popup .popup-body .account-dashboard-content { + padding: 30px; + background-color: #FFF; + box-shadow: 0px 2px 8px 4px rgba(0, 0, 0, 0.12); + position: relative; +} +.opalestate-popup .popup-body .account-dashboard-content:before { + position: absolute; + width: 0; + height: 0; + content: ''; + z-index: 2; + border-bottom: 25px solid #FFF; + border-left: 20px solid transparent; + border-right: 20px solid transparent; + transform: translateX(-50%); + left: 50%; + top: -14px; +} +.opalestate-popup.active .popup-body { + display: block; +} +.opalestate-popup.hover-align-right:hover .popup-body { + display: block; + right: 0; + padding-top: 30px; + min-width: 250px; +} +.opalestate-popup.hover-align-right:hover .popup-body .account-dashboard-content:before { + right: -15px; + left: auto; +} +.opalestate-popup .popup-close { + position: absolute; + top: 10px; + right: 15px; + color: #2f73e9; + cursor: hand; + cursor: pointer; +} +.rtl .opalestate-popup .popup-close { + left: 15px; + right: auto; +} + +.pagination li { + display: block; + min-width: 40px; + text-align: center; + padding: 5px 15px; + font-weight: 500; + color: #7e7e7e; +} +.pagination li.current, .pagination li:hover { + background-color: #2f73e9; +} +.pagination li.current a, .pagination li:hover a { + color: #FFF; +} +.pagination .nav-links { + display: flex; + flex-wrap: wrap; +} + +.opalestate-dropdown { + position: relative; +} +.opalestate-dropdown .dropdown-body { + position: absolute; + display: none; + background: red; + min-width: 250px; + right: 0; + top: 50px; +} +.opalestate-dropdown:hover .dropdown-body { + display: block; +} + +.agent-box-list .inner { + display: flex; + border-bottom: solid 1px #ebebeb; + padding-bottom: 30px; +} +.agent-box-list .inner .agent-preview { + width: 80px; + margin-right: 15px; +} +.agent-box-list .inner .agent-preview img { + border-radius: 50%; +} +.agent-box-list .opalestate-social-icons { + padding-top: 15px; +} + +.single-property-sidebar .agent-box-list .inner { + border-bottom: 0; +} +.single-property-sidebar .agent-box-list .opalestate-social-icons { + border-bottom: 1px solid #ebebeb; + padding-bottom: 15px; + padding-top: 5px; +} + +.agent-box-image { + overflow: hidden; +} + +.property-agent-info .team-header { + text-align: center; + border: 1px solid #ebebeb; +} + +.property-agent-contact .agent-preview { + margin-bottom: 0; +} +.property-agent-contact .team-header { + margin-bottom: 30px; +} + +.team-header { + position: relative; +} +.team-header .agent-label { + position: absolute; + text-transform: uppercase; + padding: 0 10px; + color: #FFF; + margin: 0; + font-size: 10px; + font-weight: 500; +} +.team-header .agent-label li { + list-style: none; +} +.team-header .agent-featured .agent-label { + top: 0; + left: 0; + background-color: #2f73e9; +} +.team-header .agent-levels .agent-label { + bottom: 0; + left: 0; + background-color: #02ce76; +} + +.agent-box-title { + border-bottom: 1px solid #ebebeb; + padding-bottom: 20px; +} + +.agent-preview { + margin-bottom: 30px; + position: relative; +} +.agent-preview .agent-avatar { + position: absolute; + bottom: 10px; + left: 10px; + width: 35px; + border-radius: 50%; +} + +.agent-box-job { + display: none; +} + +.agent-box-meta { + color: #bbb; +} +.agent-box-meta div[class*="agent-box-"] { + line-height: 1; + padding: 8px 1px; +} +.agent-box-meta div[class*="agent-box-"]:first-of-type { + padding-top: 0; +} +.agent-box-meta div[class*="agent-box-"]:last-of-type { + padding-bottom: 0; +} +.agent-box-meta div[class*="agent-box-"] i { + width: 15px; + margin-right: 6px; +} +.agent-box-meta a { + color: inherit; +} +.agent-box-meta h4 { + padding-top: 0; +} + +.gallery-summery-style { + display: flex; + flex-wrap: wrap; +} +.gallery-summery-style a { + display: block; + width: 20%; + height: 120px; + background-size: cover; + background-repeat: no-repeat; +} + +.my-featured-section .opalestate_property { + margin-right: 1px; +} + +.property-floorplans-session .opalestate-tab-head, .tabl-simple-style .opalestate-tab-head { + line-height: 1; + border-bottom: 1px solid #ebebeb; + margin-bottom: 16px; + margin-top: 0; + background-color: transparent; +} +.property-floorplans-session .tab-item, .tabl-simple-style .tab-item { + background-color: transparent; + padding: 0; + color: #0a1938; + display: inline-block; + padding-bottom: 19px; + font-weight: 500; + border-bottom: 3px solid transparent; + margin-bottom: -2px; +} +.property-floorplans-session .tab-item:not(:last-of-type), .tabl-simple-style .tab-item:not(:last-of-type) { + margin-right: 28px; +} +.property-floorplans-session .tab-item.active, .property-floorplans-session .tab-item:hover, .tabl-simple-style .tab-item.active, .tabl-simple-style .tab-item:hover { + background-color: transparent; + color: #0a1938; + border-color: #02ce76; +} + +.plan-name, .plan-content { + display: none; +} + +.plan-image { + padding: 24px; +} + +.property-category { + position: relative; + overflow: hidden; +} +.property-category .static-content { + padding: 30px; + position: absolute; + top: 0; + width: 100%; + height: 100%; + display: flex; + flex-wrap: wrap; + align-items: center; +} +.property-category .static-content a { + color: #FFF; +} +.property-category .property-category-count { + color: #02ce76; +} +.property-category .property-category-title { + margin-bottom: 10px; +} +.property-category .property-category-info { + flex-basis: 100%; +} +.property-category .category-overlay { + position: absolute; + top: 0; + width: 100%; + height: 100%; + display: block; + z-index: 2; +} +.property-category:hover .property-category-bg { + transform: scale(1.1); +} +.property-category:hover .property-category-bg::before { + background-color: rgba(0, 0, 0, 0.5); +} + +.property-category-bg { + background-repeat: no-repeat; + background-size: cover; + position: relative; + display: block; + height: 100%; + min-height: 340px; + transform: scale(1); + transition: opacity 0.5s ease, transform 1s cubic-bezier(0, 0, 0.44, 1.18), -webkit-transform 1s cubic-bezier(0, 0, 0.44, 1.18); + background-position: center center; +} +.property-category-bg::before { + content: ""; + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.35); + top: 0; + left: 0; +} + +.property-city { + position: relative; + overflow: hidden; +} +.property-city .static-content { + padding: 30px; + position: absolute; + top: 0; + width: 100%; + height: 100%; + display: flex; + flex-wrap: wrap; + align-items: center; +} +.property-city .static-content a { + color: #FFF; +} +.property-city .property-city-count { + color: #02ce76; +} +.property-city .property-city-title { + margin-bottom: 10px; +} +.property-city .property-city-info { + flex-basis: 100%; +} +.property-city .city-overlay { + position: absolute; + top: 0; + width: 100%; + height: 100%; + display: block; + z-index: 2; +} +.property-city:hover .property-city-bg { + transform: scale(1.1); +} +.property-city:hover .property-city-bg::before { + background-color: rgba(0, 0, 0, 0.5); +} + +.property-city-bg { + background-repeat: no-repeat; + background-size: cover; + position: relative; + display: block; + height: 100%; + min-height: 340px; + transform: scale(1); + transition: opacity 0.5s ease, transform 1s cubic-bezier(0, 0, 0.44, 1.18), -webkit-transform 1s cubic-bezier(0, 0, 0.44, 1.18); + background-position: center center; +} +.property-city-bg::before { + content: ""; + position: absolute; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.35); + top: 0; + left: 0; +} + +#opalestate-map-preview .cluster img + div { + line-height: 30px !important; +} + +.opalestate-note { + font-size: 90%; + color: #888; +} + +.list-inline { + list-style: none; + display: flex; + flex-wrap: wrap; +} +.list-inline li:not(:last-child) { + margin-right: 30px; +} + +@keyframes spinner-border { + to { + transform: rotate(360deg); + } +} +.property-toggle-favorite { + -webkit-transition: 0.5s; + -o-transition: 0.5s; + transition: 0.5s; + cursor: pointer; +} +.property-toggle-favorite:hover { + color: #2f73e9; +} + +header#masthead { + position: relative; +} + +.pull-right { + float: right !important; +} + +@media screen and (min-width: 1200px) { + .ajax-map-search-split .split-maps-container { + padding-left: 0; + } +} +.ajax-map-search-split .opalestate-search-form { + margin: 0; + padding: 15px 0; +} + +.split-maps-container { + left: 0; + right: auto; + top: 0; + z-index: 0; +} +@media screen and (min-width: 1200px) { + .split-maps-container { + position: fixed !important; + } +} + +@media screen and (min-width: 1200px) { + .split-search-container { + padding-right: 30px; + } +} + +.opalestate-loading { + position: absolute; + opacity: 0.9; + filter: alpha(opacity=90); + background-color: #fff; + top: 0; + right: 0; + width: 100%; + height: 100%; + text-align: center; +} +.opalestate-loading::before { + content: ""; + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: text-bottom; + border: .25em solid #000; + border-right-color: transparent; + border-radius: 50%; + animation: spinner-border .75s linear infinite; +} + +.opalestate-admin-box { + margin-bottom: 30px; +} +.opalestate-admin-box h3 { + border-bottom: 1px #ebebeb solid; + padding-bottom: 15px; + padding-top: 30px; + font-size: 150%; +} + +/** CMD BOX 2 */ +.select2-search-member { + display: flex; +} +.select2-search-member .member-meta { + margin-left: 12px; + font-weight: 500; +} + +.cmb2-wrap .field-row-2 .cmb-row { + display: inline-block; + width: 50%; +} + +@media screen and (min-width: 768px) { + .cmb2-wrap .field-row-2 .cmb-row:nth-child(even) > div { + padding-left: 12px; + } +} + +.cmb2-wrap .cmb-td { + padding: 4px 0; +} + +.bg-info { + background-color: #0288d1 !important; +} + +.bg-warning { + background-color: #ffca28 !important; +} + +.alert.alert-success { + background: #0F93FA; +} + +.alert.alert-danger { + background: #f55753; +} + +.alert.alert-warning { + background: #ffca28; +} + +/** + * + * Dashboard Page + */ +@media (max-width: 767px) { + .user-dasboard-sidebar { + display: none; + } + + body.active { + margin-left: 251px !important; + } + body.active .user-dasboard-sidebar { + display: block; + } + + .page-template-user-management { + margin-left: 0 !important; + } + + #show-user-sidebar-btn { + display: block !important; + } +} +.navbar-left { + display: flex; +} + +.opalestate-user-greeting .popup-head { + float: right; +} +.opalestate-user-greeting .popup-head a { + color: #FFF; + text-align: right; + position: relative; +} +.opalestate-user-greeting .popup-head a img { + width: 40px; + border-radius: 50%; +} +.opalestate-user-greeting .popup-head a i { + padding: 12px; + border-radius: 50%; + background: rgba(0, 0, 0, 0.06); +} +.opalestate-user-greeting ul { + padding: 0; + margin: 0; + list-style: none; +} + +.dashboard-navbar { + background-color: #FFF; + padding: 9px 30px; + border-bottom: 1px solid #ebebeb; +} +.dashboard-navbar ul { + margin-bottom: 0; +} + +.card-item { + background-color: #FFF; + border: solid 1px #ebebeb; + padding: 15px; +} +.card-item i { + background: rgba(0, 0, 0, 0.18); + padding: 15px; + border-radius: 50%; +} +.card-item h5 { + font-size: 200%; + text-align: center; +} +.card-item span { + font-weight: 700; +} + +@media screen and (min-width: 768px) { + .page-template-user-management .opalestate-box { + margin-right: 15px; + } +} +.page-template-user-management.logged-in { + margin-left: 251px; +} +.page-template-user-management #content { + padding-left: 30px; + padding-right: 30px; +} +.page-template-user-management #show-user-sidebar-btn { + display: none; + margin-right: 15px; +} +.page-template-user-management .opalestate-panel-myaccount { + padding-top: 45px; + padding-bottom: 45px; +} + +.admin-bar .opalestate-user-management .user-dasboard-sidebar { + padding-top: 32px; +} + +.opalmembership-dashboard .btn-link { + background-color: #02ce76; + color: #FFF; +} +.opalmembership-dashboard .btn-link:hover { + background-color: #2f73e9; +} + +.opalestate-user-management { + min-height: 600px; +} +.opalestate-user-management .property-submission-form .opalestate-box { + margin-right: 0; +} +.opalestate-user-management .user-dasboard-sidebar { + background-color: #0a1938; + min-height: 900px; + position: fixed; + left: 0; + width: 250px; + height: 100%; + z-index: 100; + top: 0px; +} +.opalestate-user-management .user-dasboard-sidebar .user-dasboard-sidebar-inner { + padding-top: 20px; +} +.opalestate-user-management .navbar-brand { + padding: 32px 15px; +} +.opalestate-user-management .account-links { + list-style: none; + padding: 0; + margin: 0; +} +.opalestate-user-management .account-links a { + padding: 8px 20px; + width: 100%; + display: block; + font-weight: 500; + color: #7e7e7e; +} +.opalestate-user-management .account-links a i { + margin-right: 6px; + color: #7e7e7e; +} +.opalestate-user-management .account-links a:hover { + background-color: #2f73e9; +} +.opalestate-user-management .site-main { + padding-top: 15px; +} + +.opalestate-my-reviews .commentlist { + margin: 0; +} +.opalestate-my-reviews .meta { + margin-bottom: 10px; +} +.opalestate-my-reviews .opalestate-review__ratings { + margin-bottom: 0; +} + +.opalestate-my-reviews-item_property-name { + margin-bottom: 5px; +} + +.opalestate-my-reviews-item_property-view { + font-size: 12px; + font-style: italic; +} + +.my-property-list .entry-content { + width: 100%; +} diff --git a/assets/scss/admin.scss b/assets/scss/admin.scss new file mode 100755 index 00000000..26e323a1 --- /dev/null +++ b/assets/scss/admin.scss @@ -0,0 +1,200 @@ +.post-type-opalestate_property .post-state{ + background:#ef114c; + font-size: 10px; + font-weight: normal; + padding: 3px 6px; + color:#FFF; + border-radius: 5px 5px 5px; +} +.fixed .column-featured, +.fixed .column-sku{ + width: 10%; +} +.fixed .column-address{ + width: 20%; +} +.type-download { + float: left; + margin: 0 1em 1em 0 !important; + padding: 0; + vertical-align: top; + width: 280px; + text-decoration: none; + color: inherit; + border: 2px solid #ddd; + display: block; + + overflow: hidden; + background: #f5f5f5; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 0 -1px 0 rgba(0, 0, 0, 0.1); + -webkit-transition-property: border, background, color; + transition-property: border, background, color; + -webkit-transition-duration: .05s; + transition-duration: .05s; + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + position: relative; + background: #FFF; +} +.type-download:hover{ + border-color: #0073aa; +} +.type-download h4{ + margin: 6px 0px; +} +.type-download a{ + font-size: 18px; + font-weight: bold; + outline: 0 none; + text-decoration: none; +} +.type-download .feed-content{ + color: #72777c; +} +.type-download img{ + max-width: 100%; +} +.type-download .feed-content{ + padding: 15px 20px; +} +.type-download .feed-bottom { + background: #ddd; + padding: 15px 8px; +} +.type-download:hover .feed-bottom{ + background: #0073aa; +} + +.vc_element-icon.icon-wpb-estates-1{ + background-image:url(images/1.png); +} + +.vc_element-icon.icon-wpb-estates-2{ + background-image:url(images/2.png); +} + +.vc_element-icon.icon-wpb-estates-3{ + background-image:url(images/3.png); +} + +.vc_element-icon.icon-wpb-estates-4{ + background-image:url(images/4.png); +} + +.vc_element-icon.icon-wpb-estates-5{ + background-image:url(images/5.png); +} + +.vc_element-icon.icon-wpb-estates-6{ + background-image:url(images/6.png); +} + +.vc_element-icon.icon-wpb-estates-7{ + background-image:url(images/7.png); +} + +.vc_element-icon.icon-wpb-estates-8{ + background-image:url(images/8.png); +} + +.vc_element-icon.icon-wpb-estates-9{ + background-image:url(images/9.png); +} + +.vc_element-icon.icon-wpb-estates-10{ + background-image:url(images/10.png); +} + +.vc_element-icon.icon-wpb-estates-11{ + background-image:url(images/11.png); +} + +.vc_element-icon.icon-wpb-estates-12{ + background-image:url(images/12.png); +} + +.vc_element-icon.icon-wpb-estates-13{ + background-image:url(images/13.png); +} + +.vc_element-icon.icon-wpb-estates-14{ + background-image:url(images/14.png); +} + +.vc_element-icon.icon-wpb-estates-15{ + background-image:url(images/15.png); +} + +.vc_element-icon.icon-wpb-estates-16{ + background-image:url(images/16.png); +} + +.vc_element-icon.icon-wpb-estates-17{ + background-image:url(images/17.png); +} + +.vc_element-icon.icon-wpb-estates-18{ + background-image:url(images/18.png); +} + +.vc_element-icon.icon-wpb-estates-19{ + background-image:url(images/19.png); +} + +/** CMD BOX 2 */ +.cmb2-wrap .field-row-2 .cmb-row { + display: inline-block; + width: 50%; +} + +.cmb2-wrap .field-row-2 .cmb-row:nth-child(even) > div { + padding-left: 12px; +} +.cmb2-wrap .cmb-td { + padding: 4px 0; +} + +.cmb2-wrap .cmb-th { + padding: 0px 10px 10px 0 +} + +/***/ +.form-settings-wrap { + display:flex; + .cmb2-wrap { + min-height:300px; + } + .subtab-settings-navs { + width:220px; + background:#2f73e9; + min-height:300px; + + ul { + padding:0; + margin:0; + li { + padding:0; + margin:0; + a{ + display:block; + padding:12px 6px; + background:#2f73e9; + text-align:right; + text-decoration:none; + color:#FFF; + font-weight:bold; + &.active { + background-color:#f1f1f1; + color:#000; + } + } + } + } + + } + .form-settings-form { + padding-left:20px; + padding-right:20px; + } +} diff --git a/assets/scss/bootstrap/_grid.scss b/assets/scss/bootstrap/_grid.scss new file mode 100755 index 00000000..10cf4a92 --- /dev/null +++ b/assets/scss/bootstrap/_grid.scss @@ -0,0 +1,31 @@ + .opal-row, .row { + // Large grid + // + // Columns, offsets, pushes, and pulls for the large desktop device range. + + + // Medium grid + // + // Columns, offsets, pushes, and pulls for the desktop device range. + + @media (min-width: $screen-sm-min) { + @include make-grid(sm); + @include make-grid-columns(sm); + @include make-row; + } + @media (min-width: $screen-md-min) { + @include make-grid(md); + @include make-grid-columns(md); + } + @media (min-width: $screen-lg-min) { + @include make-grid(lg); + @include make-grid-columns(lg); + } + +} + + +@mixin list-unstyled { + padding-left: 0; + list-style: none; +} \ No newline at end of file diff --git a/assets/scss/bootstrap/_mixins.scss b/assets/scss/bootstrap/_mixins.scss new file mode 100755 index 00000000..a1de4395 --- /dev/null +++ b/assets/scss/bootstrap/_mixins.scss @@ -0,0 +1,7 @@ +@import "mixins/opacity"; +@import "mixins/size"; +@import "mixins/vendor-prefixes"; +// Layout +@import "mixins/clearfix"; +@import "mixins/grid-framework"; +@import "mixins/grid"; \ No newline at end of file diff --git a/assets/scss/bootstrap/_unlities.scss b/assets/scss/bootstrap/_unlities.scss new file mode 100755 index 00000000..8c99c716 --- /dev/null +++ b/assets/scss/bootstrap/_unlities.scss @@ -0,0 +1,55 @@ +// +// Utility classes +// -------------------------------------------------- + + +// Floats +// ------------------------- + +.clearfix { + @include clearfix; +} +.center-block { + @include center-block; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} + + +// Toggling content +// ------------------------- + +// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1 +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + @include text-hide; +} + + +// Hide from screenreaders and browsers +// +// Credit: HTML5 Boilerplate + +.hidden { + display: none !important; +} + + +// For Affix plugin +// ------------------------- + +.affix { + position: fixed; +} diff --git a/assets/scss/bootstrap/_variables.scss b/assets/scss/bootstrap/_variables.scss new file mode 100755 index 00000000..878a0c82 --- /dev/null +++ b/assets/scss/bootstrap/_variables.scss @@ -0,0 +1,887 @@ +$bootstrap-sass-asset-helper: false !default; +// +// Variables +// -------------------------------------------------- + + +//== Colors +// +//## Gray and brand colors for use across Bootstrap. + +$gray-base : #000; +$light-gray : lighten(#000000, 60%) !default; // #999999 +$very-light-gray : #ebebeb !default; // #e5e5e5 +$very-dark-gray : lighten(#000000, 9%) !default; // #171717 +$gray-darker : #0d292f !default; // #0d292f +$gray-dark : #888888 !default; // #888888 +$gray : lighten(#000, 33.5%) !default; // #555555 +$gray-light : lighten(#000, 46.7%) !default; // #777777 +$gray-lighter : lighten(#000, 93.5%) !default; // #eeeeee + +$brand-primary : #ef114c !default; +$brand-success : #8ac842 !default; +$brand-info : #07a5db !default; +$brand-warning : #fabd47 !default; +$brand-danger : #ef114c !default; + + +//== Scaffolding +// +//## Settings for some of the most global styles. + +//** Background color for ``. +$body-bg: #f7f7f7 !default; +//** Global text color on ``. +$text-color: $gray-dark !default; + +//** Global textual link color. +$link-color: $gray-base !default; +//** Link hover color set via `darken()` function. +$link-hover-color: $brand-primary !default; +//** Link hover decoration. +$link-hover-decoration: none !default; + + +//== Typography +// +//## Font, line-height, and color for body text, headings, and more. + +$font-family-sans-serif: 'Lato', sans-serif !default; +$font-family-serif: Georgia, "Times New Roman", Times, serif !default; +//** Default monospace fonts for ``, ``, and `
            `.
            +$font-family-monospace:   "Montserrat", monospace !default;
            +$font-family-base:        'Lato', sans-serif !default;
            +
            +$font-size-base:          15px !default;
            +$font-size-large:         ceil(($font-size-base * 1.25)) !default; // ~18px
            +$font-size-small:         ceil(($font-size-base * 0.85)) !default; // ~12px
            +$font-size-md:         	  12px !default;
            +
            +$font-size-h1:            floor(($font-size-base * 2.6)) !default; // ~36px
            +$font-size-h2:            floor(($font-size-base * 2.15)) !default; // ~30px
            +$font-size-h3:            ceil(($font-size-base * 1.7)) !default; // ~24px
            +$font-size-h4:            ceil(($font-size-base * 1.25)) !default; // ~18px
            +$font-size-h5:            $font-size-base !default;
            +$font-size-h6:            ceil(($font-size-base * 0.85)) !default; // ~12px
            +
            +$font-weight-base	: 400 !default;
            +//** Unit-less `line-height` for use in components like buttons.
            +$line-height-base:        1.428571429 !default; // 20/14
            +//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
            +$line-height-computed:    floor(($font-size-base * $line-height-base)) !default; // ~20px
            +
            +//** By default, this inherits from the ``.
            +$headings-font-family:    "Montserrat", monospace !default;
            +$headings-font-weight:    700 !default;
            +$headings-line-height:    1.1 !default;
            +$headings-color:          $gray-base !default;
            +
            +
            +//== Iconography
            +//
            +//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
            +
            +//** Load fonts from this directory.
            +
            +// [converter] If $bootstrap-sass-asset-helper if used, provide path relative to the assets load path.
            +// [converter] This is because some asset helpers, such as Sprockets, do not work with file-relative paths.
            +$icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/") !default;
            +
            +//** File name for all font files.
            +$icon-font-name:          "glyphicons-halflings-regular" !default;
            +//** Element ID within SVG icon file.
            +$icon-font-svg-id:        "glyphicons_halflingsregular" !default;
            +
            +
            +//== Components
            +//
            +//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
            +
            +$padding-base-vertical:     6px !default;
            +$padding-base-horizontal:   12px !default;
            +
            +$padding-large-vertical:    12px !default;
            +$padding-large-horizontal:  16px !default;
            +
            +$padding-small-vertical:    5px !default;
            +$padding-small-horizontal:  10px !default;
            +
            +$padding-md-vertical:       10px !default;
            +$padding-md-horizontal:     20px !default;
            +
            +$padding-xs-vertical:       1px !default;
            +$padding-xs-horizontal:     5px !default;
            +
            +$line-height-large:         1.3333333 !default; // extra decimals for Win 8.1 Chrome
            +$line-height-small:         1.5 !default;
            +
            +$border-radius-base:        10px !default;
            +$border-radius-large:       20px !default;
            +$border-radius-small:       4px !default;
            +
            +//** Global color for active items (e.g., navs or dropdowns).
            +$component-active-color:    #fff !default;
            +//** Global background color for active items (e.g., navs or dropdowns).
            +$component-active-bg:       $brand-primary !default;
            +
            +//** Width of the `border` for generating carets that indicator dropdowns.
            +$caret-width-base:          4px !default;
            +//** Carets increase slightly in size for larger components.
            +$caret-width-large:         5px !default;
            +
            +
            +//== Tables
            +//
            +//## Customizes the `.table` component with basic values, each used across all table variations.
            +
            +//** Padding for ``s and ``s.
            +$table-cell-padding:            8px !default;
            +//** Padding for cells in `.table-condensed`.
            +$table-condensed-cell-padding:  5px !default;
            +
            +//** Default background color used for all tables.
            +$table-bg:                      transparent !default;
            +//** Background color used for `.table-striped`.
            +$table-bg-accent:               #f9f9f9 !default;
            +//** Background color used for `.table-hover`.
            +$table-bg-hover:                #f5f5f5 !default;
            +$table-bg-active:               $table-bg-hover !default;
            +
            +//** Border color for table and cell borders.
            +$table-border-color:            #ddd !default;
            +
            +
            +//== Buttons
            +//
            +//## For each of Bootstrap's buttons, define text, background and border color.
            +
            +$btn-font-weight:                900 !default;
            +
            +$btn-default-color:              #fff !default;
            +$btn-default-bg:                 #999 !default;
            +$btn-default-border:             #999 !default;
            +
            +$btn-white-color:                #000 !default;
            +$btn-white-bg:                   #fff !default;
            +$btn-white-border:               rgba(255,255,255,.2) !default;
            +
            +$btn-primary-color:              #fff !default;
            +$btn-primary-bg:                 $brand-primary !default;
            +$btn-primary-border:             darken($btn-primary-bg, 5%) !default;
            +
            +$btn-success-color:              #fff !default;
            +$btn-success-bg:                 $brand-success !default;
            +$btn-success-border:             darken($btn-success-bg, 5%) !default;
            +
            +$btn-info-color:                 #fff !default;
            +$btn-info-bg:                    $brand-info !default;
            +$btn-info-border:                darken($btn-info-bg, 5%) !default;
            +
            +$btn-warning-color:              #fff !default;
            +$btn-warning-bg:                 $brand-warning !default;
            +$btn-warning-border:             darken($btn-warning-bg, 5%) !default;
            +
            +$btn-danger-color:               #fff !default;
            +$btn-danger-bg:                  $brand-danger !default;
            +$btn-danger-border:              darken($btn-danger-bg, 5%) !default;
            +
            +$btn-link-disabled-color:        $gray-light !default;
            +
            +// Allows for customizing button radius independently from global border radius
            +$btn-border-radius-base:         $border-radius-base !default;
            +$btn-border-radius-large:        $border-radius-large !default;
            +$btn-border-radius-small:        $border-radius-small !default;
            +
            +
            +//== Forms
            +//
            +//##
            +
            +//** `` background color
            +$input-bg:                       #fff !default;
            +//** `` background color
            +$input-bg-disabled:              $gray-lighter !default;
            +
            +//** Text color for ``s
            +$input-color:                    $gray !default;
            +//** `` border color
            +$input-border:                   #ebebeb !default;
            +
            +// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
            +//** Default `.form-control` border radius
            +// This has no effect on ``s in CSS.
            +$input-border-radius:            $border-radius-small !default;
            +//** Large `.form-control` border radius
            +$input-border-radius-large:      $border-radius-large !default;
            +//** Small `.form-control` border radius
            +$input-border-radius-small:      $border-radius-small !default;
            +
            +//** Border color for inputs on focus
            +$input-border-focus:             #fff !default;
            +
            +//** Placeholder text color
            +$input-color-placeholder:        #999 !default;
            +
            +//** Default `.form-control` height
            +$input-height-base:              ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
            +//** Large `.form-control` height
            +$input-height-large:             (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
            +//** Small `.form-control` height
            +$input-height-small:             (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
            +
            +//** `.form-group` margin
            +$form-group-margin-bottom:       15px !default;
            +
            +$legend-color:                   $gray-dark !default;
            +$legend-border-color:            #e5e5e5 !default;
            +
            +//** Background color for textual input addons
            +$input-group-addon-bg:           $gray-lighter !default;
            +//** Border color for textual input addons
            +$input-group-addon-border-color: $input-border !default;
            +
            +//** Disabled cursor for form controls and buttons.
            +$cursor-disabled:                not-allowed !default;
            +
            +
            +//== Dropdowns
            +//
            +//## Dropdown menu container and contents.
            +
            +//** Background for the dropdown menu.
            +$dropdown-bg:                    #fff !default;
            +//** Dropdown menu `border-color`.
            +$dropdown-border:                rgba(0,0,0,.15) !default;
            +//** Dropdown menu `border-color` **for IE8**.
            +$dropdown-fallback-border:       #ccc !default;
            +//** Divider color for between dropdown items.
            +$dropdown-divider-bg:            #e5e5e5 !default;
            +
            +//** Dropdown link text color.
            +$dropdown-link-color:            $gray-dark !default;
            +//** Hover color for dropdown links.
            +$dropdown-link-hover-color:      darken($gray-dark, 5%) !default;
            +//** Hover background for dropdown links.
            +$dropdown-link-hover-bg:         #f5f5f5 !default;
            +
            +//** Active dropdown menu item text color.
            +$dropdown-link-active-color:     $component-active-color !default;
            +//** Active dropdown menu item background color.
            +$dropdown-link-active-bg:        $component-active-bg !default;
            +
            +//** Disabled dropdown menu item background color.
            +$dropdown-link-disabled-color:   $gray-light !default;
            +
            +//** Text color for headers within dropdown menus.
            +$dropdown-header-color:          $gray-light !default;
            +
            +//** Deprecated `$dropdown-caret-color` as of v3.1.0
            +$dropdown-caret-color:           #000 !default;
            +
            +
            +//-- Z-index master list
            +//
            +// Warning: Avoid customizing these values. They're used for a bird's eye view
            +// of components dependent on the z-axis and are designed to all work together.
            +//
            +// Note: These variables are not generated into the Customizer.
            +
            +$zindex-navbar:            1000 !default;
            +$zindex-dropdown:          1000 !default;
            +$zindex-popover:           1060 !default;
            +$zindex-tooltip:           1070 !default;
            +$zindex-navbar-fixed:      1030 !default;
            +$zindex-modal-background:  1040 !default;
            +$zindex-modal:             1050 !default;
            +
            +
            +//== Media queries breakpoints
            +//
            +//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
            +
            +// Extra small screen / phone
            +//** Deprecated `$screen-xs` as of v3.0.1
            +$screen-xs:                  480px !default;
            +//** Deprecated `$screen-xs-min` as of v3.2.0
            +$screen-xs-min:              $screen-xs !default;
            +//** Deprecated `$screen-phone` as of v3.0.1
            +$screen-phone:               $screen-xs-min !default;
            +
            +// Small screen / tablet
            +//** Deprecated `$screen-sm` as of v3.0.1
            +$screen-sm:                  768px !default;
            +$screen-sm-min:              $screen-sm !default;
            +//** Deprecated `$screen-tablet` as of v3.0.1
            +$screen-tablet:              $screen-sm-min !default;
            +
            +// Medium screen / desktop
            +//** Deprecated `$screen-md` as of v3.0.1
            +$screen-md:                  992px !default;
            +$screen-md-min:              $screen-md !default;
            +//** Deprecated `$screen-desktop` as of v3.0.1
            +$screen-desktop:             $screen-md-min !default;
            +
            +// Large screen / wide desktop
            +//** Deprecated `$screen-lg` as of v3.0.1
            +$screen-lg:                  1200px !default;
            +$screen-lg-min:              $screen-lg !default;
            +//** Deprecated `$screen-lg-desktop` as of v3.0.1
            +$screen-lg-desktop:          $screen-lg-min !default;
            +
            +// So media queries don't overlap when required, provide a maximum
            +$screen-xs-max:              ($screen-sm-min - 1) !default;
            +$screen-sm-max:              ($screen-md-min - 1) !default;
            +$screen-md-max:              ($screen-lg-min - 1) !default;
            +
            +
            +//== Grid system
            +//
            +//## Define your custom responsive grid.
            +
            +//** Number of columns in the grid.
            +$grid-columns:              12 !default;
            +//** Padding between columns. Gets divided in half for the left and right.
            +$grid-gutter-width:         30px !default;
            +// Navbar collapse
            +//** Point at which the navbar becomes uncollapsed.
            +$grid-float-breakpoint:     $screen-sm-min !default;
            +//** Point at which the navbar begins collapsing.
            +$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
            +
            +
            +//== Container sizes
            +//
            +//## Define the maximum width of `.container` for different screen sizes.
            +
            +//## Define the maximum width of `.container` for different screen sizes.
            +
            +// Small screen / tablet
            +$container-tablet:             ((750px + $grid-gutter-width)) !default;
            +//** For `$screen-sm-min` and up.
            +$container-sm:                 $container-tablet !default;
            +
            +// Medium screen / desktop
            +$container-desktop:            ((970px + $grid-gutter-width)) !default;
            +//** For `$screen-md-min` and up.
            +$container-md:                 $container-desktop !default;
            +
            +// Large screen / wide desktop
            +$container-large-desktop:      ((1170px + $grid-gutter-width) ) !default;
            +//** For `$screen-lg-min` and up.
            +$container-lg:                 $container-large-desktop !default;
            +
            +
            +
            +//== Navbar
            +//
            +//##
            +
            +// Basics of a navbar
            +$navbar-height:                    50px !default;
            +$navbar-margin-bottom:             $line-height-computed !default;
            +$navbar-border-radius:             $border-radius-base !default;
            +$navbar-padding-horizontal:        floor(($grid-gutter-width / 2)) !default;
            +$navbar-padding-vertical:          (($navbar-height - $line-height-computed) / 2) !default;
            +$navbar-collapse-max-height:       340px !default;
            +
            +$navbar-default-color:             #777 !default;
            +$navbar-default-bg:                #f8f8f8 !default;
            +$navbar-default-border:            darken($navbar-default-bg, 6.5%) !default;
            +
            +// Navbar links
            +$navbar-default-link-color:                #777 !default;
            +$navbar-default-link-hover-color:          #333 !default;
            +$navbar-default-link-hover-bg:             transparent !default;
            +$navbar-default-link-active-color:         #555 !default;
            +$navbar-default-link-active-bg:            darken($navbar-default-bg, 6.5%) !default;
            +$navbar-default-link-disabled-color:       #ccc !default;
            +$navbar-default-link-disabled-bg:          transparent !default;
            +
            +// Navbar brand label
            +$navbar-default-brand-color:               $navbar-default-link-color !default;
            +$navbar-default-brand-hover-color:         darken($navbar-default-brand-color, 10%) !default;
            +$navbar-default-brand-hover-bg:            transparent !default;
            +
            +// Navbar toggle
            +$navbar-default-toggle-hover-bg:           #ddd !default;
            +$navbar-default-toggle-icon-bar-bg:        #888 !default;
            +$navbar-default-toggle-border-color:       #ddd !default;
            +
            +
            +//=== Inverted navbar
            +// Reset inverted navbar basics
            +$navbar-inverse-color:                      lighten($gray-light, 15%) !default;
            +$navbar-inverse-bg:                         #222 !default;
            +$navbar-inverse-border:                     darken($navbar-inverse-bg, 10%) !default;
            +
            +// Inverted navbar links
            +$navbar-inverse-link-color:                 lighten($gray-light, 15%) !default;
            +$navbar-inverse-link-hover-color:           #fff !default;
            +$navbar-inverse-link-hover-bg:              transparent !default;
            +$navbar-inverse-link-active-color:          $navbar-inverse-link-hover-color !default;
            +$navbar-inverse-link-active-bg:             darken($navbar-inverse-bg, 10%) !default;
            +$navbar-inverse-link-disabled-color:        #444 !default;
            +$navbar-inverse-link-disabled-bg:           transparent !default;
            +
            +// Inverted navbar brand label
            +$navbar-inverse-brand-color:                $navbar-inverse-link-color !default;
            +$navbar-inverse-brand-hover-color:          #fff !default;
            +$navbar-inverse-brand-hover-bg:             transparent !default;
            +
            +// Inverted navbar toggle
            +$navbar-inverse-toggle-hover-bg:            #333 !default;
            +$navbar-inverse-toggle-icon-bar-bg:         #fff !default;
            +$navbar-inverse-toggle-border-color:        #333 !default;
            +
            +
            +//== Navs
            +//
            +//##
            +
            +//=== Shared nav styles
            +$nav-link-padding:                          10px 15px !default;
            +$nav-link-hover-bg:                         $gray-lighter !default;
            +
            +$nav-disabled-link-color:                   $gray-light !default;
            +$nav-disabled-link-hover-color:             $gray-light !default;
            +
            +//== Tabs
            +$nav-tabs-border-color:                     #ddd !default;
            +
            +$nav-tabs-link-hover-border-color:          $gray-lighter !default;
            +
            +$nav-tabs-active-link-hover-bg:             $body-bg !default;
            +$nav-tabs-active-link-hover-color:          $gray !default;
            +$nav-tabs-active-link-hover-border-color:   #ddd !default;
            +
            +$nav-tabs-justified-link-border-color:            #ddd !default;
            +$nav-tabs-justified-active-link-border-color:     $body-bg !default;
            +
            +//== Pills
            +$nav-pills-border-radius:                   $border-radius-base !default;
            +$nav-pills-active-link-hover-bg:            $component-active-bg !default;
            +$nav-pills-active-link-hover-color:         $component-active-color !default;
            +
            +
            +//== Pagination
            +//
            +//##
            +
            +$pagination-color:                     $link-color !default;
            +$pagination-bg:                        transparent !default;
            +$pagination-border:                    #ddd !default;
            +
            +$pagination-hover-color:               $link-hover-color !default;
            +$pagination-hover-bg:                  $gray-lighter !default;
            +$pagination-hover-border:              #ddd !default;
            +
            +$pagination-active-color:              #fff !default;
            +$pagination-active-bg:                 $brand-primary !default;
            +$pagination-active-border:             $brand-primary !default;
            +
            +$pagination-disabled-color:            $gray-light !default;
            +$pagination-disabled-bg:               #fff !default;
            +$pagination-disabled-border:           #ddd !default;
            +
            +
            +//== Pager
            +//
            +//##
            +
            +$pager-bg:                             $pagination-bg !default;
            +$pager-border:                         $pagination-border !default;
            +$pager-border-radius:                  15px !default;
            +
            +$pager-hover-bg:                       $pagination-hover-bg !default;
            +
            +$pager-active-bg:                      $pagination-active-bg !default;
            +$pager-active-color:                   $pagination-active-color !default;
            +
            +$pager-disabled-color:                 $pagination-disabled-color !default;
            +
            +
            +//== Jumbotron
            +//
            +//##
            +
            +$jumbotron-padding:              30px !default;
            +$jumbotron-color:                inherit !default;
            +$jumbotron-bg:                   $gray-lighter !default;
            +$jumbotron-heading-color:        inherit !default;
            +$jumbotron-font-size:            ceil(($font-size-base * 1.5)) !default;
            +$jumbotron-heading-font-size:    ceil(($font-size-base * 4.5)) !default;
            +
            +
            +//== Form states and alerts
            +//
            +//## Define colors for form feedback states and, by default, alerts.
            +
            +$state-success-text:             #8ac842 !default;
            +$state-success-bg:               #1bbc9b !default;
            +$state-success-border:           darken(adjust-hue($state-success-bg, -10), 5%) !default;
            +
            +$state-info-text:                #31708f !default;
            +$state-info-bg:                  #56b0ee !default;
            +$state-info-border:              darken(adjust-hue($state-info-bg, -10), 7%) !default;
            +
            +$state-warning-text:             #8a6d3b !default;
            +$state-warning-bg:               #fcb53f !default;
            +$state-warning-border:           darken(adjust-hue($state-warning-bg, -10), 5%) !default;
            +
            +$state-danger-text:              #a94442 !default;
            +$state-danger-bg:                #ff7877 !default;
            +$state-danger-border:            darken(adjust-hue($state-danger-bg, -10), 5%) !default;
            +
            +
            +//== Tooltips
            +//
            +//##
            +
            +//** Tooltip max width
            +$tooltip-max-width:           200px !default;
            +//** Tooltip text color
            +$tooltip-color:               #fff !default;
            +//** Tooltip background color
            +$tooltip-bg:                  $brand-primary !default;
            +$tooltip-opacity:             .9 !default;
            +
            +//** Tooltip arrow width
            +$tooltip-arrow-width:         5px !default;
            +//** Tooltip arrow color
            +$tooltip-arrow-color:         $tooltip-bg !default;
            +
            +
            +//== Popovers
            +//
            +//##
            +
            +//** Popover body background color
            +$popover-bg:                          #fff !default;
            +//** Popover maximum width
            +$popover-max-width:                   276px !default;
            +//** Popover border color
            +$popover-border-color:                rgba(0,0,0,.2) !default;
            +//** Popover fallback border color
            +$popover-fallback-border-color:       #ccc !default;
            +
            +//** Popover title background color
            +$popover-title-bg:                    darken($popover-bg, 3%) !default;
            +
            +//** Popover arrow width
            +$popover-arrow-width:                 10px !default;
            +//** Popover arrow color
            +$popover-arrow-color:                 $popover-bg !default;
            +
            +//** Popover outer arrow width
            +$popover-arrow-outer-width:           ($popover-arrow-width + 1) !default;
            +//** Popover outer arrow color
            +$popover-arrow-outer-color:           fade_in($popover-border-color, 0.05) !default;
            +//** Popover outer arrow fallback color
            +$popover-arrow-outer-fallback-color:  darken($popover-fallback-border-color, 20%) !default;
            +
            +
            +//== Labels
            +//
            +//##
            +
            +//** Default label background color
            +$label-default-bg:            $gray-light !default;
            +//** Primary label background color
            +$label-primary-bg:            $brand-primary !default;
            +//** Success label background color
            +$label-success-bg:            $brand-success !default;
            +//** Info label background color
            +$label-info-bg:               $brand-info !default;
            +//** Warning label background color
            +$label-warning-bg:            $brand-warning !default;
            +//** Danger label background color
            +$label-danger-bg:             $brand-danger !default;
            +
            +//** Default label text color
            +$label-color:                 #fff !default;
            +//** Default text color of a linked label
            +$label-link-hover-color:      #fff !default;
            +
            +
            +//== Modals
            +//
            +//##
            +
            +//** Padding applied to the modal body
            +$modal-inner-padding:         20px !default;
            +
            +//** Padding applied to the modal title
            +$modal-title-padding:         20px !default;
            +//** Modal title line-height
            +$modal-title-line-height:     $line-height-base !default;
            +
            +//** Background color of modal content area
            +$modal-content-bg:                             #fff !default;
            +//** Modal content border color
            +$modal-content-border-color:                   rgba(0,0,0,.2) !default;
            +//** Modal content border color **for IE8**
            +$modal-content-fallback-border-color:          #999 !default;
            +
            +//** Modal backdrop background color
            +$modal-backdrop-bg:           #000 !default;
            +//** Modal backdrop opacity
            +$modal-backdrop-opacity:      .5 !default;
            +//** Modal header border color
            +$modal-header-border-color:   #e5e5e5 !default;
            +//** Modal footer border color
            +$modal-footer-border-color:   $modal-header-border-color !default;
            +
            +$modal-lg:                    900px !default;
            +$modal-md:                    600px !default;
            +$modal-sm:                    300px !default;
            +
            +
            +//== Alerts
            +//
            +//## Define alert colors, border radius, and padding.
            +
            +$alert-padding:               15px !default;
            +$alert-border-radius:         $border-radius-small !default;
            +$alert-link-font-weight:      bold !default;
            +
            +$alert-success-bg:            $state-success-bg !default;
            +$alert-success-text:          $state-success-text !default;
            +$alert-success-border:        $state-success-border !default;
            +
            +$alert-info-bg:               $state-info-bg !default;
            +$alert-info-text:             $state-info-text !default;
            +$alert-info-border:           $state-info-border !default;
            +
            +$alert-warning-bg:            $state-warning-bg !default;
            +$alert-warning-text:          $state-warning-text !default;
            +$alert-warning-border:        $state-warning-border !default;
            +
            +$alert-danger-bg:             $state-danger-bg !default;
            +$alert-danger-text:           $state-danger-text !default;
            +$alert-danger-border:         $state-danger-border !default;
            +
            +
            +//== Progress bars
            +//
            +//##
            +
            +//** Background color of the whole progress component
            +$progress-bg:                 #f5f5f5 !default;
            +//** Progress bar text color
            +$progress-bar-color:          #fff !default;
            +//** Variable for setting rounded corners on progress bar.
            +$progress-border-radius:      $border-radius-base !default;
            +
            +//** Default progress bar color
            +$progress-bar-bg:             $brand-primary !default;
            +//** Success progress bar color
            +$progress-bar-success-bg:     $brand-success !default;
            +//** Warning progress bar color
            +$progress-bar-warning-bg:     $brand-warning !default;
            +//** Danger progress bar color
            +$progress-bar-danger-bg:      $brand-danger !default;
            +//** Info progress bar color
            +$progress-bar-info-bg:        $brand-info !default;
            +
            +
            +//== List group
            +//
            +//##
            +
            +//** Background color on `.list-group-item`
            +$list-group-bg:                 #fff !default;
            +//** `.list-group-item` border color
            +$list-group-border:             #ddd !default;
            +//** List group border radius
            +$list-group-border-radius:      $border-radius-base !default;
            +
            +//** Background color of single list items on hover
            +$list-group-hover-bg:           #f5f5f5 !default;
            +//** Text color of active list items
            +$list-group-active-color:       $component-active-color !default;
            +//** Background color of active list items
            +$list-group-active-bg:          $component-active-bg !default;
            +//** Border color of active list elements
            +$list-group-active-border:      $list-group-active-bg !default;
            +//** Text color for content within active list items
            +$list-group-active-text-color:  lighten($list-group-active-bg, 40%) !default;
            +
            +//** Text color of disabled list items
            +$list-group-disabled-color:      $gray-light !default;
            +//** Background color of disabled list items
            +$list-group-disabled-bg:         $gray-lighter !default;
            +//** Text color for content within disabled list items
            +$list-group-disabled-text-color: $list-group-disabled-color !default;
            +
            +$list-group-link-color:         #555 !default;
            +$list-group-link-hover-color:   $list-group-link-color !default;
            +$list-group-link-heading-color: #333 !default;
            +
            +
            +//== Panels
            +//
            +//##
            +
            +$panel-bg:                    #fff !default;
            +$box-content-padding:          15px !default;
            +$panel-heading-padding:       10px 15px !default;
            +$panel-footer-padding:        $panel-heading-padding !default;
            +$panel-border-radius:         0 !default;
            +
            +//** Border color for elements within panels
            +$panel-inner-border:          #ddd !default;
            +$panel-footer-bg:             #f5f5f5 !default;
            +
            +$panel-default-text:          $gray-dark !default;
            +$panel-default-border:        #FFF !default;
            +$panel-default-heading-bg:    #f5f5f5 !default;
            +
            +$panel-primary-text:          #fff !default;
            +$panel-primary-border:        $brand-primary !default;
            +$panel-primary-heading-bg:    $brand-primary !default;
            +
            +$panel-success-text:          $state-success-text !default;
            +$panel-success-border:        $state-success-border !default;
            +$panel-success-heading-bg:    $state-success-bg !default;
            +
            +$panel-info-text:             $state-info-text !default;
            +$panel-info-border:           $state-info-border !default;
            +$panel-info-heading-bg:       $state-info-bg !default;
            +
            +$panel-warning-text:          $state-warning-text !default;
            +$panel-warning-border:        $state-warning-border !default;
            +$panel-warning-heading-bg:    $state-warning-bg !default;
            +
            +$panel-danger-text:           $state-danger-text !default;
            +$panel-danger-border:         $state-danger-border !default;
            +$panel-danger-heading-bg:     $state-danger-bg !default;
            +
            +
            +//== Thumbnails
            +//
            +//##
            +
            +//** Padding around the thumbnail image
            +$thumbnail-padding:           4px !default;
            +//** Thumbnail background color
            +$thumbnail-bg:                $body-bg !default;
            +//** Thumbnail border color
            +$thumbnail-border:            #ddd !default;
            +//** Thumbnail border radius
            +$thumbnail-border-radius:     $border-radius-base !default;
            +
            +//** Custom text color for thumbnail captions
            +$thumbnail-caption-color:     $text-color !default;
            +//** Padding around the thumbnail caption
            +$thumbnail-caption-padding:   9px !default;
            +
            +
            +//== Wells
            +//
            +//##
            +
            +$well-bg:                     #f5f5f5 !default;
            +$well-border:                 darken($well-bg, 7%) !default;
            +
            +
            +//== Badges
            +//
            +//##
            +
            +$badge-color:                 #fff !default;
            +//** Linked badge text color on hover
            +$badge-link-hover-color:      #fff !default;
            +$badge-bg:                    $gray-light !default;
            +
            +//** Badge text color in active nav link
            +$badge-active-color:          $link-color !default;
            +//** Badge background color in active nav link
            +$badge-active-bg:             #fff !default;
            +
            +$badge-font-weight:           bold !default;
            +$badge-line-height:           1 !default;
            +$badge-border-radius:         10px !default;
            +
            +
            +//== Breadcrumbs
            +//
            +//##
            +
            +$breadcrumb-padding-vertical:   40px !default;
            +$breadcrumb-padding-horizontal: 0px !default;
            +//** Breadcrumb background color
            +$breadcrumb-bg:                 transparent !default;
            +//** Breadcrumb text color
            +$breadcrumb-color:              #fff !default;
            +//** Text color of current page in the breadcrumb
            +$breadcrumb-active-color:       #fff !default;
            +//** Textual separator for between breadcrumb elements
            +$breadcrumb-separator:          "/" !default;
            +
            +
            +//== Carousel
            +//
            +//##
            +
            +$carousel-text-shadow:                        none !default;
            +
            +$carousel-control-color:                      #fff !default;
            +$carousel-control-width:                      44px !default;
            +$carousel-control-opacity:                    1 !default;
            +$carousel-control-font-size:                  20px !default;
            +
            +$carousel-indicator-active-bg:                $brand-primary !default;
            +$carousel-indicator-border-color:             $brand-primary !default;
            +
            +$carousel-caption-color:                      #fff !default;
            +
            +
            +//== Close
            +//
            +//##
            +
            +$close-font-weight:           bold !default;
            +$close-color:                 #000 !default;
            +$close-text-shadow:           0 1px 0 #fff !default;
            +
            +
            +//== Code
            +//
            +//##
            +
            +$code-color:                  #c7254e !default;
            +$code-bg:                     #f9f2f4 !default;
            +
            +$kbd-color:                   #fff !default;
            +$kbd-bg:                      #333 !default;
            +
            +$pre-bg:                      #f5f5f5 !default;
            +$pre-color:                   $gray-dark !default;
            +$pre-border-color:            #ccc !default;
            +$pre-scrollable-max-height:   340px !default;
            +
            +
            +//== Type
            +//
            +//##
            +
            +//** Horizontal offset for forms and lists.
            +$component-offset-horizontal: 180px !default;
            +//** Text muted color
            +$text-muted:                  $gray-light !default;
            +//** Abbreviations and acronyms border color
            +$abbr-border-color:           $gray-light !default;
            +//** Headings small color
            +$headings-small-color:        $gray-light !default;
            +//** Blockquote small color
            +$blockquote-small-color:      $gray-light !default;
            +//** Blockquote font size
            +$blockquote-font-size:        ($font-size-base * 1.25) !default;
            +//** Blockquote border color
            +$blockquote-border-color:     $gray-lighter !default;
            +//** Page header border color
            +$page-header-border-color:    $gray-lighter !default;
            +//** Width of horizontal description list titles
            +$dl-horizontal-offset:        $component-offset-horizontal !default;
            +//** Horizontal line color.
            +$hr-border:                   $gray-lighter !default;
            diff --git a/assets/scss/bootstrap/mixins/_clearfix.scss b/assets/scss/bootstrap/mixins/_clearfix.scss
            new file mode 100755
            index 00000000..dc3e2ab4
            --- /dev/null
            +++ b/assets/scss/bootstrap/mixins/_clearfix.scss
            @@ -0,0 +1,22 @@
            +// Clearfix
            +//
            +// For modern browsers
            +// 1. The space content is one way to avoid an Opera bug when the
            +//    contenteditable attribute is included anywhere else in the document.
            +//    Otherwise it causes space to appear at the top and bottom of elements
            +//    that are clearfixed.
            +// 2. The use of `table` rather than `block` is only necessary if using
            +//    `:before` to contain the top-margins of child elements.
            +//
            +// Source: http://nicolasgallagher.com/micro-clearfix-hack/
            +
            +@mixin clearfix() {
            +  &:before,
            +  &:after {
            +    content: " "; // 1
            +    display: table; // 2
            +  }
            +  &:after {
            +    clear: both;
            +  }
            +}
            diff --git a/assets/scss/bootstrap/mixins/_grid-framework.scss b/assets/scss/bootstrap/mixins/_grid-framework.scss
            new file mode 100755
            index 00000000..51f169f2
            --- /dev/null
            +++ b/assets/scss/bootstrap/mixins/_grid-framework.scss
            @@ -0,0 +1,79 @@
            +// Framework grid generation
            +//
            +// Used only by Bootstrap to generate the correct number of grid classes given
            +// any value of `$grid-columns`.
            +
            +// [converter] This is defined recursively in LESS, but Sass supports real loops
            +@mixin make-grid-columns($class,$i: 1, $list: ".col-#{$class}-#{$i}") {
            +  @for $i from (1 + 1) through $grid-columns {
            +    $list: "#{$list}, .col-#{$class}-#{$i}";
            +  }
            +  #{$list} {
            +    position: relative;
            +    // Prevent columns from collapsing when empty
            +    min-height: 1px;
            +    // Inner gutter via padding
            +    padding-left:  ceil(($grid-gutter-width / 2));
            +    padding-right: floor(($grid-gutter-width / 2));
            +  }
            +}
            +
            +
            +// [converter] This is defined recursively in LESS, but Sass supports real loops
            +@mixin float-grid-columns($class, $i: 1, $list: ".col-#{$class}-#{$i}") {
            +  @for $i from (1 + 1) through $grid-columns {
            +    $list: "#{$list}, .col-#{$class}-#{$i}";
            +  }
            +  #{$list} {
            +    float: left;
            +  }
            +}
            +
            +
            +@mixin calc-grid-column($index, $class, $type) {
            +  @if ($type == width) and ($index > 0) {
            +    .col-#{$class}-#{$index} {
            +      width: percentage(($index / $grid-columns));
            +    }
            +  }
            +  @if ($type == push) and ($index > 0) {
            +    .col-#{$class}-push-#{$index} {
            +      left: percentage(($index / $grid-columns));
            +    }
            +  }
            +  @if ($type == push) and ($index == 0) {
            +    .col-#{$class}-push-0 {
            +      left: auto;
            +    }
            +  }
            +  @if ($type == pull) and ($index > 0) {
            +    .col-#{$class}-pull-#{$index} {
            +      right: percentage(($index / $grid-columns));
            +    }
            +  }
            +  @if ($type == pull) and ($index == 0) {
            +    .col-#{$class}-pull-0 {
            +      right: auto;
            +    }
            +  }
            +  @if ($type == offset) {
            +    .col-#{$class}-offset-#{$index} {
            +      margin-left: percentage(($index / $grid-columns));
            +    }
            +  }
            +}
            +
            +// [converter] This is defined recursively in LESS, but Sass supports real loops
            +@mixin loop-grid-columns($columns, $class, $type) {
            +  @for $i from 0 through $columns {
            +    @include calc-grid-column($i, $class, $type);
            +  }
            +}
            +
            +
            +// Create grid for specific class
            +@mixin make-grid($class) {
            +  @include float-grid-columns($class);
            +  @include loop-grid-columns($grid-columns, $class, width);
            +
            +}
            diff --git a/assets/scss/bootstrap/mixins/_grid.scss b/assets/scss/bootstrap/mixins/_grid.scss
            new file mode 100755
            index 00000000..0820258c
            --- /dev/null
            +++ b/assets/scss/bootstrap/mixins/_grid.scss
            @@ -0,0 +1,122 @@
            +// Grid system
            +//
            +// Generate semantic grid columns with these mixins.
            +
            +// Centered container element
            +@mixin container-fixed($gutter: $grid-gutter-width) {
            +  margin-right: auto;
            +  margin-left: auto;
            +  padding-left:  ($gutter / 2);
            +  padding-right: ($gutter / 2);
            +  @include clearfix;
            +}
            +
            +// Creates a wrapper for a series of columns
            +@mixin make-row($gutter: $grid-gutter-width) {
            +  margin-left:  ceil(($gutter / -2));
            +  margin-right: floor(($gutter / -2));
            +  @include clearfix;
            +}
            +
            +// Generate the extra small columns
            +@mixin make-xs-column($columns, $gutter: $grid-gutter-width) {
            +  position: relative;
            +  float: left;
            +  width: percentage(($columns / $grid-columns));
            +  min-height: 1px;
            +  padding-left:  ($gutter / 2);
            +  padding-right: ($gutter / 2);
            +}
            +@mixin make-xs-column-offset($columns) {
            +  margin-left: percentage(($columns / $grid-columns));
            +}
            +@mixin make-xs-column-push($columns) {
            +  left: percentage(($columns / $grid-columns));
            +}
            +@mixin make-xs-column-pull($columns) {
            +  right: percentage(($columns / $grid-columns));
            +}
            +
            +// Generate the small columns
            +@mixin make-sm-column($columns, $gutter: $grid-gutter-width) {
            +  position: relative;
            +  min-height: 1px;
            +  padding-left:  ($gutter / 2);
            +  padding-right: ($gutter / 2);
            +
            +  @media (min-width: $screen-sm-min) {
            +    float: left;
            +    width: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-sm-column-offset($columns) {
            +  @media (min-width: $screen-sm-min) {
            +    margin-left: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-sm-column-push($columns) {
            +  @media (min-width: $screen-sm-min) {
            +    left: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-sm-column-pull($columns) {
            +  @media (min-width: $screen-sm-min) {
            +    right: percentage(($columns / $grid-columns));
            +  }
            +}
            +
            +// Generate the medium columns
            +@mixin make-md-column($columns, $gutter: $grid-gutter-width) {
            +  position: relative;
            +  min-height: 1px;
            +  padding-left:  ($gutter / 2);
            +  padding-right: ($gutter / 2);
            +
            +  @media (min-width: $screen-md-min) {
            +    float: left;
            +    width: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-md-column-offset($columns) {
            +  @media (min-width: $screen-md-min) {
            +    margin-left: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-md-column-push($columns) {
            +  @media (min-width: $screen-md-min) {
            +    left: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-md-column-pull($columns) {
            +  @media (min-width: $screen-md-min) {
            +    right: percentage(($columns / $grid-columns));
            +  }
            +}
            +
            +// Generate the large columns
            +@mixin make-lg-column($columns, $gutter: $grid-gutter-width) {
            +  position: relative;
            +  min-height: 1px;
            +  padding-left:  ($gutter / 2);
            +  padding-right: ($gutter / 2);
            +
            +  @media (min-width: $screen-lg-min) {
            +    float: left;
            +    width: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-lg-column-offset($columns) {
            +  @media (min-width: $screen-lg-min) {
            +    margin-left: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-lg-column-push($columns) {
            +  @media (min-width: $screen-lg-min) {
            +    left: percentage(($columns / $grid-columns));
            +  }
            +}
            +@mixin make-lg-column-pull($columns) {
            +  @media (min-width: $screen-lg-min) {
            +    right: percentage(($columns / $grid-columns));
            +  }
            +}
            diff --git a/assets/scss/bootstrap/mixins/_opacity.scss b/assets/scss/bootstrap/mixins/_opacity.scss
            new file mode 100755
            index 00000000..88e9a576
            --- /dev/null
            +++ b/assets/scss/bootstrap/mixins/_opacity.scss
            @@ -0,0 +1,8 @@
            +// Opacity
            +
            +@mixin opacity($opacity) {
            +  opacity: $opacity;
            +  // IE8 filter
            +  $opacity-ie: ($opacity * 100);
            +  filter: alpha(opacity=$opacity-ie);
            +}
            diff --git a/assets/scss/bootstrap/mixins/_resize.scss b/assets/scss/bootstrap/mixins/_resize.scss
            new file mode 100755
            index 00000000..83fa6379
            --- /dev/null
            +++ b/assets/scss/bootstrap/mixins/_resize.scss
            @@ -0,0 +1,6 @@
            +// Resize anything
            +
            +@mixin resizable($direction) {
            +  resize: $direction; // Options: horizontal, vertical, both
            +  overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
            +}
            diff --git a/assets/scss/bootstrap/mixins/_size.scss b/assets/scss/bootstrap/mixins/_size.scss
            new file mode 100755
            index 00000000..abbe2463
            --- /dev/null
            +++ b/assets/scss/bootstrap/mixins/_size.scss
            @@ -0,0 +1,10 @@
            +// Sizing shortcuts
            +
            +@mixin size($width, $height) {
            +  width: $width;
            +  height: $height;
            +}
            +
            +@mixin square($size) {
            +  @include size($size, $size);
            +}
            diff --git a/assets/scss/bootstrap/mixins/_vendor-prefixes.scss b/assets/scss/bootstrap/mixins/_vendor-prefixes.scss
            new file mode 100755
            index 00000000..df4c1ec8
            --- /dev/null
            +++ b/assets/scss/bootstrap/mixins/_vendor-prefixes.scss
            @@ -0,0 +1,222 @@
            +// Vendor Prefixes
            +//
            +// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
            +// Autoprefixer in our Gruntfile. They will be removed in v4.
            +
            +// - Animations
            +// - Backface visibility
            +// - Box shadow
            +// - Box sizing
            +// - Content columns
            +// - Hyphens
            +// - Placeholder text
            +// - Transformations
            +// - Transitions
            +// - User Select
            +
            +
            +// Animations
            +@mixin animation($animation) {
            +  -webkit-animation: $animation;
            +       -o-animation: $animation;
            +          animation: $animation;
            +}
            +@mixin animation-name($name) {
            +  -webkit-animation-name: $name;
            +          animation-name: $name;
            +}
            +@mixin animation-duration($duration) {
            +  -webkit-animation-duration: $duration;
            +          animation-duration: $duration;
            +}
            +@mixin animation-timing-function($timing-function) {
            +  -webkit-animation-timing-function: $timing-function;
            +          animation-timing-function: $timing-function;
            +}
            +@mixin animation-delay($delay) {
            +  -webkit-animation-delay: $delay;
            +          animation-delay: $delay;
            +}
            +@mixin animation-iteration-count($iteration-count) {
            +  -webkit-animation-iteration-count: $iteration-count;
            +          animation-iteration-count: $iteration-count;
            +}
            +@mixin animation-direction($direction) {
            +  -webkit-animation-direction: $direction;
            +          animation-direction: $direction;
            +}
            +@mixin animation-fill-mode($fill-mode) {
            +  -webkit-animation-fill-mode: $fill-mode;
            +          animation-fill-mode: $fill-mode;
            +}
            +
            +// Backface visibility
            +// Prevent browsers from flickering when using CSS 3D transforms.
            +// Default value is `visible`, but can be changed to `hidden`
            +
            +@mixin backface-visibility($visibility){
            +  -webkit-backface-visibility: $visibility;
            +     -moz-backface-visibility: $visibility;
            +          backface-visibility: $visibility;
            +}
            +
            +// Drop shadows
            +//
            +// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
            +// supported browsers that have box shadow capabilities now support it.
            +
            +@mixin box-shadow($shadow...) {
            +  -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1
            +          box-shadow: $shadow;
            +}
            +
            +// Box sizing
            +@mixin box-sizing($boxmodel) {
            +  -webkit-box-sizing: $boxmodel;
            +     -moz-box-sizing: $boxmodel;
            +          box-sizing: $boxmodel;
            +}
            +
            +// CSS3 Content Columns
            +@mixin content-columns($column-count, $column-gap: $grid-gutter-width) {
            +  -webkit-column-count: $column-count;
            +     -moz-column-count: $column-count;
            +          column-count: $column-count;
            +  -webkit-column-gap: $column-gap;
            +     -moz-column-gap: $column-gap;
            +          column-gap: $column-gap;
            +}
            +
            +// Optional hyphenation
            +@mixin hyphens($mode: auto) {
            +  word-wrap: break-word;
            +  -webkit-hyphens: $mode;
            +     -moz-hyphens: $mode;
            +      -ms-hyphens: $mode; // IE10+
            +       -o-hyphens: $mode;
            +          hyphens: $mode;
            +}
            +
            +// Placeholder text
            +@mixin placeholder($color: $input-color-placeholder) {
            +  // Firefox
            +  &::-moz-placeholder {
            +    color: $color;
            +    opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
            +  }
            +  &:-ms-input-placeholder { color: $color; } // Internet Explorer 10+
            +  &::-webkit-input-placeholder  { color: $color; } // Safari and Chrome
            +}
            +
            +// Transformations
            +@mixin scale($ratio...) {
            +  -webkit-transform: scale($ratio);
            +      -ms-transform: scale($ratio); // IE9 only
            +       -o-transform: scale($ratio);
            +          transform: scale($ratio);
            +}
            +
            +@mixin scaleX($ratio) {
            +  -webkit-transform: scaleX($ratio);
            +      -ms-transform: scaleX($ratio); // IE9 only
            +       -o-transform: scaleX($ratio);
            +          transform: scaleX($ratio);
            +}
            +@mixin scaleY($ratio) {
            +  -webkit-transform: scaleY($ratio);
            +      -ms-transform: scaleY($ratio); // IE9 only
            +       -o-transform: scaleY($ratio);
            +          transform: scaleY($ratio);
            +}
            +@mixin skew($x, $y) {
            +  -webkit-transform: skewX($x) skewY($y);
            +      -ms-transform: skewX($x) skewY($y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
            +       -o-transform: skewX($x) skewY($y);
            +          transform: skewX($x) skewY($y);
            +}
            +@mixin translate($x, $y) {
            +  -webkit-transform: translate($x, $y);
            +      -ms-transform: translate($x, $y); // IE9 only
            +       -o-transform: translate($x, $y);
            +          transform: translate($x, $y);
            +}
            +@mixin translate3d($x, $y, $z) {
            +  -webkit-transform: translate3d($x, $y, $z);
            +          transform: translate3d($x, $y, $z);
            +}
            +@mixin rotate($degrees) {
            +  -webkit-transform: rotate($degrees);
            +      -ms-transform: rotate($degrees); // IE9 only
            +       -o-transform: rotate($degrees);
            +          transform: rotate($degrees);
            +}
            +@mixin rotateX($degrees) {
            +  -webkit-transform: rotateX($degrees);
            +      -ms-transform: rotateX($degrees); // IE9 only
            +       -o-transform: rotateX($degrees);
            +          transform: rotateX($degrees);
            +}
            +@mixin rotateY($degrees) {
            +  -webkit-transform: rotateY($degrees);
            +      -ms-transform: rotateY($degrees); // IE9 only
            +       -o-transform: rotateY($degrees);
            +          transform: rotateY($degrees);
            +}
            +@mixin perspective($perspective) {
            +  -webkit-perspective: $perspective;
            +     -moz-perspective: $perspective;
            +          perspective: $perspective;
            +}
            +@mixin perspective-origin($perspective) {
            +  -webkit-perspective-origin: $perspective;
            +     -moz-perspective-origin: $perspective;
            +          perspective-origin: $perspective;
            +}
            +@mixin transform-origin($origin) {
            +  -webkit-transform-origin: $origin;
            +     -moz-transform-origin: $origin;
            +      -ms-transform-origin: $origin; // IE9 only
            +          transform-origin: $origin;
            +}
            +
            +
            +// Transitions
            +
            +@mixin transition($transition...) {
            +  -webkit-transition: $transition;
            +       -o-transition: $transition;
            +          transition: $transition;
            +}
            +@mixin transition-property($transition-property...) {
            +  -webkit-transition-property: $transition-property;
            +          transition-property: $transition-property;
            +}
            +@mixin transition-delay($transition-delay) {
            +  -webkit-transition-delay: $transition-delay;
            +          transition-delay: $transition-delay;
            +}
            +@mixin transition-duration($transition-duration...) {
            +  -webkit-transition-duration: $transition-duration;
            +          transition-duration: $transition-duration;
            +}
            +@mixin transition-timing-function($timing-function) {
            +  -webkit-transition-timing-function: $timing-function;
            +          transition-timing-function: $timing-function;
            +}
            +@mixin transition-transform($transition...) {
            +  -webkit-transition: -webkit-transform $transition;
            +     -moz-transition: -moz-transform $transition;
            +       -o-transition: -o-transform $transition;
            +          transition: transform $transition;
            +}
            +
            +
            +// User select
            +// For selecting text on the page
            +
            +@mixin user-select($select) {
            +  -webkit-user-select: $select;
            +     -moz-user-select: $select;
            +      -ms-user-select: $select; // IE10+
            +          user-select: $select;
            +}
            diff --git a/assets/scss/cmb2-front.scss b/assets/scss/cmb2-front.scss
            new file mode 100755
            index 00000000..5dda464b
            --- /dev/null
            +++ b/assets/scss/cmb2-front.scss
            @@ -0,0 +1,6 @@
            +@import "bootstrap/variables";
            +@import "bootstrap/mixins";
            +
            + 
            +@import "opalestate/vars";
            +@import "cmb2/cmb2-front";
            \ No newline at end of file
            diff --git a/assets/scss/cmb2/cmb2-display.scss b/assets/scss/cmb2/cmb2-display.scss
            new file mode 100755
            index 00000000..dfed254e
            --- /dev/null
            +++ b/assets/scss/cmb2/cmb2-display.scss
            @@ -0,0 +1 @@
            +@import "partials/display";
            diff --git a/assets/scss/cmb2/cmb2-front.scss b/assets/scss/cmb2/cmb2-front.scss
            new file mode 100755
            index 00000000..bb3318a2
            --- /dev/null
            +++ b/assets/scss/cmb2/cmb2-front.scss
            @@ -0,0 +1,77 @@
            +@import "partials/variables";
            +@import "partials/mixins";
            +
            +
            +
            +
            +// uploader fields //
            +.cmb2-uploader-files {
            +	display:flex;
            +	flex-wrap:wrap;
            +	> div{
            +		width: 180px;
            +		height: 130px;
            +		overflow: hidden;
            +	}
            +	.preview-image{
            +		height: 100%;
            +		img{
            +			height: 100%;
            +		}
            +	}
            +	.button-placehold {	
            +		border:dashed 1px #ebebeb;
            +		cursor: pointer;
            +		text-align: center;
            +		i{
            +			display: block;
            +			font-size: 24px;
            +			margin-bottom: 8px;
            +		}
            +		.button-placehold-content{
            +			position: relative;
            +			top: 50%;
            +			transform: translateY(-50%);
            +		}
            +	}
            +	input.select-file{
            +		display: none;
            +	}
            +}
            +.uploader-item-preview {
            +	position:relative;
            +	.btn-close {
            +		position:absolute;
            +		top:4px;
            +		right:5px;
            +		width:15px;
            +		height:15px;
            +		cursor:pointer;
            +		&:hover::before{
            +			color: red;
            +		}
            +		&::before{
            +			content: '\f00d';
            +			font-family: Fontawesome;
            +			transition: all .3s ease-in-out;
            +		}
            +	}
            +	.preview-icon{
            +		padding-top: 4px;
            +	}
            +}
            +
            +//// 
            +
            +
            +@import "partials/main_wrap";
            +@import "partials/post_metaboxes";
            +@import "partials/context_metaboxes";
            +@import "partials/misc";
            +@import "partials/collapsible_ui";
            +@import "partials/jquery_ui";
            +
            +/**
            + * CMB2 Frontend
            + */
            +@import "partials/front";
            diff --git a/assets/scss/cmb2/cmb2.scss b/assets/scss/cmb2/cmb2.scss
            new file mode 100755
            index 00000000..0fe61352
            --- /dev/null
            +++ b/assets/scss/cmb2/cmb2.scss
            @@ -0,0 +1,12 @@
            +@import "partials/variables";
            +@import "partials/mixins";
            +
            +@import "partials/main_wrap";
            +@import "partials/post_metaboxes";
            +@import "partials/context_metaboxes";
            +@import "partials/options-page";
            +@import "partials/new_term";
            +@import "partials/misc";
            +@import "partials/sidebar_placements";
            +@import "partials/collapsible_ui";
            +@import "partials/jquery_ui";
            diff --git a/assets/scss/cmb2/index.html b/assets/scss/cmb2/index.html
            new file mode 100755
            index 00000000..85fe2db4
            --- /dev/null
            +++ b/assets/scss/cmb2/index.html
            @@ -0,0 +1 @@
            +do not hack here
            \ No newline at end of file
            diff --git a/assets/scss/cmb2/index.php b/assets/scss/cmb2/index.php
            new file mode 100755
            index 00000000..eea59b98
            --- /dev/null
            +++ b/assets/scss/cmb2/index.php
            @@ -0,0 +1,2 @@
            + .cmb-row:first-of-type >,
            +	.cmb-field-list > .cmb-row:first-of-type > {
            +		.cmb-td,
            +		.cmb-th {
            +			border: 0;
            +		}
            +	}
            +}
            +
            +.cmb-add-row {
            +	margin: 1.8em 0 0;
            +}
            +
            +.cmb-nested .cmb-td,
            +.cmb-repeatable-group .cmb-th,
            +.cmb-repeatable-group:first-of-type {
            +	border: 0;
            +}
            +
            +.cmb-row:last-of-type,
            +.cmb2-wrap .cmb-row:last-of-type,
            +.cmb-repeatable-group:last-of-type {
            +	border-bottom: 0;
            +}
            +
            +.cmb-repeatable-grouping {
            +	border: 1px solid $light-gray;
            +	padding: 0 1em;
            +
            +	&.cmb-row {
            +		margin: 0 0 0.8em;
            +	}
            +
            +	+ .cmb-repeatable-grouping {
            +	}
            +}
            +$headings-color: #0a1938;
            +.cmb-th {
            +	color: $headings-color;
            +	float: left;
            +	font-weight: 500;
            +	line-height: 1.2;
            +	padding: 20px 10px 20px 0;
            +	vertical-align: top;
            +	width: 200px;
            +
            +	@media (max-width: $mobile-break) {
            +		@include fullth;
            +	}
            +}
            +
            +.cmb-td {
            +	line-height: 1.3;
            +	max-width: 100%;
            +	padding: 15px 10px;
            +	vertical-align: middle;
            +}
            +
            +.cmb-type-title {
            +
            +	.cmb-td {
            +		padding: 0;
            +	}
            +}
            +
            +.cmb-th label {
            +	display: block;
            +	padding: 5px 0;
            +}
            +
            +.cmb-th + .cmb-td {
            +	float: left;
            +}
            +
            +.cmb-td .cmb-td {
            +	padding-bottom: 1em;
            +}
            +
            +.cmb-remove-row {
            +	text-align: right;
            +}
            +
            +.empty-row.hidden {
            +	display: none;
            +}
            +
            +// Repeatable fields styles
            +.cmb-repeat-table {
            +	background-color: $almostwhite;
            +	border: 1px solid darken($light-gray, 3%);
            +
            +	.cmb-row.cmb-repeat-row {
            +		position: relative;
            +		counter-increment: el;
            +
            +		margin: 0;
            +		padding: 10px 10px 10px 50px;
            +		border-bottom: none !important; // Sometime, we need !important :).
            +
            +		& + .cmb-repeat-row {
            +			border-top: solid 1px $light-gray;
            +		}
            +
            +		&.ui-sortable-helper {
            +			outline: dashed 2px $light-gray !important; // Sometime, we need !important :).
            +		}
            +
            +		&:before {
            +			content: counter(el);
            +			display: block;
            +
            +			top: 0;
            +			left: 0;
            +			position: absolute;
            +
            +			width: 35px;
            +			height: 100%;
            +			line-height: 35px;
            +			cursor: move;
            +			color: $gray;
            +			text-align: center;
            +			border-right: solid 1px $light-gray;
            +		}
            +
            +		.cmb-td {
            +			margin: 0;
            +			padding: 0;
            +		}
            +
            +	}
            +
            +	+ .cmb-add-row {
            +		margin: 0;
            +
            +		&:before {
            +			content: '';
            +			width: 1px;
            +			height: 1.6em;
            +			display: block;
            +			margin-left: 17px;
            +			background-color: darken($light-gray, 5%);
            +		}
            +	}
            +
            +	.cmb-remove-row {
            +		top: 7px;
            +		right: 7px;
            +		position: absolute;
            +
            +		width: auto;
            +		margin-left: 0;
            +		padding: 0 !important; // Sometime, we need !important :).
            +
            +		display: none;
            +
            +		> .cmb-remove-row-button {
            +			font-size: 20px;
            +			text-indent: -1000px;
            +
            +			overflow: hidden;
            +			position: relative;
            +
            +			height: auto;
            +			line-height: 1;
            +			padding: 0 10px 0;
            +
            +			&:before {
            +				@include pseudo-dashicons("\f335");
            +			}
            +		}
            +	}
            +
            +	.cmb-repeat-row:hover .cmb-remove-row {
            +		display: block;
            +	}
            +
            +}
            +
            +.cmb-repeatable-group {
            +
            +	.cmb-th {
            +		padding: 5px;
            +	}
            +
            +	.cmb-group-title {
            +		background-color: $light-gray;
            +		padding: 8px 12px 8px 2.2em;
            +		margin: 0 -1em;
            +		min-height: 1.5em;
            +		font-size: 14px;
            +		line-height: 1.4;
            +
            +		h4 {
            +			border: 0;
            +			margin: 0;
            +			font-size: 1.2em;
            +			font-weight: 500;
            +			padding: 0.5em 0.75em;
            +		}
            +
            +		.cmb-th {
            +			display: block;
            +			width: 100%;
            +		}
            +	}
            +
            +	.cmb-group-description .cmb-th {
            +		@include fullth;
            +	}
            +
            +	.cmb-shift-rows {
            +		font-size: 1em;
            +		margin-right: 1em;
            +		text-decoration: none;
            +
            +		.dashicons {
            +			font-size: 1.5em;
            +			height: 1.5em;
            +			line-height: 1.2em;
            +			width: 1em;
            +
            +			&.dashicons-arrow-down-alt2 {
            +				line-height: 1.3em;
            +
            +			}
            +		}
            +	}
            +
            +	.cmb2-upload-button {
            +		float: right;
            +	}
            +
            +}
            +
            +p.cmb2-metabox-description {
            +	color: $gray;
            +	font-style: italic;
            +	margin: 0;
            +	padding-top: .5em;
            +}
            +
            +span.cmb2-metabox-description {
            +	color: $gray;
            +	font-style: italic;
            +}
            +
            +.cmb2-metabox-title {
            +	margin: 0 0 5px 0;
            +	padding: 5px 0 0 0;
            +	font-size: 14px;
            +}
            +
            +.cmb-inline ul {
            +	padding: 4px 0 0 0;
            +}
            +
            +.cmb-inline li {
            +	display: inline-block;
            +	padding-right: 18px;
            +}
            +
            +.cmb-type-textarea-code pre {
            +	margin: 0;
            +}
            +
            +.cmb2-media-status {
            +
            +	.img-status {
            +		clear: none;
            +		display: inline-block;
            +		vertical-align: middle;
            +		margin-right: 10px;
            +		width: auto;
            +
            +		img {
            +			max-width: 350px;
            +			height: auto;
            +		}
            +	}
            +
            +	.img-status img,
            +	.embed-status {
            +		background: $lightchecker;
            +		border: 5px solid $white;
            +		outline: 1px solid $light-gray;
            +		box-shadow: inset 0 0 15px rgba( 0, 0, 0, 0.3 ), inset 0 0 0 1px rgba( 0, 0, 0, 0.05 );
            +		background-image: linear-gradient(45deg, $darkchecker 25%, transparent 25%, transparent 75%, $darkchecker 75%, $darkchecker), linear-gradient(45deg, $darkchecker 25%, transparent 25%, transparent 75%, $darkchecker 75%, $darkchecker);
            +		background-position: 0 0, 10px 10px;
            +		background-size: 20px 20px;
            +		border-radius: 2px;
            +		-moz-border-radius: 2px;
            + 		margin: 15px 0 0 0;
            +	}
            +
            +	.embed-status {
            +		float: left;
            +		max-width: 800px;
            +	}
            +
            +	.img-status, .embed-status {
            +		position: relative;
            +
            +		.cmb2-remove-file-button {
            +			background: url(../images/ico-delete.png);
            +			height: 16px;
            +			left: -5px;
            +			position: absolute;
            +			text-indent: -9999px;
            +			top: -5px;
            +			width: 16px;
            +		}
            +
            +	}
            +
            +	.img-status {
            +
            +		.cmb2-remove-file-button {
            +			top: 10px;
            +		}
            +	}
            +
            +	.img-status img, .file-status > span {
            +		cursor: pointer;
            +	}
            +
            +	&.cmb-attach-list {
            +		.img-status img, .file-status > span {
            +			cursor: move;
            +		}
            +	}
            +
            +}
            +
            +.cmb-type-file-list .cmb2-media-status .img-status {
            +	clear: none;
            +	vertical-align: middle;
            +	width: auto;
            +	margin-right: 10px;
            +	margin-bottom: 10px;
            +	margin-top: 0;
            +}
            +
            +.cmb-attach-list li {
            +	clear: both;
            +	display: inline-block;
            +	width: 100%;
            +	margin-top: 5px;
            +	margin-bottom: 10px;
            +	img {
            +		float: left;
            +		margin-right: 10px;
            +	}
            +}
            +
            +.cmb2-remove-wrapper {
            +	margin: 0;
            +}
            +
            +.child-cmb2 .cmb-th {
            +	text-align: left;
            +}
            +
            +.cmb2-indented-hierarchy {
            +	padding-left: 1.5em;
            +}
            +
            +@media (max-width: $mobile-break) {
            +	.cmb-th,
            +	.cmb-td,
            +	.cmb-th + .cmb-td {
            +		display: block;
            +		float: none;
            +		width: 100%;
            +	}
            +}
            +.opalestate-submission-form {
            +	position: relative;
            +	.cmb-td{
            +		width: 100%;
            +		padding: 15px 0;
            +	}
            +	.cmb-th{
            +		width: 100%;
            +		padding-bottom: 0;
            +		padding-top: 15px;
            +		label{
            +			margin: 0;
            +			padding: 0;
            +		}
            +	}
            +	span.cmb2-metabox-description{
            +		padding-top: .5em;
            +		display: block;
            +	}
            +	.cmb2-wrap{
            +		input.cmb2-text-medium, input.cmb2-text-small{
            +			width: 100%;
            +		}
            +	}
            +	.opalestate-tab-content{
            +		&::after{
            +			content: '';
            +			display: block;
            +			clear: both;
            +		}
            +	}
            +	.submission-next-btn{
            +		@media screen and (min-width:768px){
            +			float: right;
            +		}
            +	}
            +	.btn-submit-cmb{
            +		position: absolute;
            +		bottom: 0px;
            +		right: 0px;
            +		padding: 19px 25px 17px 20px;
            +		@media screen and (max-width:767px){
            +			position: relative;
            +			bottom: 0;
            +			right: 0;
            +			margin-top: 15px;
            +		}
            +		&::before{
            +			content: "\f138";
            +			font-family: Fontawesome;
            +			margin-right: 18px;
            +			padding-right: 20px;
            +		}
            +		&::after{
            +			content: "";
            +			width: 52px;
            +			position: absolute;
            +			top: 0;
            +			left: 0;
            +			height: 100%;
            +			background-color: transparent;
            +			-webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +			box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +		}
            +	}
            +	.submission-back-btn,.submission-next-btn,.submission-next-btn{
            +		margin-top: 15px;
            +	}
            +	.cmb-repeatable-group{
            +		.cmb-group-title{
            +			font-size: 15px;
            +		}
            +	} 
            +	.cmb2-metabox{
            +		button.dashicons-before.dashicons-no-alt.cmb-remove-group-row{
            +			top: .4em;
            +		}
            +	}
            +	
            +	.cmb-type-group{
            +		.field-row-2{
            +			.cmb-row{
            +				border-bottom: none;
            +				margin-bottom: 0;
            +				padding-bottom: 0;
            +			}
            +		} 
            +		.cmb-row{
            +			padding-top: 15px;
            +			padding-bottom: 15px;
            +			margin-bottom: 15px;
            +			&.postbox{
            +				padding-top: 0;
            +				border-bottom: 1px solid #e9e9e9;
            +			}
            +		}
            +		.cmb-th{
            +			width: 100%;
            +			padding: 0;
            +			float: none;
            +			& + .cmb-td{
            +				width: 100%;
            +				float: none;
            +				padding: 15px 0;
            +			}
            +		}
            +	}
            +	
            +}
            diff --git a/assets/scss/cmb2/partials/_misc.scss b/assets/scss/cmb2/partials/_misc.scss
            new file mode 100755
            index 00000000..b9fbc03e
            --- /dev/null
            +++ b/assets/scss/cmb2/partials/_misc.scss
            @@ -0,0 +1,29 @@
            +/*--------------------------------------------------------------
            + * Misc.
            +--------------------------------------------------------------*/
            +
            +#poststuff .cmb-repeatable-group h2 {
            +	margin: 0;
            +}
            +
            +.edit-tags-php,
            +.profile-php,
            +.user-edit-php {
            +	.cmb2-metabox-title {
            +		font-size: 1.4em;
            +	}
            +}
            +
            +.cmb2-postbox, .cmb2-no-box-wrap {
            +	.cmb-spinner {
            +		float: left;
            +		display: none;
            +	}
            +}
            +
            +.cmb-spinner {
            +	display: none;
            +	&.is-active {
            +		display: block;
            +	}
            +}
            diff --git a/assets/scss/cmb2/partials/_mixins.scss b/assets/scss/cmb2/partials/_mixins.scss
            new file mode 100755
            index 00000000..7c1d00fe
            --- /dev/null
            +++ b/assets/scss/cmb2/partials/_mixins.scss
            @@ -0,0 +1,51 @@
            +//--------------------------------------------------------------
            +// Mixins
            +//--------------------------------------------------------------
            +
            +@mixin fullth() {
            +	font-size: 1.2em;
            +	@include _fullth;
            +}
            +
            +@mixin fullth_side() {
            +
            +	@include _fullth;
            +
            +	label {
            +		font-size: $font-size;
            +		line-height: 1.4em;
            +	}
            +}
            +
            +@mixin _fullth() {
            +	display: block;
            +	float: none;
            +	padding-bottom: 1em;
            +	text-align: left;
            +	width: 100%;
            +
            +	label {
            +		display: block;
            +		margin-top: 0;
            +		margin-bottom: 0.5em;
            +	}
            +}
            +
            +@mixin pseudo-dashicons( $glyph: "\f333" ) {
            +	content: $glyph;
            +	font-family: 'Dashicons';
            +	speak: none;
            +	font-weight: normal;
            +	font-variant: normal;
            +	text-transform: none;
            +	line-height: 1;
            +	-webkit-font-smoothing: antialiased;
            +	margin: 0;
            +	text-indent: 0;
            +	position: absolute;
            +	top: 0;
            +	left: 0;
            +	width: 100%;
            +	height: 100%;
            +	text-align: center;
            +}
            diff --git a/assets/scss/cmb2/partials/_new_term.scss b/assets/scss/cmb2/partials/_new_term.scss
            new file mode 100755
            index 00000000..33a13f32
            --- /dev/null
            +++ b/assets/scss/cmb2/partials/_new_term.scss
            @@ -0,0 +1,31 @@
            +/*--------------------------------------------------------------
            + * New-Term Page
            +--------------------------------------------------------------*/
            +
            +#addtag {
            +	.cmb-th {
            +		float: none;
            +		width: auto;
            +		padding: 20px 0 0;
            +	}
            +
            +	.cmb-td {
            +		padding: 0;
            +	}
            +
            +	.cmb-th + .cmb-td {
            +		float: none;
            +	}
            +
            +	select {
            +		max-width: 100%;
            +	}
            +
            +	.cmb2-metabox {
            +		padding-bottom: 20px;
            +	}
            +
            +	.cmb-row li label {
            +		display: inline;
            +	}
            +}
            \ No newline at end of file
            diff --git a/assets/scss/cmb2/partials/_options-page.scss b/assets/scss/cmb2/partials/_options-page.scss
            new file mode 100755
            index 00000000..442ca143
            --- /dev/null
            +++ b/assets/scss/cmb2/partials/_options-page.scss
            @@ -0,0 +1,71 @@
            +/*--------------------------------------------------------------
            + * Options page
            +--------------------------------------------------------------*/
            +
            +.cmb2-options-page {
            +	max-width: 1200px;
            +
            +	&.wrap > h2 {
            +		margin-bottom: 1em;
            +	}
            +
            +	.cmb2-metabox > .cmb-row {
            +		padding: 1em;
            +		margin-top: -1px;
            +		background: $white;
            +		border: 1px solid $light-gray;
            +		box-shadow: 0 1px 1px rgba(black, 0.05);
            +
            +		> .cmb-th {
            +			padding: 0;
            +			font-weight: initial;
            +		}
            +
            +		> .cmb-th + .cmb-td {
            +			float: none;
            +			padding: 0 0 0 1em;
            +			margin-left: 200px;
            +
            +			@media (max-width: $mobile-break) {
            +				padding: 0;
            +				margin-left: 0;
            +			}
            +		}
            +	}
            +
            +	// Title field style.
            +	.cmb2-wrap .cmb-type-title {
            +		margin-top: 1em;
            +		padding: 0.6em 1em;
            +		background-color: $almostwhite;
            +
            +		.cmb2-metabox-title {
            +			font-size: 12px;
            +			margin-top: 0;
            +			margin-bottom: 0;
            +			text-transform: uppercase;
            +		}
            +
            +		.cmb2-metabox-description {
            +			padding-top: 0.25em;
            +		}
            +	}
            +
            +	.cmb-repeatable-group {
            +		.cmb-group-description .cmb-th {
            +			padding: 0 0 0.8em 0;
            +		}
            +
            +		.cmb-group-name {
            +			font-size: 16px;
            +			margin-top: 0;
            +			margin-bottom: 0;
            +		}
            +
            +		.cmb-th > .cmb2-metabox-description {
            +			font-weight: 400;
            +			padding-bottom: 0 !important;
            +		}
            +	}
            +
            +}
            diff --git a/assets/scss/cmb2/partials/_post_metaboxes.scss b/assets/scss/cmb2/partials/_post_metaboxes.scss
            new file mode 100755
            index 00000000..c3f4510c
            --- /dev/null
            +++ b/assets/scss/cmb2/partials/_post_metaboxes.scss
            @@ -0,0 +1,84 @@
            +/*--------------------------------------------------------------
            + * Post Metaboxes
            +--------------------------------------------------------------*/
            +
            +#poststuff .cmb-group-title {
            +	margin-left: -1em;
            +	margin-right: -1em;
            +	min-height: 1.5em;
            +}
            +
            +#poststuff .repeatable .cmb-group-title {
            +	padding-left: 2.2em;
            +}
            +
            +.cmb2-postbox, .cmb-type-group {
            +
            +	.cmb2-wrap {
            +		margin: 0;
            +
            +		> .cmb-field-list > .cmb-row {
            +			padding: 1.8em 0;
            +		}
            +
            +		input[type=text] {
            +
            +			&.cmb2-oembed {
            +				width: 100%;
            +			}
            +		}
            +	}
            +
            +	.cmb-row {
            +		padding: 0 0 1.8em;
            +		margin: 0 0 0.8em;
            +
            +		.cmbhandle {
            +			right: -1em;
            +			position: relative;
            +			color: $dark-gray;
            +		}
            +	}
            +
            +	.cmb-repeatable-grouping {
            +		padding: 0 1em;
            +		max-width: 100%;
            +		min-width: 1px !important;
            +	}
            +
            +	.cmb-repeatable-group > .cmb-row {
            +		padding-bottom: 0;
            +	}
            +
            +	.cmb-th {
            +		width: 18%;
            +		padding: 0 2% 0 0;
            +		// text-align: right;
            +	}
            +
            +	.cmb-td {
            +		margin-bottom: 0;
            +		padding: 0;
            +		line-height: 1.3;
            +	}
            +
            +	.cmb-th + .cmb-td {
            +		width: 80%;
            +		float: right;
            +	}
            +
            +	.cmb-row:not(:last-of-type),
            +	.cmb-repeatable-group:not(:last-of-type) {
            +		border-bottom: 1px solid $light-gray;
            +
            +		@media (max-width: $mobile-break) {
            +			border-bottom: 0;
            +		}
            +	}
            +
            +	.cmb-repeat-group-field,
            +	.cmb-remove-field-row {
            +		padding-top: 1.8em;
            +	}
            +
            +}
            diff --git a/assets/scss/cmb2/partials/_sidebar_placements.scss b/assets/scss/cmb2/partials/_sidebar_placements.scss
            new file mode 100755
            index 00000000..e69de29b
            diff --git a/assets/scss/cmb2/partials/_variables.scss b/assets/scss/cmb2/partials/_variables.scss
            new file mode 100755
            index 00000000..34621c21
            --- /dev/null
            +++ b/assets/scss/cmb2/partials/_variables.scss
            @@ -0,0 +1,25 @@
            +//--------------------------------------------------------------
            +// Variables
            +//--------------------------------------------------------------
            +
            +// Mobile break-point
            +$mobile-break : 450px;
            +
            +// Fonts
            +$font-sans    : sans-serif;
            +$font-serif   : Georgia, Times, "Times New Roman", serif;
            +$font-mono    : "Courier 10 Pitch", Courier, monospace;
            +$font-size    : 14px;
            +
            +// Colors
            +$dark-gray    : #222222;
            +$gray         : #757575;
            +$light-gray   : #e9e9e9;
            +$lightchecker : #eee;
            +$darkchecker  : #d0d0d0;
            +$blue         : #0063ce;
            +$light-yellow : #fffff8;
            +$white        : #ffffff;
            +$almostwhite  : #fafafa;
            +$red          : #f00;
            +$dark-red     : #a00;
            diff --git a/assets/scss/cmb2/partials/index.php b/assets/scss/cmb2/partials/index.php
            new file mode 100755
            index 00000000..eea59b98
            --- /dev/null
            +++ b/assets/scss/cmb2/partials/index.php
            @@ -0,0 +1,2 @@
            + .box-heading {
            +    color: $heading-text-color;
            +    background-color: $heading-bg-color;
            +    border-color: $heading-border;
            +
            +    +  .box-content {
            +      border-top-color: $border;
            +    }
            +  }
            +  & > .box-content{
            +      border-color:$border;
            +  }
            +  & > .box-footer {
            +    + .box-collapse .box-body {
            +      border-bottom-color: $border;
            +    }
            +  }
            +}
            +@mixin button-3d($suffixclass, $height3d ,$color3d){
            +  border: 0;
            +  @if ($suffixclass == "empty") {
            +      box-shadow: 0 $height3d $color3d inset;
            +      -o-box-shadow: 0 $height3d $color3d inset;
            +      -moz-box-shadow: 0 $height3d $color3d inset;
            +      -webkit-box-shadow: 0 $height3d $color3d inset;
            +      -ms-box-shadow: 0 $height3d $color3d inset;
            +  }
            +  @else {
            +  &.btn-#{$suffixclass}{
            +     box-shadow: 0 $height3d $color3d inset;
            +      -o-box-shadow: 0 $height3d $color3d inset;
            +      -moz-box-shadow: 0 $height3d $color3d inset;
            +      -webkit-box-shadow: 0 $height3d $color3d inset;
            +      -ms-box-shadow: 0 $height3d $color3d inset;
            +    }
            +  }
            +}
            +
            +@mixin button-inverse( $suffixclass,  $color ,$background ){
            + 
            +  &.btn-#{$suffixclass}{
            +      &:hover{ 
            +        color:$color;
            +        background:transparent;
            +      }
            +  }
            +}
            +
            +@mixin button-outline( $suffixclass, $color, $hovercolor ){
            +  background:transparent;
            +  &.btn-#{$suffixclass}{
            +      color:$color;
            +      &:hover{
            +          color:$hovercolor;
            +      }
            +  }
            +}
            +/// button variant outline
            +@mixin button-variant-outline($color, $background, $border, $colorhover, $bghover, $borderhover ) {
            +  color: $color;
            +  background-color: $background;
            +  border-color: $border;
            +
            +  &:hover,
            +  &:focus,
            +  &:active,
            +  &.active {
            +    color: $colorhover;
            +    background-color: $bghover;
            +        border-color: $borderhover ;
            +  }
            +  .open & { &.dropdown-toggle {
            +    color: $colorhover;
            +    background-color: $bghover;
            +        border-color: $borderhover ;
            +  } }
            +  &:active,
            +  &.active {
            +    background-image: none;
            +  }
            +  .open & { &.dropdown-toggle {
            +    background-image: none;
            +  } }
            +  &.disabled,
            +  &[disabled],
            +  fieldset[disabled] & {
            +    &,
            +    &:hover,
            +    &:focus,
            +    &:active,
            +    &.active {
            +      background-color: $background;
            +          border-color: $border;
            +    }
            +  }
            +
            +  .badge {
            +    color: $background;
            +    background-color: $color;
            +  }
            +}
            +// icon variant inverse
            +
            +@mixin icons-inverse( $suffixclass,  $color ,$background ){
            + 
            +  &.icons-#{$suffixclass}{
            +      &:hover{ 
            +        color:$color;
            +        background:transparent;
            +      }
            +  }
            +}
            +// icon variant outline
            +
            +@mixin icons-outline( $suffixclass, $color, $hovercolor ){
            +  &.icons-#{$suffixclass}{
            +  background:transparent;
            +      color:$color;
            +      &:hover{
            +          color:$hovercolor;
            +      }
            +  }
            +}
            +
            +// Block
            +// -------------------------
            +@mixin block-variant($border, $heading-text-color, $heading-bg-color, $heading-border) {
            +  
            +  border: solid 1px $border;
            +
            +  & .#{$block-heading-selector} {
            +    + .#{$block-prefix}-collapse .#{$block-content-selector} {
            +      border-top-color: $border;
            +    }
            +  }
            +  & > .#{$block-prefix}-footer {
            +    + .#{$block-prefix}-collapse .#{$block-prefix}-body {
            +      border-bottom-color: $border;
            +    }
            +  }
            +}
            +
            +/****/
            +/****/
            +@mixin container-layout-variant($color, $background, $linkcolor ){
            +    background: $background;
            +    color: $color;
            +    a{
            +      color:$linkcolor; 
            +      &:hover{
            +        color: $theme-color; 
            +      }  
            +    }         
            +}
            +
            +@mixin widget-heading-style(){
            +     font-size: 36px;
            +      position: relative;
            +      text-align: center;
            +      padding-bottom: 35px;
            +      text-transform: uppercase;
            +      margin-top: 0;
            +      margin-bottom: 40px;
            +      &.style-2 {
            +        font-size: 20px;
            +        margin-bottom: 20px;
            +        @include rtl-text-align-left();
            +        padding-bottom: 0;
            +        .widget-heading {
            +          font-size: 20px;
            +          > span:first-child {
            +            position: relative;
            +            margin-bottom: 20px;
            +            padding-bottom: 15px;
            +            display: block;
            +            &:before {
            +              content: "";
            +              background-color: $theme-color;
            +              @include size(40px,1px);
            +              position: absolute;
            +              bottom: 0;
            +              @include rtl-left(0px);
            +            }
            +          }
            +          .description {
            +            font-size: 18px;
            +            font-family: $font-family-base;
            +            color: $black;
            +            line-height: 30px;
            +          }
            +        }
            +        &:before,
            +        &:after {
            +          content: none;
            +        }
            +        @media screen and (max-width: $screen-xs-max) {
            +          margin-top: 20px;
            +        }
            +      }
            +      &.style-3 {
            +        text-transform: none;
            +        padding-bottom: 0;
            +        .description {
            +          margin: 15px 23% 0;
            +        }
            +        &:before,
            +        &:after {
            +          content: none;
            +        }
            +      }
            +      &.style-4 {
            +        background: url('#{$image-theme-path}heading-title-bg.png') no-repeat center bottom;
            +        .widget-heading {
            +          color: $white;
            +          .description {
            +            &:after {
            +              content: none;
            +            }
            +          }
            +        }
            +        &:before {
            +          content: none;
            +        }
            +        &:after {
            +          background-color: transparent;
            +        }
            +      }
            +      &:before {
            +        content: "";
            +        width: 156px;
            +        height: 1px;
            +        background-color: #d3d3d3;
            +        position: absolute;
            +        bottom: 0;
            +        @include rtl-left(50%);
            +        @include rtl-margin-left(-78px);
            +      }
            +      &:after {
            +        content: "";
            +        border: 2px solid $theme-color;
            +        @include border-radius(2px);
            +        @include rotate(45deg);
            +        position: absolute;
            +        bottom:-5px;
            +        @include rtl-left(50%);
            +        @include square(12px);
            +        z-index: 1;
            +        @include rtl-margin-left(-6px);
            +        background-color: $white;
            +      }
            +      .widget-heading {
            +        margin: 0;
            +        font-size: 36px;
            +        @media screen and (max-width: 979px) {
            +          font-size: 30px;
            +        }
            +        @media screen and (max-width: $screen-xs-min) {
            +          font-size: 24px;
            +        }
            +      }
            +      .description, .widget-desc{
            +          display: block;
            +          font-size: 18px;
            +          font-style: italic;
            +          color: $light-gray;
            +          font-weight: 400;
            +          text-transform: none;
            +          font-family: $font-family-base;
            +          margin: 10px 0 0;
            +          line-height: 1.4;
            +          &:after {
            +            content: "";
            +            @include size(50px,1px);
            +            background-color: $body-bg;
            +            position: absolute;
            +            bottom: 0;
            +            @include rtl-left(50%);
            +            @include rtl-margin-left(-25px);
            +          }
            +      }
            +      @media screen and (max-width: 979px) {
            +        font-size: 30px;
            +        padding-bottom: 25px;
            +        margin-bottom: 30px;
            +      }
            +}
            +
            +@mixin widget-specical-style(){
            +  margin-bottom: 40px;
            +  @include widget-heading-style();
            +  &.text-white {
            +    .widget-heading {
            +      color: $white;
            +      &:after {
            +        background-color: $white;
            +      }
            +    }    
            +  }
            +}
            \ No newline at end of file
            diff --git a/assets/scss/components/mixins/_rtl.scss b/assets/scss/components/mixins/_rtl.scss
            new file mode 100755
            index 00000000..c8b2fcff
            --- /dev/null
            +++ b/assets/scss/components/mixins/_rtl.scss
            @@ -0,0 +1,259 @@
            +// Support for RTL (Right to Left) & non-latin fonts
            +
            +$rtl-left : left;
            +$rtl-right : right;
            +$rtl-center: center;
            +
            +// BASIC CONVERTER (ignore these)
            +
            +@mixin rtl-base-simple ($property, $direction) {
            +  #{$property}:$direction;
            +  .rtl & {
            +    @if $direction == $rtl-right {
            +      #{$property}:$rtl-left;
            +    }
            +    @else {
            +      #{$property}:$rtl-right;
            +    }
            +  }
            +}
            +@mixin rtl-base-inherit ($property, $direction, $value, $inherit : inherit) {
            +  #{$property}-#{$direction}: $value;
            +  .rtl & {
            +    @if $direction == $rtl-right {
            +      #{$property}-#{$rtl-left}: $value;
            +    }
            +    @else {
            +      #{$property}-#{$rtl-right}: $value;
            +    }
            +    #{$property}-#{$direction}: $inherit;
            +  }
            +}
            +
            +@mixin rtl-base-toprightbottomleft ($property, $t, $r, $b, $l) {
            +  #{$property}: $t $r $b $l;
            +  .rtl & {
            +    #{$property}: $t $l $b $r;
            +  }
            +}
            +
            +// BODY STYLES
            +@mixin rtl-direction ($forBody : true) {
            +  direction: ltr;
            +  @if $forBody {
            +    &.rtl {
            +      direction: rtl;
            +    }
            +  }
            +  @else {
            +    .rtl & {
            +      direction: rtl;
            +    }
            +  }
            +}
            +
            +@mixin rtl-font-family ($ltr, $rtl, $forBody : false) {
            +  font-family: $ltr;
            +  @if $forBody {
            +    &.rtl, &.non-latin {
            +      font-family:$rtl;
            +    }
            +  }
            +  @else {
            +    .rtl &, .non-latin & {
            +      font-family:$rtl;
            +    }
            +  }
            +}
            +
            +
            +// MARGIN
            +
            +@mixin rtl-margin ($t, $r, $b, $l) {
            +  @include rtl-base-toprightbottomleft(margin,$t, $r, $b, $l);
            +}
            +@mixin rtl-margin-left ($value) {
            +  @include rtl-base-inherit(margin,$rtl-left,$value);
            +}
            +@mixin rtl-margin-right ($value) {
            +  @include rtl-base-inherit(margin,$rtl-right,$value);
            +}
            +
            +// PADDING
            +
            +@mixin rtl-padding ($t, $r, $b, $l) {
            +  @include rtl-base-toprightbottomleft(padding,$t, $r, $b, $l);
            +}
            +@mixin rtl-padding-left ($value) {
            +  @include rtl-base-inherit(padding,$rtl-left,$value);
            +}
            +@mixin rtl-padding-right ($value) {
            +  @include rtl-base-inherit(padding,$rtl-right,$value);
            +}
            +
            +// BORDER
            +
            +@mixin rtl-border-left ($value) {
            +  @include rtl-base-inherit(border,$rtl-left,$value);
            +}
            +@mixin rtl-border-right ($value) {
            +  @include rtl-base-inherit(border,$rtl-right,$value);
            +}
            +
            +// POSITION
            +
            +@mixin rtl-left ($value) {
            +  #{$rtl-left}: $value;
            +  .rtl & {
            +    #{$rtl-right}: $value;
            +    #{$rtl-left}: auto;
            +  }
            +}
            +@mixin rtl-right ($value) {
            +  #{$rtl-right}: $value;
            +  .rtl & {
            +    #{$rtl-left}: $value;
            +    #{$rtl-right}: auto;
            +  }
            +}
            +
            +
            +// CLEAR
            +
            +@mixin rtl-clear-left () {
            +  @include rtl-base-simple(clear, $rtl-left);
            +}
            +@mixin rtl-clear-right () {
            +  @include rtl-base-simple(clear, $rtl-right);
            +}
            +
            +// TEXT-ALIGN
            +
            +@mixin rtl-text-align-left () {
            +  @include rtl-base-simple(text-align, $rtl-left);
            +}
            +@mixin rtl-text-align-right () {
            +  @include rtl-base-simple(text-align, $rtl-right);
            +}
            +@mixin rtl-text-align-center () {
            +  @include rtl-base-simple(text-align, $rtl-center);
            +}
            +
            +// FLOAT
            +
            +@mixin rtl-float-left () {
            +  @include rtl-base-simple(float, $rtl-left);
            +}
            +@mixin rtl-float-right () {
            +  @include rtl-base-simple(float, $rtl-right);
            +}
            +
            +// BACKGROUND-POSITION
            +
            +@mixin rtl-background-position-left ($vertical) {
            +  background-position:$rtl-left $vertical;
            +  .rtl & {
            +    background-position:$rtl-right $vertical;
            +  }
            +}
            +@mixin rtl-background-position-right ($vertical) {
            +  background-position:$rtl-right $vertical;
            +  .rtl & {
            +    background-position:$rtl-left $vertical;
            +  }
            +}
            +
            +@mixin rtl-background-position-percent ($vertical, $horPercent) {
            +  background-position:$horPercent $vertical;
            +  .rtl & {
            +    background-position:100% - $horPercent $vertical;
            +  }
            +}
            +
            +// TEXT-SHADOW & BOX-SHADOW
            +
            +@mixin rtl-text-shadow ($x, $rest) {
            +  text-shadow: $x $rest;
            +  .rtl & {
            +    text-shadow: -1 * $x $rest;
            +  }
            +}
            +@mixin rtl-box-shadow ($x, $rest) {
            +  -moz-box-shadow: $x $rest;
            +  -webkit-box-shadow: $x $rest;
            +  box-shadow: $x $rest;
            +  .rtl & {
            +    -moz-box-shadow: -1 * $x $rest;
            +    -webkit-box-shadow: -1 * $x $rest;
            +    box-shadow: -1 * $x $rest;
            +  }
            +}
            +
            +// BORDER-RADIUS
            +
            +@mixin rtl-border-radius-topright ($tl, $tr, $br, $bl) {
            +  -moz-border-radius: $tl, $tr, $br, $bl;
            +  -webkit-border-radius: $tl, $tr, $br, $bl;
            +  border-top-radius: $tl, $tr, $br, $bl;
            +  .rtl & {
            +    -moz-border-radius: $tr, $tl, $bl, $br;
            +    -webkit-border-radius: $tr, $tl, $bl, $br;
            +    border-top-radius: $tr, $tl, $bl, $br;
            +  }
            +}
            +
            +@mixin rtl-border-radius-topright ($value) {
            +  -moz-border-radius-top#{$rtl-right}: $value;
            +  -webkit-border-top-#{$rtl-right}-radius: $value;
            +  border-top-#{$rtl-right}-radius: $value;
            +  .rtl & {
            +    -moz-border-radius-top#{$rtl-left}: $value;
            +    -webkit-border-top-#{$rtl-left}-radius: $value;
            +    border-top-#{$rtl-left}-radius: $value;
            +    -moz-border-radius-top#{$rtl-right}: inherit;
            +    -webkit-border-top-#{$rtl-right}-radius: inherit;
            +    border-top-#{$rtl-right}-radius: inherit;
            +  }
            +}
            +
            +@mixin rtl-border-radius-bottomright ($value) {
            +  -moz-border-radius-bottom#{$rtl-right}: $value;
            +  -webkit-border-bottom-#{$rtl-right}-radius: $value;
            +  border-bottom-#{$rtl-right}-radius: $value;
            +  .rtl & {
            +    -moz-border-radius-bottom#{$rtl-left}: $value;
            +    -webkit-border-bottom-#{$rtl-left}-radius: $value;
            +    border-bottom-#{$rtl-left}-radius: $value;
            +    -moz-border-radius-bottom#{$rtl-right}: inherit;
            +    -webkit-border-bottom-#{$rtl-right}-radius: inherit;
            +    border-bottom-#{$rtl-right}-radius: inherit;
            +  }
            +}
            +
            +@mixin rtl-border-radius-topleft ($value) {
            +  -moz-border-radius-top#{$rtl-left}: $value;
            +  -webkit-border-top-#{$rtl-left}-radius: $value;
            +  border-top-#{$rtl-left}-radius: $value;
            +  .rtl & {
            +    -moz-border-radius-top#{$rtl-right}: $value;
            +    -webkit-border-top-#{$rtl-right}-radius: $value;
            +    border-top-#{$rtl-right}-radius: $value;
            +    -moz-border-radius-top#{$rtl-left}: inherit;
            +    -webkit-border-top-#{$rtl-left}-radius: inherit;
            +    border-top-#{$rtl-left}-radius: inherit;
            +  }
            +}
            +
            +@mixin rtl-border-radius-bottomleft ($value) {
            +  -moz-border-radius-bottom#{$rtl-left}: $value;
            +  -webkit-border-bottom-#{$rtl-left}-radius: $value;
            +  border-bottom-#{$rtl-left}-radius: $value;
            +  .rtl & {
            +    -moz-border-radius-bottom#{$rtl-right}: $value;
            +    -webkit-border-bottom-#{$rtl-right}-radius: $value;
            +    border-bottom-#{$rtl-right}-radius: $value;
            +    -moz-border-radius-bottom#{$rtl-left}: inherit;
            +    -webkit-border-bottom-#{$rtl-left}-radius: inherit;
            +    border-bottom-#{$rtl-left}-radius: inherit;
            +  }
            +}
            diff --git a/assets/scss/components/mixins/_template-mixins.scss b/assets/scss/components/mixins/_template-mixins.scss
            new file mode 100755
            index 00000000..b98348b0
            --- /dev/null
            +++ b/assets/scss/components/mixins/_template-mixins.scss
            @@ -0,0 +1,278 @@
            +// Box Size
            +// -------------------------
            +@mixin box-size($background, $padding-top,$padding-bottom){
            +    background: $background;
            +    padding-top: $padding-top;
            +    padding-bottom: $padding-bottom;
            +}
            +
            +// Button
            +// -------------------------
            +@mixin button-outline($color, $background, $border, $background-hover, $color-hover, $border-hover, $border-radius) {
            +    color: $color;
            +    background-color: $background;
            +    border: $border;
            +    @include border-radius($border-radius);
            +    &:hover,
            +    &:focus,
            +    &:active,
            +    &.active {
            +        color: $color-hover;
            +        background-color: $background-hover;
            +        border: $border-hover;
            +    }
            +    .fa,.icon{
            +        font-size: $icon-font-size-base;
            +        margin: 0;
            +    }
            +}
            +
            +// Block
            +// -------------------------
            +@mixin block-variant($border, $heading-text-color, $heading-bg-color, $heading-border) {
            +    border-color: $border;
            +    background: $heading-bg-color;
            +    & .#{$block-heading-selector} {
            +        & span:before, & span:after{ background:$white; }
            +        color: $heading-text-color;
            +        background-color: $heading-bg-color;
            +        border-color: $heading-border;
            +        + .#{$block-prefix}-collapse .#{$block-content-selector} {
            +            border-top-color: $border;
            +        }
            +    }
            +    & > .#{$block-prefix}-footer {
            +        + .#{$block-prefix}-collapse .#{$block-prefix}-body {
            +            border-bottom-color: $border;
            +        }
            +    }
            +}
            +
            +@mixin block-elements-styles($border, $heading-text-color, $heading-bg-color, $heading-border, $text-color, $text-color-primary){
            +    border-color: $border;
            +    background: $heading-bg-color;
            +    & .#{$block-heading-selector} {
            +        color: $heading-text-color;
            +        background-color: $heading-bg-color;
            +        border-color: $heading-border;
            +        + .#{$block-prefix}-collapse .#{$block-content-selector} {
            +            border-top-color: $border;
            +        }
            +    }
            +    & > .#{$block-prefix}-footer {
            +        + .#{$block-prefix}-collapse .#{$block-prefix}-body {
            +            border-bottom-color: $border;
            +        }
            +    }
            +}
            +
            +/****/
            +@mixin container-layout-variant($color, $background, $linkcolor,  $topbar-link-color-hover ){
            +    background: $background;
            +    color: $color;
            +    a{
            +        color:$linkcolor;
            +    }
            +    a:hover{
            +        color: $topbar-link-color-hover;
            +    }
            +}
            +
            +//== Inline block
            +//==========================================
            +@mixin inline-block ($haslayout : true){
            +    display: inline-block;
            +    vertical-align: middle;
            +    @if $haslayout == true {
            +        .lt-ie8 & {
            +            display: inline;
            +            zoom: 1;
            +        }
            +    }
            +}
            +
            +//== vertical block
            +//==========================================
            +@mixin vertical-center( $width: 100px, $height: 100px) {
            +    left: 0;
            +    right: 0;
            +    bottom: 0;
            +    top: 0;
            +    margin: auto;
            +    width: $width;
            +    height: $height;
            +    position: absolute;
            +}
            +
            +//== Translate X - Y - Z
            +//==========================================
            +@mixin translateX($x) {
            +    -webkit-transform: translateX($x);
            +    -ms-transform: translateX($x); // IE9 only
            +    -o-transform: translateX($x);
            +    transform: translateX($x);
            +}
            +
            +@mixin translateY($y) {
            +    -webkit-transform: translateY($y);
            +    -ms-transform: translateY($y); // IE9 only
            +    -o-transform: translateY($y);
            +    transform: translateY($y);
            +}
            +
            +@mixin translateZ($z) {
            +    -webkit-transform: translateZ($z);
            +    -ms-transform: translateZ($z); // IE9 only
            +    -o-transform: translateZ($z);
            +    transform: translateZ($z);
            +}
            +
            +//== Transform
            +//==========================================
            +@mixin transform($argument){
            +    -webkit-transform: ($argument);
            +    -moz-transform: ($argument);
            +    -ms-transform: ($argument);
            +    -o-transform: ($argument);
            +    transform: ($argument);
            +}
            +
            +//== Transform
            +//==========================================
            +@mixin transition-delay($time1,$time2){
            +    -webkit-transition-delay: ($time1,$time2);
            +    -moz-transition-delay: ($time1,$time2);
            +    -ms-transition-delay: ($time1,$time2);
            +    -o-transition-delay: ($time1,$time2);
            +    transition-delay: ($time1,$time2);
            +}
            +
            +//== Background Size
            +//==========================================
            +@mixin background-size($size1,$size2) {
            +    -webkit-background-size: ($size1,$size2);
            +    -moz-background-size: ($size1,$size2);
            +    -ms-background-size: ($size1,$size2);
            +    -o-background-size: ($size1,$size2);
            +    background-size: ($size1,$size2);
            +}
            +
            +//== Background origin
            +//==========================================
            +@mixin background-origin($value1,$value2){
            +    -webkit-background-origin: ($value1,$value2);
            +    -moz-background-origin: ($value1,$value2);
            +    -ms-background-origin: ($value1,$value2);
            +    -o-background-origin: ($value1,$value2);
            +    background-origin: ($value1,$value2);
            +}
            +
            +//== Border radius
            +//==========================================
            +@mixin border-radius($radius) {
            +    border-radius         : $radius;
            +    -webkit-border-radius : $radius;
            +    -moz-border-radius    : $radius;
            +    -ms-border-radius     : $radius;
            +    -o-border-radius      : $radius;
            +}
            +
            +//== Text Shadow
            +//==========================================
            +@mixin text-shadow($shadow) {
            +    text-shadow         : $shadow;
            +    -webkit-text-shadow : $shadow;
            +    -moz-text-shadow    : $shadow;
            +    -ms-text-shadow     : $shadow;
            +    -o-text-shadow      : $shadow;
            +}
            +
            +//== Transform Origin
            +//==========================================
            +@mixin transform-origin($originX,$originY) {
            +    -webkit-transform-origin : $originX $originY;
            +    -moz-transform-origin    : $originX $originY;
            +    -ms-transform-origin     : $originX $originY; // IE9 only
            +    transform-origin         : $originX $originY;
            +}
            +
            +//== appearance
            +//==========================================
            +@mixin appearance() {
            +    -webkit-appearance : none;
            +    -moz-appearance    : none;
            +    -o-appearance      : none;
            +    -ms-appearance     : none;
            +    appearance         : none;
            +}
            +
            +//== selection
            +//==========================================
            +$prefixes: ("-moz-", "");
            +@mixin selection($color, $background) {
            +    @each $prefix in $prefixes {
            +        ::#{$prefix}selection {
            +            color: $color;
            +            background: $background;
            +        }
            +    }
            +}
            +
            +//== animation fill mode
            +//==========================================
            +@mixin animation-fill-mode($fill) {
            +    -webkit-animation-fill-mode: $fill;
            +    -moz-animation-fill-mode: $fill;
            +    -o-animation-fill-mode: $fill;
            +    animation-fill-mode: $fill;
            +}
            +
            +//== filter
            +//==========================================
            +@mixin filter($argument){
            +    filter         : $argument;
            +    -webkit-filter : $argument;
            +    -moz-filter    : $argument;
            +    -o-filter      : $argument;
            +    -ms-filter     : $argument;
            +}
            +
            +// Clear Lists
            +// -------------------------
            +@mixin clear-list(){
            +    padding    : 0;
            +    margin     : 0;
            +    list-style : none;
            +}
            +
            +// Formart lists widget
            +// -------------------------
            +@mixin lists-style() {
            +    ul,ol{
            +        @include clear-list();
            +        li{
            +            &:first-child{
            +
            +            }
            +            &:last-child{
            +                border-bottom: 0;
            +                padding-bottom: 0;
            +            }
            +            .children{
            +                > li{
            +                    &:before{
            +                        top: 24px;
            +                    }
            +                }
            +            }
            +        }
            +        ul{
            +            li:first-child{
            +                padding-top: 14px;
            +                background-position: 0 24px;
            +            }
            +        }
            +    }
            +}
            +
            +@import "functions";
            \ No newline at end of file
            diff --git a/assets/scss/components/vars/_elements.scss b/assets/scss/components/vars/_elements.scss
            new file mode 100755
            index 00000000..c7f969a0
            --- /dev/null
            +++ b/assets/scss/components/vars/_elements.scss
            @@ -0,0 +1,244 @@
            +$opalestate-parallax-before-background : url("http://venusdemo.com/wpopal/mix/mobile/wp-content/uploads/2014/11/bg-footer-cd.jpg")!default;
            +
            +$element-color-primary        : $theme-color !default;
            +
            + /* --- SCSS For Accordion --- */
            +$opalestate-accordion-background:                        $brand-success !default; 
            +$opalestate-accordion-color:                             $brand-success !default;
            +
            +$opalestate-accordion-border-color:                      #eee !default;
            +
            + /* --- SCSS For Breadcrumb --- */
            +
            + /* --- SCSS For Buttons --- */
            +
            + /* --- SCSS For Call-to-action --- */$white : #FFFFFF !default;
            +
            + /* --- SCSS For Content-slider --- *//*  */
            +
            +$opalestate-carousel-md-width:                             44px !default;
            +$opalestate-carousel-md-height:                            44px !default;
            +
            +$opalestate-carousel-sm-width:                             34px !default;
            +$opalestate-carousel-sm-height:                            34px !default;
            +
            +$opalestate-carousel-xs-width:                             30px !default;
            +$opalestate-carousel-xs-height:                            30px !default;
            + 
            +/* carousel-controls-v1 */
            +$opalestate-carousel-controls-v1-color:                    #999 !default;
            +$opalestate-carousel-controls-v1-hover-color:              darken($opalestate-carousel-controls-v1-color, 15%) !default;
            +$opalestate-carousel-controls-v1-bg:                       rgba(0, 0, 0, 0.5) !default;
            +
            +/* carousel-controls-v2 */
            +$opalestate-carousel-controls-v2-color:                    #999 !default;
            +$opalestate-carousel-controls-v2-hover-color:              darken($opalestate-carousel-controls-v2-color, 25%) !default;
            +
            +/* carousel-controls-v3 */
            +$opalestate-carousel-controls-v3-color:                    #fff !default;
            +$opalestate-carousel-controls-v3-hover-color:              #fff !default;
            +$opalestate-carousel-controls-v3-bg:                       $element-color-primary  !default;
            +$opalestate-carousel-controls-v3-hover-bg:                 darken($opalestate-carousel-controls-v3-bg, 15%) !default;
            +
            +
            +
            +/* Navigation Styles */
            +
            +/* carousel-indicators-v1 */
            +$opalestate-carousel-indicators-v1-bg:                     #ddd !default;
            +$opalestate-carousel-indicators-v1-hover-bg:               $brand-success !default;
            +
            +/* carousel-indicators-v2 */
            +$opalestate-carousel-indicators-v2-bg:                     #ddd !default;
            +$opalestate-carousel-indicators-v2-hover-bg:               $brand-success !default;
            +
            +/* carousel-indicators-v3 */
            +$opalestate-carousel-indicators-v3-bg:                     $brand-success !default;
            +$opalestate-carousel-indicators-v3-hover-bg:               $brand-success !default;
            +
            +/* carousel-indicators-v4 */
            +$opalestate-carousel-indicators-v4-bg:                     $brand-success !default;
            +$opalestate-carousel-indicators-v4-hover-bg:               $brand-success !default;
            +
            +
            +/* carousel-indicators-v5 */
            +$opalestate-carousel-indicators-v5-bg:                     $brand-success !default;
            +$opalestate-carousel-indicators-v5-hover-bg:               $brand-success !default;
            +
            +/* carousel-indicators-v6 */
            +$opalestate-carousel-indicators-v6-bg:                     $brand-success !default;
            +$opalestate-carousel-indicators-v6-hover-bg:               $brand-success !default;
            +
            + /* --- SCSS For Counters --- */
            +$opalestate-counter-color:                   $brand-primary;
            +$opalestate-counter-font-weight:             700;
            +$opalestate-counter-font-size:               48px;
            +
            +$opalestate-counter-icon-font-size:          46px;
            +$opalestate-counter-heading-font-weight:     400;
            +
            + /* --- SCSS For Heading --- */$opalestate-heading-color:            $brand-success;
            +
            + /* --- SCSS For Icon-box --- */
            +
            + /* --- SCSS For Interactive-banner --- */
            +
            + /* --- SCSS For Latest-posts --- *//* latest posts */
            +$opalestate-latest-posts-color:                   #696969;
            +$opalestate-latest-posts-a-color:                 #000;
            +$opalestate-latest-posts-a-hover-color:           red;
            +$opalestate-latest-posts-font-size:               14px;
            +$opalestate-latest-posts-title-font-size:         18px;
            +
            +$opalestate-latest-posts-profile-font-size:       13px;
            +$opalestate-latest-posts-profile-color:           #696969;
            +
            + /* --- SCSS For List --- *//* variables for list */
            +$opalestate-list-color:                           #666 !default; 
            +$opalestate-list-a-color:                         $opalestate-list-color !default; 
            +$opalestate-list-a-color-hover:                   $brand-success  !default;
            +
            +/* variables for list light */
            +
            +$opalestate-list-light-color:                     #FFFFFF !default; 
            +$opalestate-list-light-a-color:                   $opalestate-list-light-color !default; 
            +$opalestate-list-light-a-color-hover:             $brand-success  !default;
            +
            +
            + /* --- SCSS For Message --- */
            +
            + /* --- SCSS For Newsletter --- */$newsletter-v2-bg            : lighten($gray-light, 50%) !default;
            +$newsletter-v3-bg            : $gray-dark !default;
            +
            +
            + /* --- SCSS For Piechart --- */
            +
            + /* --- SCSS For Pricing --- */
            +
            + /* --- SCSS For Process-steps --- *//* process-steps */
            +$opalestate-process-steps-color:                      #000;
            +$opalestate-process-steps-bg:                         #000;
            +
            +$opalestate-process-steps-active-color:               $brand-success;
            +$opalestate-process-steps-active-bg:                  $brand-success;
            +
            + /* --- SCSS For Service --- *//* variables for tab style1 using as base of tab */
            +
            +
            + /* --- SCSS For Style-icon --- *//* Variables icons default */
            +$opalestate-style-icon-color:                              #fff!default;
            +$opalestate-style-icon-hover-color:                        #fff!default;
            +$opalestate-style-icon-bg:                                 $brand-success!default;
            +$opalestate-style-icon-hover-bg:                           darken($opalestate-style-icon-bg, 5%)!default;
            +
            +/* Variables icons bodered */
            +$opalestate-style-icon-bodered-color:                      $brand-success!default;
            +$opalestate-style-icon-bodered-hover-color:                darken($opalestate-style-icon-bodered-color, 10%)!default;
            +
            +/* Variables icons darker */
            +$opalestate-style-icon-darker-color:                        #fff!default;
            +$opalestate-style-icon-darker-hover-color:                  #fff!default;
            +$opalestate-style-icon-darker-bg:                           #000!default;
            +$opalestate-style-icon-darker-hover-bg:                     lighten($opalestate-style-icon-darker-bg, 35%)!default;
            +
            +/* Variables icons light */
            +$opalestate-style-icon-light-color:                        #000!default;
            +$opalestate-style-icon-light-hover-color:                  #fff!default;
            +$opalestate-style-icon-light-bg:                           #f0f0f0!default;
            +$opalestate-style-icon-light-hover-bg:                     darken($opalestate-style-icon-light-bg, 10%)!default;
            +
            +/* Variables icons plain */
            +$opalestate-style-icon-plain-color:                        $brand-success!default;
            +$opalestate-style-icon-plain-hover-color:                  #000!default;
            +$opalestate-style-icon-plain-bg:                           transparent!default;
            +$opalestate-style-icon-plain-hover-bg:                     transparent!default;
            +
            +/* Variables icons for light style */
            +$opalestate-light-style-icon-color:                        $brand-success!default;
            +$opalestate-light-style-icon-hover-color:                  $brand-success!default;
            +$opalestate-light-style-icon-bg:                           transparent!default;
            +$opalestate-light-style-icon-hover-bg:                     darken(#fff, 5%)!default;
            +
            +$opalestate-light-style-icon-bodered-color:                #fff!default;
            +$opalestate-light-style-icon-bodered-hover-color:          darken(#fff, 5%)!default;
            +$opalestate-light-style-icon-bodered-bg:                   #fff!default;
            +$opalestate-light-style-icon-bodered-hover-bg:             darken(#fff, 5%)!default;
            +
            +/* Variables icons outline */
            +
            +$icons-outline-color:                              #d1d646!default;
            +$icons-outline-bg:                                 transparent!default;
            +$icons-outline-border:                             $icons-outline-color!default;
            +$icons-outline-hover-color:                        #fff!default;		
            +$icons-outline-hover-bg:                           $icons-outline-color!default;
            +$icons-outline-hover-border:                       darken($icons-outline-hover-bg, 5%)!default;
            +
            +/* Variables icons inverse */
            +
            +$icons-inverse-color:                              #fff!default;
            +$icons-inverse-bg:                                 #d1d646!default;
            +$icons-inverse-border:                             darken($icons-inverse-bg, 5%)!default;
            +$icons-inverse-hover-color:                        #d1d646!default;	
            +$icons-inverse-hover-bg:                            transparent!default;
            +$icons-inverse-hover-border:                       $icons-inverse-bg!default;
            +
            +
            + /* --- SCSS For Table --- */
            +
            + /* --- SCSS For Tabs --- */
            +/* variables for tab style1 using as base of tab */
            +$opalestate-tabs-a-color:#FFFFFF !default; 
            +$opalestate-tabs-a-color-active:#000000 !default;
            +
            +$opalestate-tabs-padding: 10px 20px !default; 
            +$opalestate-tabs-background: $brand-primary !default;
            +$opalestate-tabs-background-hover: #f6f6f6 !default;
            +$opalestate-tabs-content-background:#f6f6f6 !default;
            +
            +$opalestate-tabs-border-color : #eee !default;
            +$opalestate-tabs-content-border:  1px solid $opalestate-tabs-border-color !default;
            +$opalestate-tabs-content-padding: 15px 20px!default;
            +
            +
            +/* tab style version 5 */
            +$opalestate-tabs-primary-background-hover:#000000!default;
            +$opalestate-tabs-primary-background:#FFFFFF !default;
            +
            +/* tab style version 6 */
            +$opalestate-tabs-v6-heading-background: #FFFFFF !default; 
            +
            +$opalestate-tabs-v6-a-color : #000000 !default;
            +$opalestate-tabs-v6-a-color-active:red !default;
            +$opalestate-tabs-v6-heading-padding: 10px 20px;
            +$opalestate-tabs-v6-heading-border-top-color:#000000 !default; 
            +
            +$opalestate-tabs-v6-heading-border-color:#eee !default;  
            +$opalestate-tabs-v6-content-border-color:1px solid $opalestate-tabs-border-color !default;
            +
            + /* --- SCSS For Testimonials --- *//* testimonials default */
            +$opalestate-testimonials-color:                              #696969;
            +$opalestate-testimonials-a-color:                            #696969;
            +$opalestate-testimonials-heading-color:                      #696969;							
            +
            +
            +/* testimonials-v1 */
            +$opalestate-testimonials-v1-color:                              #696969;
            +$opalestate-testimonials-v1-a-color:                            #696969;
            +$opalestate-testimonials-v1-background:                         #f3f3f3;
            +$opalestate-testimonials-v1-light-background:                   #fff;
            +$opalestate-testimonials-v1-light-color:                        $gray-dark;
            +
            +/* testimonials light */
            +$opalestate-testimonials-light-color:                              #fff;
            +$opalestate-testimonials-light-a-color:                            #fff;
            +$opalestate-testimonials-light-heading-color:                      #fff;
            +
            +
            +
            + /* --- SCSS For Typography --- */
            +$opalestate-blockquote-icon-background  : $brand-primary !default;
            +$opalestate-blockquote-icon-color       : #FFFFFF !default;
            +$opalestate-blockquote-icon-font-size   : 17px !default;
            +$opalestate-blockquote-icon-line-height : 22px !default;
            +
            +$opalestate-blockquote-color            : #000000 !default;
            diff --git a/assets/scss/components/vars/_form.scss b/assets/scss/components/vars/_form.scss
            new file mode 100755
            index 00000000..abeeb1f4
            --- /dev/null
            +++ b/assets/scss/components/vars/_form.scss
            @@ -0,0 +1,114 @@
            +// Select
            +// -------------------------
            +$select-size                            : 32px !default;
            +$select-border-color                    : $border-color !default;
            +$select-padding                         : 4px 6px !default;
            +
            +// Input
            +// -------------------------
            +$input-padding                          : 5px 6px !default;
            +$input-font-size                        : $font-size-base - 1;
            +
            +$input-group-form-bg                    : transparent !default;
            +$input-group-form-margin                : 0 0 5px 0!default;
            +$input-group-padding                    : 6px 11px !default;
            +$input-group-font-size                  : 12px !default;
            +$input-group-addon-color                : #fff !default;
            +$input-group-height                     : 42px !default;
            +
            +$input-form-bg                          : $gray-darker !default;
            +
            +// Button
            +// -------------------------
            +$btn-transform                          : uppercase !default;
            +$btn-padding-vertical                   : 5px !default;
            +$btn-padding-horizontal                 : 20px !default;
            +$btn-font-size                          : 12px !default;
            +$btn-line-height                        : 30px !default;
            +$btn-border-radius                      : 4px !default;
            +
            +$btn-lg-padding-vertical                : 15px !default;
            +$btn-lg-padding-horizontal              : 30px !default;
            +$btn-lg-font-size                       : 18px !default;
            +$btn-lg-line-height                     : $line-height-large !default;
            +$btn-lg-border-radius                   : 5px !default;
            +
            +$btn-sm-padding-vertical                : 7px !default;
            +$btn-sm-padding-horizontal              : 12px !default;
            +$btn-sm-font-size                       : 10px !default;
            +$btn-sm-line-height                     : $line-height-small !default;
            +$btn-sm-border-radius                   : $border-radius-small !default;
            +
            +$btn-xs-padding-vertical                : 4px !default;
            +$btn-xs-padding-horizontal              : 10px !default;
            +$btn-xs-font-size                       : 10px !default;
            +$btn-xs-line-height                     : $line-height-small !default;
            +$btn-xs-border-radius                   : $border-radius-small !default;
            +
            +$btn-outline-color                      : $white !default;
            +$btn-outline-hover-color                : $white !default;
            +$btn-outline-height                     : 36px !default;
            +$btn-outline-padding 			: 3px 15px !default;
            +$btn-outline-bg                         : $theme-color !default;
            +$btn-outline-hover-bg                   :$theme-color-second !default;
            +$btn-outline-border                     : 0 !default;
            +$btn-outline-border-hover               : 0 !default;
            +$btn-outline-font-size                  : 12px !default;
            +$btn-outline-line-height                : 28px !default;
            +$btn-outline-border-radius              : 0 !default;
            +
            +$btn-outline-sm-padding-vertical        : 8px !default;
            +$btn-outline-sm-padding-horizontal      : 18px !default;
            +$btn-outline-sm-font-size               : 11px !default;
            +$btn-outline-sm-line-height             : 1.3 !default;
            +$btn-outline-sm-border-radius           : 3px !default;
            +
            +$btn-outline-xs-padding-vertical        : 5px !default;
            +$btn-outline-xs-padding-horizontal      : 15px !default;
            +$btn-outline-xs-font-size               : 11px !default;
            +$btn-outline-xs-line-height             : 1.2 !default;
            +$btn-outline-xs-border-radius           : 3px !default;
            +
            +$btn-outline-lg-padding-vertical        : 21px !default;
            +$btn-outline-lg-padding-horizontal      : 48px !default;
            +$btn-outline-lg-font-size               : 14px !default;
            +$btn-outline-lg-line-height             : 3 !default;
            +$btn-outline-lg-border-radius           : 4px !default;
            +
            +$btn-inverse-color                      : $black !default;
            +$btn-inverse-hover-color                : $white !default;
            +$btn-inverse-bg                         : $white !default;
            +$btn-inverse-hover-bg                   : $black !default;
            +$btn-inverse-border-color               : $border-color !default;
            +$btn-inverse-border-hover-color         : $border-color !default;
            +$btn-inverse-font-size                  : 12px !default;
            +$btn-inverse-padding                    : 10px 15px !default;
            +
            +$btn-outline-inverse-color              : $theme-color-second !default;
            +$btn-outline-inverse-bg                 : $black !default;
            +$btn-outline-inverse-border-color       : 1px solid $btn-outline-inverse-bg !default;
            +$btn-outline-inverse-hover-bg           : $theme-color !default;
            +$btn-outline-inverse-hover-color        : $white !default;
            +$btn-outline-inverse-border-hover-color : 1px solid $theme-color-second !default;
            +
            +// Search
            +// -------------------------
            +$search-bg                              : $white !default;
            +$search-font-size                       : 12px !default;
            +$search-padding                         : 15px !default;
            +$search-width                           : auto !default;
            +$search-button-bg                       : transparent !default;
            +$search-main-button-bg                  : $white !default;
            +$search-main-button-border              : $border-color !default;
            +$search-main-button-color               : $gray-darker !default;
            +$search-button-border                   : 0px !default;
            +$search-button-hover-bg                 : $white !default;
            +$search-button-color                    : $white !default;
            +$search-button-size                     : 36px !default;
            +$search-button-hover-color              : $gray-darker !default;
            +$search-radius                          : 3px !default;
            +$search-height                          : 50px !default;
            +$search-border                          : transparent !default;
            +$search-hover-border                    : $border-color !default;
            +$search-border-radius                   : 4px !default;
            +$search-categories-border-radius        : 4px !important;
            diff --git a/assets/scss/components/vars/_layout.scss b/assets/scss/components/vars/_layout.scss
            new file mode 100755
            index 00000000..51f8766e
            --- /dev/null
            +++ b/assets/scss/components/vars/_layout.scss
            @@ -0,0 +1,91 @@
            +
            +// Topbar
            +// -------------------------
            +$topbar-bg                                      : #1c2b49 !default;
            +$topbar-link-color                              : $light-gray !default;
            +$topbar-link-hover-color                        : $theme-color !default;
            +$topbar-color                                   : $light-gray !default;
            +$topbar-border                                  : 0 !default;
            +$topbar-font-size                               : 14px !default;
            +$topbar-icon-color                              : $theme-color !default;
            +$topbar-icon-font-size                          : 14px !default;
            +$topbar-text-transform                          : none !default;
            +$topbar-padding                            		: 0 !default;
            +
            +//// Header
            +
            +$header-main-padding : 30px 0 !default; 
            +$header-main-margin : 0 !default; 
            +$header-bg-color: #233354 !default;
            +
            +
            +$massbottom-head-bg		 : $theme-color !default;
            +$massbottom-head-padding : 6px 9px !default;
            +$massbottom-head-color   : $theme-color !default;
            +$massbottom-head-border-color: darken($massbottom-head-bg,4%)!default; 
            +
            +/**
            + *
            + */
            +
            + $mainmenu-bg: #222222 !default;
            +
            +
            +
            +
            +// Footer
            +// -------------------------  
            +$footer-bg                                      : none !default;
            +$footer-color                                   : #ccc !default;
            +$footer-transform                               : none !default;
            +$footer-font-size                               : 14px !default; 
            +$footer-border                                  : none !default;
            +$footer-padding-top                             : 60px !default;
            +$footer-padding-bottom                          : 0 !default;
            +$footer-text-hightlight                         : $white !default;
            +$footer-link-font-size							      : 14px !default;
            +$footer-column-margin                           : 0 0 25px 0 !default;
            +$footer-link-color                              : #FFF !default;
            +$footer-link-hover-color                        : $theme-color !default;
            +$footer-icon-color                              : darken($white, 20%) !default;
            +$footer-icon-font-size                          : 13px !default;
            +$footer-heading-font-size                       : 16px !default;
            +$footer-heading-color                           : $white !default;
            +$footer-heading-margin                          : 0 0 25px !default;
            +$footer-heading-padding                         : 0 0 15px !default;
            +$footer-heading-display                         : none !default;
            +$footer-heading-transform                       : uppercase !default;
            +$footer-list-transform                          : none !default;
            +$footer-list-font-size                          : 14px !default; 
            +$footer-list-margin                             : 0 0 10px !default;
            +$footer-list-light-height                       : 2.5 !default;  
            +$footer-heading-fweight                         : 400 !default;
            +$footer-heading-ffamily                         : $font-family-second !default;
            +
            +$footer-newsletter-padding                      : 25px !default;
            +$footer-newsletter-bg                           : $theme-color !default;
            +$footer-newsletter-color                        : #484848 !default;
            +$footer-newsletter-heading-font-size            : 18px !default;
            +
            +$footer-top-bg 									: $white !default;
            +$footer-top-color  								: $black !default;
            +$footer-top-padding-top							: 12px !default; 
            +$footer-top-padding-bottom						: 12px !default;
            +$footer-top-font-size							: 12px !default;
            +$footer-top-letter-spacing						: 2px !default;
            +$footer-top-border-color 						: rgba(0, 0, 0, 0.1);
            +// Copyright
            +// -------------------------
            +
            + // Copyright
            +// -------------------------
            +$copyright-bg                                   : none !default;
            +$copyright-color                                : $light-gray !default;
            +$copyright-link-color                           : $light-gray !default;
            +$copyright-padding-top                          : 30px !default;
            +$copyright-padding-bottom                       : 30px !default;
            +$copyright-font-size							: 14px !default; 
            +$copyright-font-weight							: 400 !default;
            +
            +$del-font-size									: 12px !default;
            +$del-color										: #999999;
            \ No newline at end of file
            diff --git a/assets/scss/components/vars/_nav.scss b/assets/scss/components/vars/_nav.scss
            new file mode 100755
            index 00000000..863a3a26
            --- /dev/null
            +++ b/assets/scss/components/vars/_nav.scss
            @@ -0,0 +1,95 @@
            +// Main Menu
            +// -------------------------
            +$megamenu-bg                               : $white !default;
            +$navbar-mega-border                        : transparent !default;
            +$navbar-mega-line-height                   : 75px !default;
            +
            +$navbar-mega-skin2-bg                      : transparent !default;
            +$navbar-mega-skin2-border                  : $border-color !default;
            +$navbar-mega-skin2-line-height             : 30px !default; 
            +
            +$navbar-text-transform                     : none !default;
            +
            +$navbar-font-size                          : 14px !default;
            +$navbar-font-weight                        : 400 !default;
            + 
            +$navbar-link-margin                        : 0 !default;
            +$navbar-link-padding                       : 6px 20px !default;
            +$navbar-link-color                         : $white !default;
            +$navbar-link-hover-color                   : $theme-color !default;
            +$navbar-link-hover-bg                      : $nocolor !default;
            +$navbar-link-active-color                  : $theme-color !default;
            +$navbar-link-active-bg                     : $nocolor !default;
            +$navbar-link-font-family		           : $headings-font-family !default;
            +
            +$navbar-widget-title-color                 : $black !default;
            +$navbar-widget-title-margin                : 0 0 10px 0 !default;
            +$navbar-widget-title-font-size             : 14px !default;
            +$navbar-widget-title-font-weight		   : 900 !default;
            +
            +$navbar-dropdown-padding                   : 8px 18px !default;
            +$navbar-dropdown-bg                        : #fff !default;
            +$navbar-dropdown-size                      : 200px !default;
            +$navbar-dropdown-link-color                : #000 !default;
            +$navbar-dropdown-link-hover-color          : $theme-color !default;
            +$navbar-dropdown-link-hover-bg             : $nocolor !default;
            +$navbar-dropdown-link-transform            : none !default;
            +$navbar-dropdown-link-font-size            : 14px !default;
            +$navbar-dropdown-link-font-weight          : 400 !default;
            +$navbar-dropdown-link-border-color         : $nocolor !default;
            +
            +$navbar-link-small-padding                 : 18px 0 !default;
            +$navbar-link-large-padding                 : 46px 0 46px !default;  
            +
            +// Vertical Menu
            +// -------------------------
            +
            +// Top Menu
            +// -------------------------
            +$navbar-menutop-font-weight				    : 800 !default;
            +$navbar-menutop-font-size				       : 12px !default;
            +$navbar-menutop-padding-top				    : 22px !default;
            +$navbar-menutop-padding-bottom			    : 18px !default;
            +$navbar-menutop-color					       : #828282 !default;
            +$navbar-menutop-margin					       : 0 10px !default;
            +
            +// Off-Canvas Menu
            +// -------------------------
            +$navbar-offcanvas-width                    : 69% !default;
            +$navbar-offcanvas-bg-close                 : $nocolor !default;
            +$navbar-offcanvas-color                    : $black !default;
            +$navbar-offcanvas-bg                       : #f5f5f5  !default;
            +$navbar-offcanvas-border                   : rgba(0, 0, 0, 0.1) !default;
            +
            +// Inverted navbar links
            +// -------------------------
            +$navbar-offcanvas-link-color               : $text-color !default;
            +$navbar-offcanvas-link-hover-color         : #0281AB !default;
            +$navbar-offcanvas-link-hover-bg            : transparent !default;
            +$navbar-offcanvas-link-active-color        : $navbar-offcanvas-link-hover-color !default;
            +$navbar-offcanvas-link-active-bg           : darken($navbar-offcanvas-bg, 10%) !default;
            +$navbar-offcanvas-link-disabled-color      : #444 !default;
            +$navbar-offcanvas-link-disabled-bg         : transparent !default;
            +$navbar-offcanvas-link-font-size           : 14px !default;
            +
            +// Inverted navbar brand label
            +// -------------------------
            +$navbar-offcanvas-brand-color              : $navbar-offcanvas-link-color !default;
            +$navbar-offcanvas-brand-hover-color        : $white !default;
            +$navbar-offcanvas-brand-hover-bg           : transparent !default;
            +
            +// Inverted navbar search
            +// -------------------------
            +$navbar-offcanvas-search-bg                : lighten($navbar-offcanvas-bg, 25%) !default;
            +$navbar-offcanvas-search-bg-focus          : $white !default;
            +$navbar-offcanvas-search-border            : $navbar-offcanvas-bg !default;
            +$navbar-offcanvas-search-placeholder-color : $light-gray !default;
            +$navbar-offcanvas-search-input-bg          : transparentize($black, .10) !default;
            +
            +// Inverted navbar toggle
            +// -------------------------
            +$navbar-offcanvas-toggle-hover-bg          : $gray-dark !default;
            +$navbar-offcanvas-toggle-icon-bar-bg       : $white !default;
            +$navbar-offcanvas-toggle-border-color      : $gray-dark !default;
            +
            +$navbar-offcanvas-button-position          : -172px !default;
            \ No newline at end of file
            diff --git a/assets/scss/components/vars/_widget.scss b/assets/scss/components/vars/_widget.scss
            new file mode 100755
            index 00000000..9c55db7f
            --- /dev/null
            +++ b/assets/scss/components/vars/_widget.scss
            @@ -0,0 +1,88 @@
            +/**
            + *   Blocks Layout Selectors
            + */
            +$block-prefix                    : 'widget' !default;
            +$block-selector                  : 'widget ' !default;
            +$block-heading-selector          : 'widget-title, .widgettitle' !default;
            +$block-content-selector          : 'widget-content' !default;
            +$block-heading-reversed-selector : 'widget-title-reversed' !default;
            +$container-prefix                : 'wpb-container' !default;
            +
            +
            +
            +// Box Modules
            +// -------------------------
            +$block-module-margin-bottom                     : 30px !default;
            +$block-module-padding                           : 0px !default;
            +$block-module-border-color                      : none !default;
            +
            +$block-module-heading-color						: #000000 !default;
            +$block-module-heading-border                    : 0px !default;
            +$block-module-heading-transform                 : uppercase !default;
            +$block-module-heading-line-height               : normal !default;
            +$block-module-heading-bg                        : transparent !default;
            +$block-module-heading-padding                   : 0 0 15px !default;
            +$block-module-heading-margin                    : 0 0 25px !default;
            +$block-module-heading-font-size                 : 16px !default;
            +$block-module-heading-font-weight               : 700 !default;
            +$block-module-heading-show-separator            : none !default;
            +$block-module-heading-image-position            : 0 0 !default;
            +
            +$block-module-content-bg                        : transparent !default;
            +$block-module-content-color						: #bbb !default;
            +$block-module-content-border                    : 1px solid $border-color !default;
            +$block-module-content-padding                   : 20px !default;
            +$block-module-content-margin                    : 1px !default;
            +$block-module-content-radius                    : 0px !default;
            +
            +$block-module-highlighted-bg                    : $theme-color !default;
            +$block-module-highlighted-border                : solid 2px $theme-color !default;
            +
            +$block-module-footer-heading-color              : $white !default;
            +
            +$block-product-padding                          : 0 !default;
            +$block-heading-letter-spacing                   : 0 !default;
            +
            +// Sidebar
            +// -------------------------
            +$block-sidebar-module-border                    : none !default;
            +$block-sidebar-box-padding                      : 0 !default; 
            +$block-sidebar-box-margin                       : 0 0 30px !default;
            +
            +$block-sidebar-list-padding-vertical            : 13px 0px 13px 13px !default;
            +$block-sidebar-list-border-color                : $border-color !default;
            +
            +$block-sidebar-hightlight-margin 				: 0 0 20px !default;
            +$block-sidebar-heading-margin            		: 0 !default;
            +$block-sidebar-heading-hightlight-bg            : $nocolor !default;
            +$block-sidebar-heading-hightlight-padding       : 0 !default;
            +$block-sidebar-heading-hightlight-margin    	: 0 !default;
            +$block-sidebar-heading-hightlight-color         : $black !default;
            +$block-sidebar-heading-hightlight-margin-bottom : 0px !default;
            +$block-sidebar-heading-hightlight-font-size     : 14px !default;
            +$block-sidebar-heading-hightlight-font-weight   : 900 !default;
            +$block-sidebar-hightlight-content-bg			: $nocolor !default;
            +$block-sidebar-hightlight-content-color			: #666666 !default; 
            +$block-sidebar-hightlight-content-padding		: 0 !default;
            +$block-sidebar-hightlight-border   				: 1px solid rgba(0, 0, 0, 0.1) !default;
            +$block-sidebar-hightlight-font-size 			: 12px !default;	
            +$block-sidebar-hightlight-transform 			: uppercase !default;
            +$block-sidebar-hightlight-font-weight			: 300 !default;						
            +$block-sidebar-link-hightlight-color            : $white !default;
            +$block-sidebar-link-hightlight-hover-color      : $theme-color !default;
            +$block-sidebar-list-hightlight-border-color     : #393939 !default;
            +$block-sidebar-list-hightlight-font-size        : 10px !default;
            +$block-sidebar-list-hightlight-padding          : 17px 15px !default;
            +$block-sidebar-list-hightlight-image            : url('#{$image-theme-path}dot.jpg') 0 22px no-repeat !default;
            +$block-sidebar-list-image                       : url('#{$image-theme-path}dot.jpg') 0 22px no-repeat !default;
            +
            +$block-sidebar-heading-padding                  : 0 0 30px !default;
            +$block-sidebar-heading-margin                   : 0 !default;
            +$block-sidebar-heading-font-size                : 14px !default;
            +$block-sidebar-heading-color                    : $black !default; 
            +$block-sidebar-heading-line-height              : 20px !default;
            +$block-sidebar-heading-font-weight				: 900 !default;
            +
            +$block-sidebar-widget-border                    : 1px solid lighten($border-color, 3%) !default;
            +
            +/********* LAYOUT **************/
            \ No newline at end of file
            diff --git a/assets/scss/opalestate.scss b/assets/scss/opalestate.scss
            new file mode 100755
            index 00000000..7400de4a
            --- /dev/null
            +++ b/assets/scss/opalestate.scss
            @@ -0,0 +1,41 @@
            +/*
            +Theme Name: FullHouse
            +Theme URI: http://demovenustheme.com/wordpress/opalestate/
            +Author: Opal Team
            +Author URI: https://wordpress.org/
            +Description: In 2019, our default theme lets you create a responsive magazine website with a sleek, modern design. Feature your favorite homepage content in either a grid or a slider. Use the three widget areas to customize your website, and change your content's layout with a full-width page template and a contributor page to show off your authors. Creating a magazine website with WordPress has never been easier.
            +Version: 1.0
            +License: GNU General Public License v2 or later
            +License URI: http://www.gnu.org/licenses/gpl-2.0.html
            +Tags: black, green, white, light, dark, two-columns, three-columns, left-sidebar, right-sidebar, fixed-layout, responsive-layout, custom-background, custom-header, custom-menu, editor-style, featured-images, flexible-header, full-width-template, microformats, post-formats, rtl-language-support, sticky-post, theme-options, translation-ready, accessibility-ready
            +Text Domain: opalestate
            +
            +This theme, like WordPress, is licensed under the GPL.
            +Use it to make something cool, have fun, and share what you've learned with others.
            +*/
            +// Core variables and mixins
            +
            +@import "bootstrap/variables";
            +@import "bootstrap/mixins";
            +
            +@import "bootstrap/grid";
            +@import "opalestate/vars";
            +
            +
            +@import "components/variables";
            +@import "components/mixins";
            +
            +@import "opalestate/layout";
            +@import "opalestate/page";
            +@import "opalestate/shortcodes";
            +
            +// @import "opalestate/styles";
            +@import "opalestate/3rd";
            +@import "opalestate/form";
            +@import "opalestate/properties-loop";
            +@import "opalestate/agency-loop";
            +@import "opalestate/elements";
            +@import "opalestate/styles";
            +@import "opalestate/modules";
            +
            +@import "opalestate/dashboard";
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_3rd.scss b/assets/scss/opalestate/_3rd.scss
            new file mode 100755
            index 00000000..7feb7652
            --- /dev/null
            +++ b/assets/scss/opalestate/_3rd.scss
            @@ -0,0 +1,497 @@
            +//header login
            +.site-header-account{
            +  .account-label{
            +    margin-left: 5px;
            +  }
            +  .opalestate-popup{
            +    .popup-body{
            +      padding: 0;
            +      box-shadow: none;
            +      background-color: transparent;
            +    }
            +  }
            +  .btn{
            +    margin-bottom: $padding-base;
            +  }
            +  .opalestate-social-login__buttons{
            +    a{
            +      padding: 0 10px;
            +    }
            +    i{
            +      margin-right: 10px;
            +      padding-right: 10px;
            +    }
            +  }
            +}
            +
            +//Google Login
            +.mfp-with-zoom .mfp-container,
            +.mfp-with-zoom.mfp-bg {
            +  opacity: 0;
            +  -webkit-backface-visibility: hidden;
            +  /* ideally, transition speed should match zoom duration */
            +  -webkit-transition: all 0.3s ease-in-out;
            +  -moz-transition: all 0.3s ease-in-out;
            +  -o-transition: all 0.3s ease-in-out;
            +  transition: all 0.3s ease-in-out;
            +}
            +.mfp-with-zoom .white-popup{
            +  top: 20px;
            +  -webkit-transition: all 0.3s ease-in-out;
            +  -moz-transition: all 0.3s ease-in-out;
            +  -o-transition: all 0.3s ease-in-out;
            +  transition: all 0.3s ease-in-out;
            +}
            +.mfp-with-zoom.mfp-ready .white-popup{
            +  top: 0;
            +}
            +.mfp-with-zoom.mfp-ready .mfp-container {
            +    opacity: 1;
            +    
            +}
            +.mfp-with-zoom.mfp-ready.mfp-bg {
            +    opacity: 0.8;
            +}
            +
            +.mfp-with-zoom.mfp-removing .mfp-container,
            +.mfp-with-zoom.mfp-removing.mfp-bg {
            +  opacity: 0;
            +}
            +.white-popup {
            +  position: relative;
            +  background: $white;
            +  padding: $grid-gutter-width;
            +  width:auto;
            +  max-width: 500px;
            +  margin: 20px auto;
            +  .mfp-close{
            +    top: 15px;
            +  }
            +  .submit{
            +    a{
            +      display: block;
            +      margin-top: 10px;
            +    }
            +  }
            +  .opalestate-button{
            +    padding: 17px 35px 14px 35px;
            +    width: 100%;
            +  }
            +}
            +
            +
            +.opalestate-social-login__buttons{
            +  list-style: none;
            +  padding: 0;
            +  margin: 0;
            +  a{
            +    display: block;
            +    padding: 0 $padding-base;
            +    color: $white;
            +    &:hover{
            +      color: $white;
            +    }
            +  }
            +  li{
            +    &:not(:last-child){
            +      margin-bottom: $padding-base;
            +    }
            +  }
            +  i{
            +    margin-right: $padding-base;
            +    padding: 16px $padding-base 14px 0;
            +    position: relative;
            +    text-align: center;
            +    width: 35px;
            +    &::after{
            +      content: "";
            +      position: absolute;
            +      top: 0;
            +      right: 0;
            +      height: 100%;
            +      border-left: 1px solid rgba(0, 0, 0, .1);
            +      border-right: 1px solid rgba(255, 255, 255, .1);
            +    }
            +  }
            +}
            +.opalestate-social-login-facebook-btn{
            +  background-color: #3C5A99;
            +}
            +.opalestate-social-login-google-btn{
            +  background-color: #d34836;
            +}
            +// Loading map
            +.sk-folding-cube {
            +  margin: 20px auto;
            +  width: 40px;
            +  height: 40px;
            +  position: relative;
            +  -webkit-transform: rotateZ(45deg);
            +          transform: rotateZ(45deg);
            +}
            +
            +.sk-folding-cube .sk-cube {
            +  float: left;
            +  width: 50%;
            +  height: 50%;
            +  position: relative;
            +  -webkit-transform: scale(1.1);
            +      -ms-transform: scale(1.1);
            +          transform: scale(1.1); 
            +}
            +.sk-folding-cube .sk-cube:before {
            +  content: '';
            +  position: absolute;
            +  top: 0;
            +  left: 0;
            +  width: 100%;
            +  height: 100%;
            +  background-color: $theme-color;
            +  -webkit-animation: sk-foldCubeAngle 2.4s infinite linear both;
            +          animation: sk-foldCubeAngle 2.4s infinite linear both;
            +  -webkit-transform-origin: 100% 100%;
            +      -ms-transform-origin: 100% 100%;
            +          transform-origin: 100% 100%;
            +}
            +.sk-folding-cube .sk-cube2 {
            +  -webkit-transform: scale(1.1) rotateZ(90deg);
            +          transform: scale(1.1) rotateZ(90deg);
            +}
            +.sk-folding-cube .sk-cube3 {
            +  -webkit-transform: scale(1.1) rotateZ(180deg);
            +          transform: scale(1.1) rotateZ(180deg);
            +}
            +.sk-folding-cube .sk-cube4 {
            +  -webkit-transform: scale(1.1) rotateZ(270deg);
            +          transform: scale(1.1) rotateZ(270deg);
            +}
            +.sk-folding-cube .sk-cube2:before {
            +  -webkit-animation-delay: 0.3s;
            +          animation-delay: 0.3s;
            +}
            +.sk-folding-cube .sk-cube3:before {
            +  -webkit-animation-delay: 0.6s;
            +          animation-delay: 0.6s; 
            +}
            +.sk-folding-cube .sk-cube4:before {
            +  -webkit-animation-delay: 0.9s;
            +          animation-delay: 0.9s;
            +}
            +@-webkit-keyframes sk-foldCubeAngle {
            +  0%, 10% {
            +    -webkit-transform: perspective(140px) rotateX(-180deg);
            +            transform: perspective(140px) rotateX(-180deg);
            +    opacity: 0; 
            +  } 25%, 75% {
            +    -webkit-transform: perspective(140px) rotateX(0deg);
            +            transform: perspective(140px) rotateX(0deg);
            +    opacity: 1; 
            +  } 90%, 100% {
            +    -webkit-transform: perspective(140px) rotateY(180deg);
            +            transform: perspective(140px) rotateY(180deg);
            +    opacity: 0; 
            +  } 
            +}
            +
            +@keyframes sk-foldCubeAngle {
            +  0%, 10% {
            +    -webkit-transform: perspective(140px) rotateX(-180deg);
            +            transform: perspective(140px) rotateX(-180deg);
            +    opacity: 0; 
            +  } 25%, 75% {
            +    -webkit-transform: perspective(140px) rotateX(0deg);
            +            transform: perspective(140px) rotateX(0deg);
            +    opacity: 1; 
            +  } 90%, 100% {
            +    -webkit-transform: perspective(140px) rotateY(180deg);
            +            transform: perspective(140px) rotateY(180deg);
            +    opacity: 0; 
            +  }
            +}
            +
            +
            +////
            +.cmb2-element{
            +  .ui-datepicker{
            +    width: 350px !important;
            +    .ui-datepicker-month,.ui-datepicker-year{
            +      display: inline-block;
            +    }
            +  }
            +}
            +
            +.noUi-target, .noUi-target * {
            +  -webkit-touch-callout: none;
            +  -webkit-user-select: none;
            +  -ms-touch-action: none;
            +  -ms-user-select: none;
            +  -moz-user-select: none;
            +  -moz-box-sizing: border-box;
            +  box-sizing: border-box
            +}
            +.noUi-target {
            +  position: relative;
            +  direction: ltr
            +}
            +.noUi-base {
            +  width: 100%;
            +  height: 100%;
            +  position: relative;
            +  border-radius: 3px;
            +}
            +.noUi-origin {
            +  position: absolute;
            +  right: 0;
            +  top: 0;
            +  left: 0;
            +  bottom: 0;
            +}
            +.noUi-handle {
            +  position: relative;
            +  z-index: 1
            +}
            +.noUi-stacking .noUi-handle {
            +  z-index: 10
            +}
            +.noUi-state-tap .noUi-origin {
            +  -webkit-transition: left .3s, top .3s;
            +  transition: left .3s, top .3s
            +}
            +.noUi-state-drag * {
            +  cursor: inherit!important
            +}
            +.noUi-base {
            +  -webkit-transform: translate3d(0, 0, 0);
            +  transform: translate3d(0, 0, 0)
            +}
            +.noUi-horizontal {
            +  height: 6px;
            +  border-radius: 3px;
            +  .noUi-base {
            +    .noUi-origin {
            +      .noUi-handle {
            +        @include rtl-margin-left(-18px);
            +      }
            +      &:first-child {
            +        .noUi-handle {
            +          @include rtl-margin-left(0px);
            +        }
            +      }
            +    }
            +  }
            +}
            +.noUi-horizontal[data-mode="1"]{
            +  .noUi-base{
            +    background: $primary;
            +    .noUi-origin{
            +      background: #e9e9f6;
            +      &:first-child {
            +        .noUi-handle {
            +          @include rtl-margin-left(-9px);
            +        }
            +      }
            +    }
            +  }
            +}
            +.noUi-horizontal[data-mode="2"]{
            +  .noUi-base{
            +    background:#e9e9f6;
            +    .noUi-origin{
            +      background: transparent;
            +    }
            +  }
            +}
            +.noUi-horizontal .noUi-handle {
            +  height:18px;
            +  width:18px;
            +  left: 0px;
            +  top: -6px;
            +  &.noUi-handle-upper {
            +    @include rtl-margin-left(-18px);
            +  }
            +}
            +.noUi-vertical {
            +  width: 18px
            +}
            +.noUi-vertical .noUi-handle {
            +  width: 28px;
            +  height: 34px;
            +  left: -6px;
            +  top: -17px
            +}
            +.noUi-background {
            +  background: #dadada;
            +  border-radius: 3px;
            +}
            +.noUi-connect {
            +  background: $primary;
            +  border-radius: 3px;
            +  height: 100%;
            +  position: absolute;
            +}
            +.noUi-origin {
            +}
            +.noUi-target {
            +}
            +.noUi-target.noUi-connect {
            +}
            +.noUi-dragable {
            +  cursor: w-resize
            +}
            +.noUi-vertical .noUi-dragable {
            +  cursor: n-resize
            +}
            +.noUi-handle {
            +  border-radius: 50%;
            +  background: #FFF;
            +  cursor: default;
            +  border: 1px solid transparentize($black, .9);
            +}
            +.noUi-active {
            +  box-shadow: inset 0 0 1px #FFF, inset 0 1px 7px #DDD, 0 3px 6px -3px #BBB
            +}
            +.noUi-handle:after, .noUi-handle:before {
            +}
            +.noUi-handle:after {
            +}
            +.noUi-vertical .noUi-handle:after, .noUi-vertical .noUi-handle:before {
            +}
            +.noUi-vertical .noUi-handle:after {
            +}
            +[disabled] .noUi-connect, [disabled].noUi-connect {
            +  background: #B8B8B8
            +}
            +[disabled] .noUi-handle {
            +  cursor: not-allowed
            +}
            +
            +
            +//Tooltip
            +.opalestate-rating-detail-container { display: none; }
            +.opalestate-tooltip{
            +  display: inline-block;
            +  line-height: 1;
            +}
            +.opalestate-rating-detail{
            +  padding: 0;
            +  margin: 0;
            +  list-style: none;
            +  text-align: center;
            +  line-height: 2;
            +  li{
            +    padding: 5px 0;
            +    label{
            +      margin-bottom: 0;
            +    }
            +  }
            +  li:not(:last-child){
            +    border-bottom: 1px solid $border-color;
            +    
            +  }
            +}
            +body {
            +  .tooltipster-sidetip .tooltipster-box {
            +    border: none; 
            +    border-radius: 5px;
            +    background: white;
            +    box-shadow: $box-shadow-base;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-bottom .tooltipster-box {
            +    margin-top: 6px;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-left .tooltipster-box {
            +    margin-right: 6px;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-right .tooltipster-box {
            +    margin-left: 6px;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-top .tooltipster-box {
            +    margin-bottom: 6px;
            +  }
            +  
            +  .tooltipster-sidetip .tooltipster-content {
            +    color: $body-color;
            +    background-color: $white;
            +  }
            +  
            +  .tooltipster-sidetip .tooltipster-arrow {
            +    height: 6px;
            +    margin-left: -6px;
            +    width: 12px;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-left .tooltipster-arrow,
            +  .tooltipster-sidetip.tooltipster-right .tooltipster-arrow {
            +    height: 12px;
            +    margin-left: 0;
            +    margin-top: -6px;
            +    width: 6px;
            +  }
            +  
            +  .tooltipster-sidetip .tooltipster-arrow-background {
            +    display: none;
            +  }
            +  
            +  .tooltipster-sidetip .tooltipster-arrow-border {
            +    border: 6px solid transparent;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border {
            +    border-bottom-color: white;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border {
            +    border-left-color: white;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border {
            +    border-right-color: white;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border {
            +    border-top-color: white;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped {
            +    top: -6px;
            +  }
            +  
            +  .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped {
            +    left: -6px;
            +  }
            +}
            +
            +/***/
            +
            +/**
            + * jQuery toast plugin created by Kamran Ahmed copyright MIT license 2014
            + */
            +.jq-toast-wrap { display: block; position: fixed; width: 350px;  pointer-events: none !important; margin: 0; padding: 0; letter-spacing: normal; z-index: 9000 !important; }
            +.jq-toast-wrap * { margin: 0; padding: 0; }
            +
            +.jq-toast-wrap.bottom-left { bottom: 20px; left: 20px; }
            +.jq-toast-wrap.bottom-right { bottom: 20px; right: 40px; }
            +.jq-toast-wrap.top-left { top: 20px; left: 20px; }
            +.jq-toast-wrap.top-right { top: 20px; right: 40px; }
            +
            +.jq-toast-single { display: block; width: 100%; padding: 10px; margin: 0px 0px 5px; border-radius: 4px; font-size: 12px;line-height: 17px; position: relative;  pointer-events: all !important; background-color: #444444; color: white; }
            +
            +.jq-toast-single h2 {font-size: 14px; margin: 0px 0px 7px; background: none; color: inherit; line-height: inherit; letter-spacing: normal; }
            +.jq-toast-single a { color: #eee; text-decoration: none; font-weight: bold; border-bottom: 1px solid white; padding-bottom: 3px; font-size: 12px; }
            +
            +.jq-toast-single ul { margin: 0px 0px 0px 15px; background: none; padding:0px; }
            +.jq-toast-single ul li { list-style-type: disc !important; line-height: 17px; background: none; margin: 0; padding: 0; letter-spacing: normal; }
            +
            +.close-jq-toast-single { position: absolute; top: 3px; right: 7px; font-size: 14px; cursor: pointer; }
            +
            +.jq-toast-loader { display: block; position: absolute; top: -2px; height: 5px; width: 0%; left: 0; border-radius: 5px; background: red; }
            +.jq-toast-loaded { width: 100%; }
            +.jq-has-icon { padding: 10px 10px 10px 50px; background-repeat: no-repeat; background-position: 10px; }
            +.jq-icon-info { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII='); background-color: #31708f; color: #d9edf7; border-color: #bce8f1; }
            +.jq-icon-warning { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII='); background-color: #8a6d3b; color: #fcf8e3; border-color: #faebcc; }
            +.jq-icon-error { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII='); background-color: #a94442; color: #f2dede; border-color: #ebccd1; }
            +.jq-icon-success { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg=='); color: #dff0d8; background-color: #3c763d; border-color: #d6e9c6; }
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_agency-loop.scss b/assets/scss/opalestate/_agency-loop.scss
            new file mode 100755
            index 00000000..f3fe4ba2
            --- /dev/null
            +++ b/assets/scss/opalestate/_agency-loop.scss
            @@ -0,0 +1,150 @@
            +.opalestate_agency{
            +    margin-bottom: $grid-gutter-width;
            +}
            +.trusted-label{
            +    font-size: 23px;
            +    color: $primary;
            +    text-align: center;
            +    line-height: 1;
            +}
            +.team-header {
            +    .trusted-label{
            +        position: absolute;
            +        right: 20px;
            +        background-color: $white;
            +        border-radius: 50%;
            +        bottom: 0;
            +        transform: translateY(50%);
            +        border: 1px solid $border-color;
            +        width: 48px;
            +        line-height: 48px;
            +    }
            +}
            +
            +.agency-box-title{
            +    display: inline-block;
            +    margin-right: 10px;
            +    line-height: 1;
            +}
            +.agency-address{
            +    margin-bottom: 0;
            +}
            +.agency-box-meta{
            +    [class*="agency-box-"]{
            +        &:not(:last-of-type){
            +        }
            +        i{
            +            width: $font-size-base;
            +            margin-right: 12px;
            +            display: inline-block;
            +        }
            +    }
            +    a{
            +        color: inherit;
            +        &:hover{
            +            color: $link-hover-color;
            +        }
            +    }
            +    
            +}
            +//Grid Layout
            +.agency-grid-style{
            +    
            +    .agency-body-content{
            +        background-color: #f8f8f8;
            +    }
            +    .agency-logo{
            +        width: 80px;
            +        height: 80px;
            +        border-radius: 5px;
            +        overflow: hidden;
            +        margin-right: $grid-gutter-width;
            +    }
            +    .agency-info{
            +        padding: $grid-gutter-width;
            +        display: flex;
            +        flex-wrap: wrap;
            +        border-bottom: 1px solid $border-color;
            +    }
            +    .agency-content{
            +        flex: 1;
            +    }
            +    .agency-box-meta{
            +        padding: $grid-gutter-width;
            +        [class*="agency-box-"]{
            +            line-height: 1;
            +            &:not(:last-of-type){
            +                margin-bottom: 13px;
            +            }
            +        }
            +    }
            +    .agency-box-title{
            +        margin-bottom: 9px;
            +        margin-right: 0;
            +        display: block;
            +    }
            +    .agency-address{
            +        font-size: 13px;
            +    }
            +}
            +
            +//List Layout
            +.agency-list-style{
            +    .agency-inner{
            +        display: flex;
            +        flex-wrap: wrap;
            +        padding: $grid-gutter-width 0;
            +        border: 1px solid $border-color;
            +    }
            +    .agent-box-image{
            +        height: 100%;
            +        img{
            +            height: 100%;
            +        }
            +    }
            +    .agency-header{
            +        
            +        margin: 0 $grid-gutter-width;
            +    }
            +    .agency-body-content{
            +        flex: 1;
            +        padding: $grid-gutter-width 0 0;
            +    }
            +    .agency-logo{
            +        width: 48px;
            +        height: 48px;
            +        border-radius: 50%;
            +        border: 1px solid $border-color;
            +        overflow: hidden;
            +        position: absolute;
            +        bottom: 0;
            +        right: $grid-gutter-width;
            +        transform: translateY(50%);
            +    }
            +    .agency-info{
            +        position: relative;
            +        padding: 0 $grid-gutter-width 18px;
            +        border-bottom: 1px solid $border-color;
            +        margin-bottom: 17px;
            +
            +    }
            +    .agency-box-meta{
            +        @media screen and (max-width:767px){
            +            padding: 0 30px;
            +        }
            +    }
            +    .agency-box-title{
            +        margin-bottom: 0px;
            +    }
            +    @media screen and (min-width:768px) {
            +        .agency-body-content{
            +            padding: 0 0 0 10px;
            +        }
            +        .agency-header{
            +            max-width: 240px;
            +        }
            +        .agency-info{
            +            padding: 0 0 18px;
            +        }
            +    }
            +}
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_archive.scss b/assets/scss/opalestate/_archive.scss
            new file mode 100755
            index 00000000..7c82b822
            --- /dev/null
            +++ b/assets/scss/opalestate/_archive.scss
            @@ -0,0 +1,88 @@
            +//
            +.archive{
            +	.opalestate-head{
            +		margin-bottom: 80px;
            +	}
            +}
            +.opalestate-head {
            +	position: relative;
            +	background-color:$secondary;	
            +	display: flex;
            +	align-items: center;
            +	min-height: 640px;
            +	.opalestate-heading {
            +		color:$white;
            +		text-align:center;
            +		p{
            +			margin-bottom: 50px;
            +		}
            +		a{
            +			color: $white;
            +			&:hover{
            +				color: $link-hover-color;
            +			}
            +		}
            +	}
            +	.opalestate-head-title{ 
            +		color: $white;
            +		margin-bottom: 19px;
            +	}
            +	.search-agent-title{
            +		display: none;
            +	}
            +
            +	.opalestate-head-form{
            +		padding: 0 $grid-gutter-width;
            +		margin-bottom: 21px;
            +	}
            +}
            +.opalestate-single-agent{
            +	min-height: 500px;
            +	align-items: flex-end;
            +	.opalestate-heading{
            +		text-align: left;
            +		& > span{
            +			margin-bottom: 13px;
            +			display: inline-block;
            +		}
            +	}
            +	
            +	.opalestate-head-title{
            +		margin-bottom: 29px;
            +	}
            +}
            +.opalesate-archive-top{
            +	margin-bottom: $grid-gutter-width*2;
            +    padding: 12px 0;
            +    border-style: solid;
            +	border-width: 1px 0 1px;
            +	border-color: $border-color;
            +	position: relative;
            +	.opalestate-results{
            +		line-height: 45px;
            +	}
            +	.opalestate-sortable{
            +		display: inline-block;
            +		.form-control,.select2-selection--single{
            +			padding-top: 8px;
            +		}
            +	}
            +}
            +.opalesate-archive-bottom {
            +	position: relative;
            +}
            +
            +.display-mode{
            +	display: inline-block;
            +	.btn:not(:disabled):not(.disabled){
            +        padding: 0;
            +        background-color: transparent;
            +        color: $body-color;
            +		margin-left: 10px;
            +		font-size: 18px;
            +        &.active,&:hover{
            +            background-color: transparent;
            +            color: $secondary;
            +        }
            +    }
            +}
            diff --git a/assets/scss/opalestate/_dashboard.scss b/assets/scss/opalestate/_dashboard.scss
            new file mode 100755
            index 00000000..6d665b75
            --- /dev/null
            +++ b/assets/scss/opalestate/_dashboard.scss
            @@ -0,0 +1,253 @@
            +.opalestate-admin-box{
            +	margin-bottom:$padding-base*2;
            +	h3 {
            +		border-bottom:1px $border-color solid;
            +		padding-bottom:15px;
            +		padding-top:30px;
            +		font-size:150%;
            +	}
            +}
            +
            +/** CMD BOX 2 */
            +.select2-search-member {
            +	display:flex;
            +	.member-meta {
            +		margin-left:12px;
            +		font-weight:500
            +	}
            +}
            +.cmb2-wrap .field-row-2 .cmb-row  {
            +	display: inline-block;
            +	width: 50%;
            +}
            +
            +.cmb2-wrap .field-row-2 .cmb-row:nth-child(even) > div {
            +	@media screen and (min-width:768px){
            +		padding-left: 12px;
            +	}
            +}
            +.cmb2-wrap  .cmb-td {
            +	padding: 4px 0;
            +}
            +
            +
            +.bg-info {
            +	background-color:#0288d1 !important;
            +}
            +.bg-warning {
            +	background-color:#ffca28!important;
            +}
            +.alert.alert-success{
            +	background: #0F93FA;
            +}
            +
            +.alert.alert-danger{
            +	background: #f55753;
            +}
            +.alert.alert-warning{
            +	background: #ffca28;
            +}
            +/**
            + *
            + * Dashboard Page
            + */
            +
            +@media( max-width: $screen-xs-max ) {
            +
            +	.user-dasboard-sidebar {
            +		display:none;
            +	}
            +	body.active {
            +		.user-dasboard-sidebar{
            +			display:block;
            +		}
            +		margin-left:251px!important;
            +	}
            +	.page-template-user-management {
            +		margin-left:0!important;
            +	}
            +
            +	#show-user-sidebar-btn {
            +		display:block!important;
            +	}
            +}
            +
            +.navbar-left {
            +	display:flex;
            +}
            +.opalestate-user-greeting {
            +	.popup-head  {
            +		float:right;
            +	}
            +	.popup-head a { 
            +		color:$white; 
            +		text-align:right;
            +		img {
            +			width:40px;
            +			border-radius:50%;
            +		}
            +		position:relative;
            +		i { 
            +			padding:12px; 
            +			border-radius:50%;
            +			background:rgba(0, 0, 0, .06 );
            +		}
            +	}
            +
            +	ul {
            +		padding:0;
            +		margin :0 ;
            +		list-style:none;
            +	}
            +	
            +}
            +
            + .dashboard-navbar {
            +
            + 	background-color: $white;
            + 	padding:9px $grid-gutter-width;
            + 	
            +	border-bottom:1px solid $border-color;
            +	ul{
            +		margin-bottom: 0;
            +	}
            + }
            +
            +.card-item {
            +	background-color:$white;
            +	border:solid 1px $border-color;
            +	padding:$padding-base;
            +	i {
            +		background:rgba(0, 0, 0, .18);
            +		padding:15px;
            +		border-radius:50%;
            +	}
            +	h5 {
            +		font-size:200%;
            +		text-align:center;
            +	}
            +	span {
            +		font-weight:700
            +	}
            +}
            +
            +.page-template-user-management {
            +	.opalestate-box{
            +		@media screen and (min-width:768px){
            +			margin-right: $padding-base;
            +		}
            +	}
            +	&.logged-in { margin-left:251px; }
            +	#content {
            +		padding-left:$padding-base*2;
            +		padding-right:$padding-base*2;
            +	}
            +
            +	#show-user-sidebar-btn {
            +	 	display:none;
            +		margin-right:$padding-base;
            +	}
            +	.opalestate-panel-myaccount {
            +		padding-top: $padding-base*3;
            +		padding-bottom: $padding-base*3;
            +	}
            +}
            +.admin-bar{
            +	.opalestate-user-management{
            +		.user-dasboard-sidebar{
            +			padding-top: 32px;
            +		}
            +	}
            +}
            +.opalmembership-dashboard{
            +	.btn-link{
            +		background-color: $secondary;
            +		color: $white;
            +		&:hover{
            +			background-color: $primary;
            +		}
            +	}
            +}
            +.opalestate-user-management {
            +	min-height: 600px;
            +	.property-submission-form{
            +		.opalestate-box{
            +			margin-right: 0;
            +		}
            +	}
            +	.user-dasboard-sidebar {
            +		background-color:$headings-color;
            +		min-height:900px;
            +		position:fixed;
            +		left:0;
            +		width:250px;
            +		height:100%;
            +		z-index:100;
            +		top:0px;
            +	 	.user-dasboard-sidebar-inner{
            +	 		padding-top:20px;
            +	 	}
            +	}
            +	.navbar-brand {
            +		padding:32px $padding-base;
            +	}
            +	
            +
            +	.account-links {
            +		list-style:none;
            +		padding:0;
            +		margin : 0; 
            +		a {
            +			padding:8px 20px;
            +			width:100%;
            +			display:block;
            +			font-weight:500	;
            +			i {
            +				margin-right:6px;
            +				color:$body-color;
            +			}
            +			color:$body-color;
            +			&:hover {
            +				background-color:$primary;
            +
            +			}
            +		}
            +	}
            +
            +	.site-main {
            +		padding-top:$padding-base;
            +		$padding-bottom:$padding-base;
            +	}
            +}
            +
            +//my reviews
            +.opalestate-my-reviews{
            +	.commentlist{
            +		margin: 0;
            +	}
            +	.meta{
            +		margin-bottom: 10px;
            +	}
            +	.opalestate-review__ratings{
            +		margin-bottom: 0;
            +	}
            +}
            +.opalestate-my-reviews-item_property-name{
            +	margin-bottom: 5px;
            +}
            +.opalestate-my-reviews-item_property-view{
            +	font-size: 12px;
            +	font-style: italic;
            +}
            +
            +//my property
            +.my-property-list{
            +	.entry-content{
            +		width: 100%;
            +	}
            +}
            +
            +
            +.dashboard {
            +	
            +}
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_elements.scss b/assets/scss/opalestate/_elements.scss
            new file mode 100755
            index 00000000..3eed54dc
            --- /dev/null
            +++ b/assets/scss/opalestate/_elements.scss
            @@ -0,0 +1,975 @@
            +.floating-keep-top {
            +	position: fixed;
            +    top: 0;
            +    width:100%;
            +    background:#FFF;
            +	z-index:999;
            +	transition: all 1s ease-in-out;
            +}
            +.admin-bar{
            +	.floating-keep-top{
            +		top: 32px;
            +	}
            +}
            +.hide {
            +    display: none !important;
            +}
            +.highlight-text{
            +	font-weight: $headings-font-weight;
            +}
            +//Property status
            +ul.property-status{
            +	padding: 0;
            +	margin: 0;
            +	display: inline-block;
            +	li{
            +		list-style: none;
            +		display: inline-block;
            +		&:not(:last-child){
            +			margin-right: 5px;
            +		}
            +	}
            +}
            +//single stick bars
            +.keep-top-bars{
            +	top: -70px;
            +	transition: all 1s ease-in-out;
            +	border-bottom: 1px solid $border-color;
            +	ul{
            +		margin: 0;
            +		align-items: center;
            +		&:not(.opalestate-scroll-elements){
            +			padding: 10px 0;
            +		}
            +		li{
            +			&:not(:last-child){
            +				margin-right: 50px;
            +			}
            +		}
            +	}
            +	&.floating-keep-top{
            +		border-bottom: none;
            +		box-shadow: $box-shadow-base;
            +	}
            +		
            +	.single-property-buttons{
            +		flex: 1;
            +		text-align: right;
            +		a{
            +			position: relative;
            +			margin-left: 20px;
            +			text-transform: capitalize;
            +			i{
            +				margin-right: 18px;
            +				padding-right: 20px;
            +			}
            +			&::before{
            +				content: "";
            +				width: 52px;
            +				position: absolute;
            +				top: 0;
            +				left: 0;
            +				height: 100%;
            +				background-color: transparent;
            +				box-shadow: $box-shadow-base;
            +			}
            +		}
            +	}
            +}
            +.opalestate-scroll-elements{
            +	a:not(.btn-primary){
            +		display: block;
            +		padding: 21px 0 17px;
            +		border-bottom: 3px solid transparent;
            +		color: inherit;
            +		transition: all .5s ease-in-out;
            +		&:focus, &:hover{
            +			border-color: $primary;
            +			color: inherit;
            +		}
            +	}
            +}
            +
            +
            +//Rating star
            +.opalestate-rating__stars{
            +	position: relative;
            +    overflow: hidden;
            +    height: $font-size-base;
            +    font-size: $font-size-base;
            +	width: calc(#{$font-size-base}*5 - 5px);
            +	line-height: 1;
            +	
            +	&::before{
            +		font-family:'FontAwesome';
            +		font-size: inherit;
            +		text-rendering: auto;
            +		content: "\f005\f005\f005\f005\f005";
            +		opacity: 0.5;
            +		position: absolute;
            +		top: 0;
            +		left: 0;
            +	}
            +	span{
            +		position: relative;
            +		overflow: hidden;
            +		display: block;
            +		height: 100%;
            +		color: transparent;
            +		padding-top: 20px;
            +		&::before{
            +			font-family:'FontAwesome';
            +			font-size: inherit;
            +			text-rendering: auto;
            +			content: "\f005\f005\f005\f005\f005";
            +			color: #f6be15;
            +			position: absolute;
            +			top: 0;
            +			left: 0;
            +			width: calc(#{$font-size-base}*5);
            +		}
            +	}
            +}
            +p.stars {
            +	a {
            +		position: relative;
            +		height: 1em;
            +		width: 1em;
            +		text-indent: -999em;
            +		display: inline-block;
            +		text-decoration: none;
            +
            +		&::before {
            +			display: block;
            +			position: absolute;
            +			top: 0;
            +			left: 0;
            +			width: 1em;
            +			height: 1em;
            +			line-height: 1;
            +			font-family: "FontAwesome";
            +			content: "\f006";
            +			text-indent: 0;
            +		}
            +
            +		&:hover {
            +			~ a::before {
            +				
            +				content: "\f006";
            +			}
            +		}
            +	}
            +
            +	&:hover {
            +		a {
            +			&::before {
            +				
            +				content: '\f005';
            +			}
            +		}
            +	}
            +
            +	&.selected {
            +		a.active {
            +			&::before {
            +				
            +				content: '\f005';
            +			}
            +
            +			~ a::before {
            +				
            +				content: '\f006';
            +			}
            +		}
            +
            +		a:not( .active ) {
            +			&::before {
            +				
            +				content: '\f005';
            +			}
            +		}
            +	}
            +}
            +
            +//mortgage
            +.opalestate-mortgage-chart-svg{
            +	display: inline-block;
            +	overflow: hidden;
            +	margin-bottom: 0;
            +	&::after{
            +		content:"";
            +		position: absolute;
            +		width: 60px;
            +		height: 60px;
            +		transform: translate(-50%, -50%);
            +		border-radius: 50%;
            +		top: 50%;
            +		left: 50%;
            +		background-color: #fff;
            +	}
            +}
            +.opalestate-loan-amount{
            +	display: none;
            +}
            +
            +
            +// Form group
            +.opal-form-group{
            +	margin-top: 16px;
            +		label{
            +			margin-bottom: 0;
            +			cursor: pointer;
            +			display: block;
            +			padding-left: 25px;
            +		}
            +}
            +
            +/** 
            +* SOCIAL ICONS 
            +**/
            +.opalestate-social-icons{
            +	margin:15px -30px 0 -30px;
            +	border-top: 1px solid $border-color;
            +	padding: 0 $theme-padding;
            +	[class^="opalestate-social-"]{
            +		font-size: 13px;           
            +		color: $body-color;               
            +		display:inline-block;                
            +		margin: 10px 5px 0 0;
            +		overflow: hidden;
            +		text-decoration: none; 
            +		text-align: center;       
            +		vertical-align: top;
            +		line-height: 32px;                        
            +		@include square(34px);
            +		background: $border-color;
            +		transition: all 0.2s ease-out 0s;
            +		border-radius: 50%;
            +		&:last-of-type{
            +			margin-right: 0;
            +		}
            +		&:hover{
            +			border-color: $link-hover-color;
            +			color: $link-hover-color;
            +		}
            +	} 
            +	.opalestate-social-white{
            +		background: #FFFFFF;
            +		color: $body-color;
            +		border: 1px solid $border-color;
            +	}   
            +	.opalestate-social-outline{
            +		background: transparent;
            +		color: #000;
            +		border: 1px solid #000;
            +	}   
            +	.opalestate-social-outline-light{
            +		background: transparent;
            +		color: #FFF;
            +		border: 1px solid #FFFFFF;
            +		&:hover{
            +			background: #FFF;
            +			color: #000;
            +			border-color: #000;
            +		}
            +	}
            +	&:first-child{
            +		[class*="opalestate-social-"]{
            +			margin-top: 0;
            +		}
            +	}
            +	&:last-child{
            +		[class*="opalestate-social-"]{
            +			margin-bottom: 0;
            +		}
            +	}
            +	&.opalestate-sicolor{
            +		[class*="opalestate-social-"]{
            +			color: #FFFFFF;
            +		}
            +	}
            +}
            +/**
            + * Tabs
            + */
            + .opalestate-tab-head{
            +	background-color:$primary;
            + }
            + 	.tab-item {
            +		 color: $white;
            +		 border-bottom: 3px solid transparent;
            +		 transition: all .5s ease-in-out;
            + 		&.active,&:hover {
            +		border-color: $secondary;
            +		color: $white;
            + 		}
            +		padding: 14px 18px 15px;
            +		font-weight: $headings-font-weight;
            + 	}
            + 	.opalestate-tab-content {
            + 		display: none;
            + 		&.active {
            + 			display: block;
            + 		}
            + 		clear:both;
            + 	}
            +
            +
            +.opalmembership-login-form-wrapper{
            +	text-align: center;
            +}
            +
            +.list-tabs {
            +	margin-bottom: $padding-base;
            +	background-color: $white;
            +	padding: 0;
            +	ul {
            +		padding: 0;
            +		margin: 0;
            +		li {
            +			text-transform: uppercase;
            +			display: inline-block;
            +			position: relative;
            +			 
            +			a {
            +				display: block;
            +				padding: 5px 20px;
            +			}
            +			&.active,
            +			&:hover {
            +				
            +				a {
            +					color: $white;
            +					background-color: $primary;
            +				}
            +			}
            +		}
            +	}
            +} 
            +/**
            + * end Tabs
            + */
            +//Status Label
            +.property-group-label, 
            +.agency-label {
            +	position: absolute;
            +	z-index: 1;
            +	top: $padding-base;
            +	left: 20px;
            +	line-height: 1;
            +}
            +
            +.property-group-status {
            +	position: absolute;
            +	z-index: 1;
            +	top: $padding-base;
            +	right: 20px;
            +	line-height: 1;
            +}
            +
            +.property-group-status + .property-meta-bottom {
            +	top: 45px;
            +    right: 20px;
            +    z-index: 9;
            +} 
            +
            +.agency-header{
            +	position: relative;
            +}
            +
            +// label 
            +.label {
            +	display: inline-block;
            +	padding: 3px 10px;
            +	line-height: 14px;
            +	font-size: 10px;
            +	font-weight: 500;
            +	margin-bottom: 0;
            +	text-transform: uppercase;
            +	text-align: center;
            +	white-space: nowrap;
            +	vertical-align: baseline;
            +	color: $white;
            +}	
            +
            +.property-label, 
            +.property-status-item  {
            +	margin:0;
            +	padding:0;
            +	list-style: none;
            +	line-height: 14px;
            +	&.property-status-for-rent,
            +	&.property-status-for-sale {
            +		background-color:$primary;
            +	}
            +	.property-label-item:not(last-child){
            +		margin-right:5px;
            +	}
            +}
            +
            +.property-label-rented {
            +   background-color: #2048f6;
            +   color: $white;
            +}
            +
            +.property-label-sold {
            +    background-color: #fee882;
            +    color: $white;
            +}
            +
            +.label-featured {
            +	background-color:$secondary;
            +	color:$white;
            +	margin-bottom: 5px;
            +}
            +
            +.single {
            +	.label-featured {
            +		margin-bottom: 0;
            +		margin-right: 5px;
            +    }
            +}
            +
            +.label-danger {
            +	background-color:$primary;
            +	color:$white;
            +}
            +
            +//// 
            +.property-meta-list {
            +	> li {
            +		vertical-align: middle;
            +	}
            +	.icon-box {
            +		display: inline-block;
            +	}
            +	.info-meta{
            +		display: inline-block;
            +	}
            +}
            +
            +/// map infor view 
            +.map-info-preview{
            +	position: relative;
            +	padding: $grid-gutter-width;
            +	background-color:#FFFFFF;
            +	margin-bottom: 15px;
            +	max-width: 300px;
            +	box-shadow: $box-shadow-base;
            +	&:before {
            +		@include triangle( bottom,0px, $white, 20px );
            +		transform: translateX(-50%);
            +		left: 50%;
            +		bottom: -14px;
            +		margin-left: -34px;
            +	}
            +	a img{
            +		max-width: 240px;
            +		width: 240px;
            +	}
            +	.media-top{
            +		position: relative;
            +	}
            +	.property-status{
            +		top: 10px;
            +		left: 10px;
            +		position: absolute;
            +		line-height: 1;
            +	}
            +	.label-property{
            +		visibility: hidden;
            +	}
            +	.info-container{
            +		.prop-title {
            +			text-transform: uppercase; 
            +			margin: 15px 0 8px;
            +		}
            +		p {
            +			line-height: 22px;
            +		}
            +		.prop-address {
            +			 
            +		}
            +	}
            +	.property-meta-list.list-inline {
            +		border-top: 1px solid $border-color;
            +		padding: 0;
            +		display: flex;
            +		flex-wrap: wrap;
            +		> li {
            +			flex-basis: 50%;
            +			padding: 0;
            +			margin: $padding-base 0 0;
            +			i{
            +				width: 20px;
            +
            +			}
            +		}
            +	}
            +	.arrow-down{
            +		border-style: solid;
            +		border-width: 10px 10px 0;
            +		bottom: -13px;
            +		height: 0;
            +		left: 112px;
            +		position: absolute;
            +		width: 0;
            +		border-color:$primary;
            +		display: none;
            +	}
            +}
            +
            +.opalestate-map-preview-wrap {
            +	.gm-style img {
            +		max-width: inherit !important;
            +	}
            +}
            +
            +.infoBox {
            +	> img {
            +		position: absolute!important;
            +		z-index: 99;
            +		right: -5px;
            +		top: -10px;
            +	}
            +}
            +
            +.opalestate-popup{
            +	position: relative;
            +	.popup-head {
            +		position:relative;
            +		> span {
            +			cursor: pointer;
            +		}
            +		.notify {
            +			background-color:#00bcd4;
            +			padding:1px 6px;
            +			border-radius:50%;
            +			position:absolute;
            +			top:-10px;
            +			right:0px;
            +			font-size:8px;
            +			color:$white;
            +			&.active {
            +				top:auto;
            +				bottom:-10px;
            +				padding:5px;
            +				background-color:$primary
            +			}
            +		}
            +	}
            +
            +	.popup-body{
            +		display: none;
            +		position:absolute;
            +		z-index: 999;
            +		min-width: 450px;
            +		top: 30px;
            +		margin:0 0 0 -194px;
            +		padding: $grid-gutter-width;
            +		background-color: $white;
            +		box-shadow: $box-shadow-base;
            +		h6 {
            +			margin-bottom: 15px;
            +		}
            +		label {
            +			text-transform: uppercase;
            +		}
            +		button {
            +			margin-top: 20px;
            +		}
            +		
            +		.account-dashboard-content{
            +			padding: $grid-gutter-width;
            +			background-color: $white;
            +			box-shadow: $box-shadow-base;
            +			position: relative;
            +			&:before {
            +				@include triangle( top,0px, $white, 20px );
            +				transform: translateX(-50%);
            +				left: 50%;
            +				top: -14px;
            +			}
            +		}
            +		
            +	}
            +	&.active .popup-body{
            +		display: block;
            +	}
            +	&.hover-align-right:hover .popup-body {
            +		display:block;
            +		right:0;
            +		padding-top:30px;
            +		min-width: 250px;
            +		.account-dashboard-content{
            +			&:before {
            +				right:-15px;
            +				left:auto;
            +			}
            +		}
            +
            +	}
            +	
            +	.popup-close{
            +		position:absolute;
            +		top: 10px;
            +		@include rtl-right(15px);
            +		color:$primary;
            +		cursor: hand;cursor:pointer;
            +	}
            +}
            +//Pagination
            +.pagination {
            +	li{
            +        display: block;
            +        min-width: 40px;
            +        text-align: center;
            +        padding: 5px $padding-base;
            +        font-weight: 500;
            +        color: $body-color;
            +        &.current, &:hover{
            +			background-color: $primary;
            +			a{
            +				color: $white;
            +			}
            +        }
            +	}
            +	.nav-links{
            +		display: flex;
            +		flex-wrap: wrap;
            +	}
            +}
            +
            +//// opalestate-dropdown
            +
            +.opalestate-dropdown {
            +	position:relative;
            +	.dropdown-body {
            +		position:absolute;
            +		display:none;
            +		background:red;
            +		min-width:250px;
            +		right:0;
            +		top:50px;
            +	}
            +	&:hover {
            +		.dropdown-body {
            +			display:block;
            +		}
            +	}
            +}
            +
            +//Agent
            +// display in single package
            +.agent-box-list {
            +	.inner {
            +		display:flex;
            +		.agent-preview { 
            +			width:80px;
            +			margin-right:$padding-base;
            +			img { border-radius:50%; }
            +		}
            +		border-bottom:solid 1px $border-color;
            +		padding-bottom:$padding-base*2;
            +	}
            +	.opalestate-social-icons {
            +		padding-top:$padding-base; 
            +	}
            +}
            +
            +.single-property-sidebar {
            +	.agent-box-list{
            +		.inner {
            +			border-bottom:0;
            +		}
            +		.opalestate-social-icons {
            +			border-bottom: 1px solid $border-color;
            +			padding-bottom:$padding-base;
            +			padding-top: 5px;
            +		}
            +
            +	}
            +}
            +
            +.agent-box-image{
            +	overflow: hidden;
            +}
            +.property-agent-info{
            +	.team-header{
            +		text-align: center;
            +		border: 1px solid $border-color;
            +	}
            +}
            +.property-agent-contact{
            +	.agent-preview{
            +		margin-bottom: 0;
            +	}
            +	.team-header{
            +		margin-bottom: $grid-gutter-width;
            +	}
            +}
            +.team-header {
            +	position: relative;
            +	.agent-label {
            +		position: absolute;
            +		text-transform: uppercase;
            +		padding: 0 10px;
            +		color: $white;
            +		margin: 0;
            +		font-size: 10px;
            +		font-weight: 500;
            +		li {
            +			list-style: none;
            +		}
            +	}
            +	.agent-featured{
            +		.agent-label{
            +			top: 0;
            +			left: 0;
            +			background-color: $primary;
            +		}
            +	}
            +	.agent-levels{
            +		.agent-label{
            +			bottom: 0;
            +			left: 0;
            +			background-color: $secondary;
            +		}
            +	}
            +}
            +.agent-box-title{
            +	border-bottom: 1px solid $border-color;
            +	padding-bottom: 20px;
            +	//margin-bottom: 28px;
            +}
            +.agent-preview{
            +	margin-bottom: $grid-gutter-width;
            +	position: relative;
            +	.agent-avatar{
            +		position: absolute;
            +		bottom: 10px;
            +		left: 10px;
            +		width: 35px;
            +		border-radius: 50%;
            +	}
            +}
            +
            +.agent-box-job{
            +	display: none;
            +}
            +
            +.agent-box-meta{
            +	color: $body-color-light;
            +	div[class*="agent-box-"]{
            +		line-height: 1;
            +		padding: 8px 1px;
            +		&:first-of-type{
            +			padding-top: 0;
            +		}
            +		&:last-of-type{
            +			padding-bottom: 0;
            +		}
            +		&:not(:last-of-type){
            +			//border-bottom: 1px solid $border-color;
            +		}
            +		i{
            +			width: $font-size-base;
            +			margin-right: 6px;
            +		}
            +	}
            +	a{
            +		color: inherit;
            +	}
            +	h4 {
            +		padding-top:0;
            +	}
            +}
            +.gallery-summery-style  {
            +
            +	display:flex;
            +	flex-wrap:wrap;
            +	a {
            +		display:block;
            +		width:20%;
            +		height:120px;
            +		background-size:cover;
            +		background-repeat:no-repeat;
            + 
            +	}
            +}
            +
            +//Featured Properties
            +.my-featured-section{
            +	.opalestate_property{
            +		margin-right: 1px;
            +	}
            +}
            +
            +
            +//Floor plans
            +.property-floorplans-session, .tabl-simple-style{ //tabs outline
            +	.opalestate-tab-head{
            +		line-height: 1;
            +		border-bottom: 1px solid $border-color;
            +		margin-bottom: 16px;
            +		margin-top: 0;
            +		background-color: transparent;
            +	}
            +	.tab-item{
            +		background-color: transparent;
            +		padding: 0;
            +		color: $headings-color;
            +		display: inline-block;
            +		padding-bottom: 19px;
            +		font-weight: $headings-font-weight;
            +		border-bottom: 3px solid transparent;
            +		margin-bottom: -2px;
            +		&:not(:last-of-type){
            +			margin-right: 28px;
            +		}	
            +		&.active, &:hover{
            +			background-color: transparent;
            +			color: $headings-color;
            +			border-color: $secondary;
            +		}
            +	}
            +}
            +.plan-name,.plan-content{
            +	display: none;
            +}
            +.plan-image{
            +	padding: 24px;
            +}
            +
            +//Property categories
            +.property-category{
            +	position: relative;
            +	overflow: hidden;
            +	.static-content{
            +		padding: $grid-gutter-width;
            +		position: absolute;
            +		top: 0;
            +		width: 100%;
            +		height: 100%;
            +		display: flex;
            +		flex-wrap: wrap;
            +		align-items: center;
            +		a{
            +			color: $white;
            +		}
            +	}
            +	.property-category-count{
            +		color: $secondary;
            +	}
            +	.property-category-title{
            +		margin-bottom: 10px;
            +	}
            +	.property-category-info{
            +		flex-basis: 100%;
            +	}
            +	.category-overlay{
            +		position: absolute;
            +		top: 0;
            +		width: 100%;
            +		height: 100%;
            +		display: block;
            +		z-index: 2;
            +	}
            +	&:hover{
            +		.property-category-bg{
            +			transform: scale(1.1);
            +			&::before{
            +				background-color: rgba(0, 0, 0, 0.5);
            +			}
            +		}
            +	}
            +}
            +.property-category-bg{
            +	background-repeat: no-repeat;
            +	background-size: cover;
            +	position: relative;
            +	display: block;
            +	height: 100%;
            +	min-height: 340px;
            +	transform: scale(1);
            +	transition: opacity 0.5s ease, transform 1s cubic-bezier(0, 0, 0.44, 1.18), -webkit-transform 1s cubic-bezier(0, 0, 0.44, 1.18);
            +	background-position: center center;
            +	&::before{
            +		content: "";
            +		position: absolute;
            +		width: 100%;
            +		height: 100%;
            +		background-color: rgba(0, 0, 0, 0.35);
            +		top: 0;
            +		left: 0;
            +	}
            +}
            +
            +
            +
            +.property-city{
            +	position: relative;
            +	overflow: hidden;
            +	.static-content{
            +		padding: $grid-gutter-width;
            +		position: absolute;
            +		top: 0;
            +		width: 100%;
            +		height: 100%;
            +		display: flex;
            +		flex-wrap: wrap;
            +		align-items: center;
            +		a{
            +			color: $white;
            +		}
            +	}
            +	.property-city-count{
            +		color: $secondary;
            +	}
            +	.property-city-title{
            +		margin-bottom: 10px;
            +	}
            +	.property-city-info{
            +		flex-basis: 100%;
            +	}
            +	.city-overlay{
            +		position: absolute;
            +		top: 0;
            +		width: 100%;
            +		height: 100%;
            +		display: block;
            +		z-index: 2;
            +	}
            +	&:hover{
            +		.property-city-bg{
            +			transform: scale(1.1);
            +			&::before{
            +				background-color: rgba(0, 0, 0, 0.5);
            +			}
            +		}
            +	}
            +}
            +.property-city-bg{
            +	background-repeat: no-repeat;
            +	background-size: cover;
            +	position: relative;
            +	display: block;
            +	height: 100%;
            +	min-height: 340px;
            +	transform: scale(1);
            +	transition: opacity 0.5s ease, transform 1s cubic-bezier(0, 0, 0.44, 1.18), -webkit-transform 1s cubic-bezier(0, 0, 0.44, 1.18);
            +	background-position: center center;
            +	&::before{
            +		content: "";
            +		position: absolute;
            +		width: 100%;
            +		height: 100%;
            +		background-color: rgba(0, 0, 0, 0.35);
            +		top: 0;
            +		left: 0;
            +	}
            +}
            +
            +#opalestate-map-preview .cluster img + div {
            +	line-height: 30px !important;
            +}
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_form.scss b/assets/scss/opalestate/_form.scss
            new file mode 100755
            index 00000000..579b5e99
            --- /dev/null
            +++ b/assets/scss/opalestate/_form.scss
            @@ -0,0 +1,481 @@
            +
            +/*
            + *
            + */
            +.opalestate-search-form{
            +	&:not([class*="opalestate-search-form--vertical"]){
            +		background-color: $white;
            +		padding: $theme-padding/2 $theme-padding ;
            +		&.opalestate-search-agents-form {
            +			border:1px solid $border-color;
            +			margin-bottom: $theme-margin;
            +		}
            +	}
            +	.btn-search, .status-item, .opalestate-collapse-btn {
            +		margin-top: 45px;
            +	}
            +
            +	&.hidden-labels{
            +		.opalestate-label{
            +			display: none;
            +		}
            +		.input-search-city {
            +			.opalestate-popup {
            +				top: 20%;
            +			}
            +		}
            +		.select2-container,.btn-search,.form-control,.opal-collapse-button,.input-group-number {
            +			margin: $padding-base 0;
            +		}
            +		.opal-slide-ranger{
            +			.slide-ranger-label{
            +				display: block;
            +				line-height: 2;
            +			}
            +		}
            +		.map-remove { top: 10px;}
            +	}
            +	.opalestate-label{
            +		font-weight: $headings-font-weight;
            +		display: block;
            +		color: $headings-color;
            +		line-height: 1;
            +		margin-top: $theme-margin/2;
            +		margin-bottom: $theme-margin/2;
            +	}
            +	h6 {
            +		margin: 0;
            +	}
            +	.searchbox-top {
            +		border-bottom:solid 1px $border-color;
            +		margin-bottom: $padding-base;
            +		text-transform: uppercase;
            +	}
            +	.select2-container,.btn-search,.form-control,.list-property-status,.opal-collapse-button,.input-group-number {
            +		margin-bottom: $padding-base;
            +	}
            +	
            +	.opal-slide-ranger{
            +		padding: ceil($padding-base/2) 0;
            +		.slide-ranger-label{
            +			display: block;
            +			line-height: 1;
            +		}
            +	}
            +	.list-property-status{
            +		.status-item{
            +			cursor: pointer;
            +			text-align: center;
            +			flex: 1;
            +			padding: 9px 0 6px;
            +			color: $white;
            +			background-color: $secondary;
            +			transition: all ease-in-out 0.5s;
            +			&:hover,&.active{
            +				background-color: $primary;
            +			}
            +		}
            +	}
            +	.btn-search {
            +		width: 100%;
            +		text-align: center;
            +		i{
            +			margin-right: 5px;
            +		}
            +	}
            +	.opal-slide-ranger{
            +		@media screen and (max-width:$screen-sm){
            +			margin: $grid-gutter-width/2 0;
            +		}
            +	}
            +}
            +.opalestate-archive-agency,
            +.opalestate-archive-search-block,
            +.post-type-archive-opalestate_agent{
            +	.opalestate-search-form {
            +		&:not([class*="opalestate-search-form--vertical"]) {
            +			margin: 0 -30px;
            +		}
            +	}
            +}
            +
            +.map-remove {
            +	display: none;
            +	position: absolute;
            +	right: 50px;
            +	top: 40px;
            +}
            +.opalestate-search-opal-map {
            +	&.active {
            +		.map-remove {
            +			display: block;
            +			&:focus,
            +			&:hover {
            +				cursor: pointer;
            +			}
            +		}
            +		input[value=""] + .map-remove {
            +			display: none;
            +		}
            +	}
            +}
            +
            +[class*="opalestate-search-form--vertical"]{
            +	.btn-search{
            +		margin-top: 15px;
            +	}
            +	.opalestate-label {
            +		margin-top: 10px;
            +		margin-bottom: 10px;
            +	}
            +}
            +.search-more-options{
            +	position: relative;
            +	margin: $padding-base 0 5px;
            +	line-height: 1;
            +	
            +}
            +
            +a.opal-collapse-button{
            +	display: block;
            +	font-weight: 600;
            +	&:before {
            +		font-family: "Font Awesome 5 Free";
            +		content: '\f0fe';
            +		padding-right:5px;
            +		color: $primary;
            +		transition: all 0.5s ease;
            +	}
            +	&.show{
            +		color: $link-hover-color;
            +		&:before {
            +			content: '\f146';
            +		}
            +	}
            +}
            +
            +
            +.more-options-container{
            +	margin-top: $padding-base;
            +}
            +.more-options-items{
            +	display: inline-block;
            +	width: 100%;
            +
            +}
            +.opal-collapse-container{
            +    width: 100%;
            +	display: none;
            +}
            +button.opal-collapse-button{
            +	transition: all 0.5s;
            +	width: 100%;
            +	i::before{
            +		display: block;
            +		transition: all 0.5s;
            +	}
            +	&:hover,&.show{
            +		outline: none;
            +	}
            +	&:focus{
            +		outline: none;
            +	}
            +	&.show{
            +		i::before{
            +			transform: rotate(180deg);
            +			
            +		}
            +	}
            +}
            +.more-options-item{
            +	width: 25%;
            +	float: left;
            +	margin-bottom: $padding-base;
            +	@media(max-width: 767px) {
            +		width: 100%;
            +	}
            +}
            +.input-search-city {
            +	position:relative;
            +	.opalestate-popup {
            +		position: absolute;
            +		top: 40px;
            +		right: 16px;
            +	}
            +}
            +
            +//custom checkbox
            +.form-item--types{
            +	.group-item{
            +		display: block;
            +		position: relative;
            +		padding-left: 0px;
            +		margin-bottom: 15px;
            +		cursor: pointer;
            +		-webkit-user-select: none;
            +		-moz-user-select: none;
            +		-ms-user-select: none;
            +		user-select: none;
            +		line-height: 1;
            +		.custom-checkbox-label{
            +			z-index: -1;
            +		}
            +		input[type="checkbox"]{
            +			position: absolute;
            +			opacity: 0;
            +			cursor: pointer;
            +			&:checked ~ .custom-checkbox-label{
            +				background-color: $primary;
            +				&::after{
            +					display: block;
            +				}
            +			}
            +		}
            +		&:hover{
            +			input ~ .custom-checkbox-label{
            +				background-color: #ccc;
            +			}
            +	
            +		}
            +	}
            +	
            +}
            +
            +.opalestate-search-form--vertical {
            +	.more-options-item {
            +		float:none;
            +		width:100%;
            +	}
            +}
            +
            +.more-options-label{
            +	display: inline-block;
            +    position: relative;
            +    padding-left: 23px;
            +    margin-bottom: 0px;
            +    cursor: pointer;
            +    -webkit-user-select: none;
            +    -moz-user-select: none;
            +    -ms-user-select: none;
            +	user-select: none;
            +	input[type="checkbox"]{
            +		position: absolute;
            +		opacity: 0;
            +		cursor: pointer;
            +		&:checked ~ .custom-checkbox-label{
            +			background-color: $secondary;
            +			&::after{
            +				display: block;
            +			}
            +		}
            +	}
            +	&:hover{
            +		input ~ .custom-checkbox-label{
            +			background-color: #ccc;
            +		}
            +
            +	}
            +}
            +.custom-checkbox-label{
            +	position: absolute;
            +	top: 0;
            +	left: 0;
            +	height: 15px;
            +	width: 15px;
            +	background-color: #eee;
            +	&::after{
            +		content: "";
            +		position: absolute;
            +		display: none;
            +		left: 5px;
            +		top: 2px;
            +		width: 5px;
            +		height: 8px;
            +		border: solid $white;
            +		border-width: 0 2px 2px 0;
            +		-webkit-transform: rotate(45deg);
            +		-ms-transform: rotate(45deg);
            +		transform: rotate(45deg);
            +	}
            +
            +}
            +//status bar 2
            +.search-status-bar--2{
            +	.list-property-status{ 
            +		padding:0;
            +		margin: 0;
            +		.status-item {
            +			font-size: 100%;
            +			padding: 8px 35px 5px 35px;
            +			color: $headings-color;
            +			border-width: 1px 0 1px;
            +			margin-right: 0;
            +			margin-top: $padding-base;
            +			border-style: solid;
            +			border-color: transparent;
            +			position: relative;
            +			font-weight: $headings-font-weight;
            +			flex: unset;
            +			background-color: transparent;
            +			&:last-child{
            +				margin-right: 0;
            +			}
            +			@media screen and (max-width:767px){
            +				margin-right: $theme-margin;
            +			}
            +			&.active,&:hover {
            +				background-color: transparent;
            +				color: $link-hover-color;
            +				border-color: $link-hover-color;
            +			}
            +			&.active{
            +				&::after{
            +					content: "";
            +					border-top: 8px solid;
            +					border-right: 9px solid transparent;
            +					border-left: 9px solid transparent;
            +					border-bottom: 0;
            +					position: absolute;
            +					top: 100%;
            +					left: 50%;
            +					transform: translateX(-50%);
            +				}
            +			}
            +		}
            +	}
            +}
            +
            +//Form vertical
            +.opalestate-search-form--vertical{
            +	.select2-container, .input-group-number{
            +		margin-top: 0;
            +	}
            +	.opalestate-label{
            +		display: inline-block;
            +	}
            +}
            +
            +//Form vertical2
            +.opalestate-search-form--vertical-2{
            +	padding-top: 0;
            +	padding-bottom: 0;
            +	.opalestate-label{
            +		display: none;
            +	}
            +	.input-group-number{
            +		margin-top: 15px;
            +	}
            +	h6{
            +		margin-bottom: 5px;
            +	}
            +	.input-search-city{
            +		.opalestate-popup{
            +			top: 20%;
            +		}
            +	} 
            +	.opal-form-content{
            +		.form-item:not(:last-of-type){
            +			border-bottom: 1px solid $border-color;
            +			padding-bottom: $padding-base;
            +			margin-bottom: $grid-gutter-width; 
            +		}
            +	}
            +	.more-options-items {
            +		.more-options-item {
            +			width: 100%;
            +		}
            +	}
            +}
            +
            +
            +.input-group-number{
            +	display: inline-flex;
            +	align-items: center;
            +	border: 1px solid $border-color;
            +	padding: $input-padding-y $input-padding-x;
            +	height: $input-height;
            +	width: 100%;
            +	position: relative;
            +	background-color: $white;
            +	i[class*="icon-property-"]{
            +        margin-right: $input-padding-x;
            +	}
            +	.form-control{
            +		padding: 0;
            +		margin: 0;
            +		height: auto;
            +		border: none;
            +		flex: 1;
            +		background-color: transparent;
            +		&:focus{
            +			background-color: transparent;
            +		}
            +	}
            +	.btn-actions{
            +		position: absolute;
            +		right: 0;
            +		top: 0;
            +		line-height: $input-height;
            +		span{
            +			padding-left: $input-padding-x;
            +			padding-right: $input-padding-x;
            +            border-left: 1px solid $border-color;
            +            &:hover{
            +                color: $secondary;
            +                cursor: pointer;
            +            }
            +		}
            +	}
            +}
            +
            +//Form v6
            +.opalestate-search-form--advanced-6{
            +	display: flex;
            +	.opalestate-search-form__item:not(:first-child){
            +        flex: 1;
            +    }
            +    .opalestate-search-form__item:first-child{
            +        flex-basis: 12%;
            +        .select2-selection--single{
            +            padding-left: 10px;
            +            border-right: 0;
            +            .select2-selection__rendered{
            +                padding: 0;
            +            }
            +        }
            +    }
            +    .btn-search{
            +        width: 128px;
            +    }
            +}
            +
            +//Search Agent
            +.search-agent-title{
            +	margin-bottom: 0;
            +}
            +//
            +.select2-container{
            +	&.select2-container--default .select2-selection--single {
            +		display: block;
            +		width: 100%;
            +		height: $input-height;
            +		padding: $input-padding-y $input-padding-x;
            +		font-size: $font-size-base;
            +		line-height: $input-line-height;
            +		color: $input-color;
            +		background-color: $input-bg;
            +		border: 1px solid $input-border-color; 
            +		background-clip: padding-box;
            +		border-radius: 0;
            +		.select2-selection__arrow {
            +			height: $input-height;
            +			width: 40px;
            +		}
            +	}
            +	.select2-dropdown{
            +		border-color: $border-color;
            +	}
            +}
            +
            +
            +
            diff --git a/assets/scss/opalestate/_layout.scss b/assets/scss/opalestate/_layout.scss
            new file mode 100755
            index 00000000..89f067e1
            --- /dev/null
            +++ b/assets/scss/opalestate/_layout.scss
            @@ -0,0 +1 @@
            +/** list **/
            diff --git a/assets/scss/opalestate/_modules.scss b/assets/scss/opalestate/_modules.scss
            new file mode 100755
            index 00000000..473d4c0c
            --- /dev/null
            +++ b/assets/scss/opalestate/_modules.scss
            @@ -0,0 +1,70 @@
            +@keyframes spinner-border {
            +	to { transform: rotate(360deg); }
            +  }
            +
            +
            +//favorite button
            +.property-toggle-favorite {
            +	@include transition(.5s);
            +	cursor: pointer;
            +	&:hover {
            +		color: $link-hover-color;
            +	}
            +}
            +
            +/// split search ///
            +header#masthead {
            +	position:relative;
            +}
            +
            +.pull-right {
            +	float: right!important;
            +}
            +.ajax-map-search-split{
            +	.split-maps-container{
            +		@media screen and (min-width:1200px){
            +			padding-left: 0;
            +		}
            +	}
            +	.opalestate-search-form{
            +		margin: 0;
            +		padding: $padding-base 0;
            +	}
            +}
            +.split-maps-container {
            +	@media screen and (min-width:1200px){
            +		position:fixed !important;
            +	}
            +	left: 0;
            +	right: auto;
            +	top: 0;
            +	z-index: 0;
            +	
            +}
            +.split-search-container{
            +	@media screen and (min-width:1200px){
            +		padding-right: $grid-gutter-width;
            +	}
            +}
            +.opalestate-loading {
            +	position:absolute;
            +	@include opacity(0.9);
            +	background-color:#fff;
            +	top: 0;
            +	right: 0;
            +	width: 100%;
            +	height: 100%;
            +	text-align: center;
            +	&::before{
            +		content:"";
            +		display: inline-block;
            +		width: 2rem;
            +		height: 2rem;
            +		vertical-align: text-bottom;
            +		border: .25em solid #000;
            +		border-right-color: transparent;
            +		border-radius: 50%;
            +		animation: spinner-border .75s linear infinite;
            +	}
            +	
            +}
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_page.scss b/assets/scss/opalestate/_page.scss
            new file mode 100755
            index 00000000..b9a7898c
            --- /dev/null
            +++ b/assets/scss/opalestate/_page.scss
            @@ -0,0 +1,100 @@
            +
            +@import "single";
            +@import "archive";
            +
            +// no header and footer for user management page 
            +.page-template-user-management  {
            +	header, footer, #colophon {
            +		display:none;
            +	}
            +	article header {
            +		display:block !important;
            +	}
            +}
            +/// my-properties  page
            +.button-actions {
            +	position:absolute;
            +	top: 0;
            +	right: 0;
            +	color:$white;
            +	z-index: 1;
            +	display: flex;
            +	a{
            +		background-color:$primary;
            +		color: $white;
            +		&:hover{
            +			cursor: pointer;
            +			background-color: $secondary;
            +			color: $white;
            +		}
            +		
            +	}
            +}
            +.my-properties{
            +	.property-status{
            +		position: relative;
            +		top: 0;
            +		left: 0;
            +	}
            +	.property-meta-list{
            +		padding: 0;
            +	}
            +	.my-properties-bottom{
            +		display: none;
            +	}
            +	.abs-col-item{
            +		padding-top: 10px;
            +	}
            +	.entry-title{
            +		margin: 0;
            +	}
            +}
            +
            +
            +/// search agent page
            +
            +.search-agents-wrap {
            +	.opalestate-search-agents-form {
            +		padding-bottom: $grid-gutter-width;
            +	}
            +}
            +	//Grid style
            +	.agent-grid-style {
            +		margin-bottom: $grid-gutter-width;
            +		background-color: $white;
            +		.agent-body{
            +			border-style: solid;
            +			border-width: 0 1px 1px 1px;
            +			border-color: $border-color;
            +			padding: $grid-gutter-width $grid-gutter-width $grid-gutter-width/2;
            +		}
            +		.agent-job{
            +			line-height: 1;
            +			padding-bottom: 14px;	
            +			border-bottom: 1px solid #ebebeb;
            +		}
            +		.trusted-label{
            +			position: absolute;
            +			right: 20px;
            +			background-color: $white;
            +			border-radius: 50%;
            +			bottom: 0;
            +			transform: translateY(50%);
            +			border: 1px solid $border-color;
            +			width: 48px;
            +			line-height: 48px;
            +		}
            +	}
            +
            +	//List style
            +	.agent-list-style{
            +		padding: $grid-gutter-width;
            +		border: 1px solid $border-color;
            +		margin-bottom: $grid-gutter-width;
            +		.team-info{
            +			margin: $padding-base 0 0;
            +		}
            +		.agent-box-title{
            +			
            +		}
            +	}
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_properties-loop.scss b/assets/scss/opalestate/_properties-loop.scss
            new file mode 100755
            index 00000000..cbcb6e4a
            --- /dev/null
            +++ b/assets/scss/opalestate/_properties-loop.scss
            @@ -0,0 +1,696 @@
            +
            +//property options
            +.property-options{
            +	position: absolute;
            +    bottom: 10px;
            +    right: 10px;
            +    .opalestate-ajax-gallery{
            +        width: 35px;
            +        line-height: 35px;
            +        text-align: center;
            +        display: inline-block;
            +        color: $white;
            +        background-color: $secondary;
            +        border-radius: 50%;
            +        &:hover{
            +            background-color: $primary;
            +        }
            +    }
            +}
            +.author-avatar{
            +    img{
            +        border-radius: 50%;
            +    }
            +}
            +
            +//property loop
            +.opalestate_property{
            +    margin-bottom: $grid-gutter-width;
            +    background-color: $white;
            +    border:solid 1px $border-color;
            +    position:relative;
            +    &.opalestate-single-property,&[class*="property-featured"]{
            +        border:none;
            +        margin-bottom: 0;
            +        background: transparent;
            +    }
            +    header{
            +		position: relative;
            +	}
            +}
            +
            +.property-box-image{
            +    overflow: hidden;
            +    position: relative;
            +    a{
            +        &::after{
            +            content: "";
            +            position: absolute;
            +            width: 100%;
            +            height: 100%;
            +            background-color:rgba(0, 0, 0, 0.3);
            +            top: 0;
            +            left: 0;
            +        }
            +    }
            +    
            +}
            +
            +.property-price{
            +    .property-regular-price,.property-saleprice{
            +        font-size: 18px;
            +        letter-spacing: -0.5px;
            +        font-weight: $headings-font-weight;
            +        color:$primary;
            +    }
            +    .property-regular-price.has-saleprice{
            +        font-size: $font-size-base;
            +        opacity: 0.8;
            +    }
            +}
            +
            +
            +/** ----list---- **/
            +.property-list{
            +    display: flex;
            +    flex-wrap: wrap;
            +    header{
            +        flex-basis: 35.065%;
            +    }
            +    .property-box-image{
            +        height: 100%;
            +        img{
            +            height: 100%;
            +        }
            +    }
            +    
            +    .entry-title{
            +        margin: 7px 0 0px;
            +    }
            +    .property-address{
            +        margin: 6px 0 23px;
            +    }
            +    .abs-col-item{
            +        flex: 1;
            +		padding-left:$grid-gutter-width;
            +        position: relative;
            +        display: flex;
            +        flex-wrap: wrap;
            +    }
            +    .property-meta-list{
            +        align-self: flex-end;
            +        flex-basis: 100%;
            +        padding: $padding-base 0 0;
            +        margin-top: $padding-base;
            +        border-top: 1px solid $border-color;
            +        li{
            +            margin-bottom: $padding-base;
            +            &:not(:last-child){
            +                margin-right: $grid-gutter-width;
            +            }
            +            
            +        }
            +    }
            +    .entry-summary{
            +        flex-basis: 25%;
            +        padding: 0 $grid-gutter-width;
            +    }
            +    .property-meta-bottom{
            +        display: flex;
            +        position: absolute;
            +        top: 10px;
            +        right: 10px;
            +        .property-toggle-favorite{
            +            display: block;
            +            width: 22px;
            +            line-height: 22px;
            +            border-radius: 50%;
            +            color: $white;
            +            text-align: center;
            +            cursor: pointer;
            +            font-size: 12px;
            +            background-color:rgba(0,0,0,0.3);
            +            &:hover{
            +                background-color: $link-hover-color;
            +            }
            +        }
            +    }
            +    .author-avatar{
            +        width: 22px;
            +    }
            +    .author-link{
            +        display: block;
            +        line-height: 1;
            +    }
            +    .author-name{
            +        display: none;
            +    }
            +    .meta-item:not(:last-of-type){
            +        margin-right: 5px;
            +    }
            +    .property-group-label{
            +        top: 10px;
            +        left: 10px;
            +    }
            +    @media screen and (max-width: 992px) {
            +        padding: $padding-base;
            +        header{
            +            flex-basis: 100%;
            +        }
            +        .abs-col-item{
            +            padding: $padding-base 0 0;
            +        }
            +        .entry-summary{
            +            flex-basis: 33.3333%;
            +            padding-top: $padding-base;
            +            padding-right: 0;
            +        }
            +    }
            +    @media screen and (max-width: 767px) {
            +        .entry-summary{
            +            flex-basis: 100%;
            +            padding: $padding-base 0 0;
            +        }
            +    }
            +}
            +// list style 1
            +.property-list-style-v1 {
            +	header {
            +		padding-bottom:0;
            +    }
            +    .property-list{
            +        padding: 10px;
            +    }
            +}
            +.container-cols-3{
            +    .abs-col-item{
            +        @media screen and (min-width: 768px) {
            +            border-right: 1px solid $border-color;
            +        }
            +    }
            +}
            +//list style 2
            +.property-list-style-v2{
            +    .property-list{
            +        padding: 0;
            +    }
            +    .abs-col-item{
            +        padding: 0 $grid-gutter-width;
            +        border: none;
            +    }
            +    .entry-content{
            +        width: 100%;
            +    }
            +    .entry-title{
            +        margin: 16px 0 0px;
            +    }
            +    .property-address{
            +        margin: 6px 0 0px;
            +    }
            +    .property-meta-list{
            +        padding: 0;
            +        margin-top: 9px;
            +        li{
            +            margin-top: 19px;
            +            margin-bottom: 8px;
            +            &:not(:last-child){
            +                margin-right: 30px;
            +            }
            +        }
            +        .label-property{
            +            display: none;
            +        }
            +    }
            +}
            +////
            +ul.property-meta-list{
            +    padding: $grid-gutter-width 20px 0;
            +    margin: 0;
            +    li{
            +        line-height: 1;
            +        margin-bottom: $grid-gutter-width;
            +    }
            +	i{
            +		margin-right: 5px;
            +		width: 20px;
            +        display: inline-block;
            +        font-style: unset;
            +	}	
            +}
            +i[class*="icon-property-"]{
            +    font-family: FontAwesome;
            +}
            +.icon-property-areasize:before{
            +    content: "\f047";
            +    
            +}
            +.icon-property-bedrooms:before{
            +    content: "\f236";
            +    
            +}
            +.icon-property-bathrooms:before{
            +    content: "\f2cd";
            +    
            +}
            +.icon-property-parking:before{
            +    content: "\f1b9";
            +    
            +}
            +.icon-property-builtyear:before{
            +    content: "\f073";
            +    
            +}
            +.icon-property-plotsize:before{
            +    content: "\f278";
            +    
            +}
            +.icon-property-orientation:before{
            +    content: "\f14e";
            +    
            +}
            +.icon-property-livingrooms:before{
            +    content: "\f26c";
            +    
            +}
            +.icon-property-kitchens:before{
            +    content: "\f0f5";
            +    
            +}
            +.icon-property-amountrooms:before{
            +    content: "\f1ad";
            +    
            +}
            +
            +/** Grid **/
            +.property-grid{
            +	.entry-content{
            +		padding: 0 20px $padding-base;
            +	}
            +	.entry-title{
            +        margin: 0 0 6px;
            +    }
            +    .property-address{
            +        margin: 0;
            +        span.property-view-map {
            +            color: $body-color;
            +        }
            +    }
            +    
            +    .property-meta-list.list-inline{
            +		li{
            +            flex-basis: 50%;
            +            margin-right: 0;
            +		}
            +    }
            +    .property-price{
            +        .property-regular-price,.property-saleprice{
            +            @media screen and (min-width:768px){
            +                font-size: 24px;
            +            }
            +            letter-spacing: -0.5px;
            +            color: $primary;
            +        }
            +        .property-regular-price.has-saleprice{
            +            font-size: $font-size-base;
            +        }
            +    }
            +    .entry-content-bottom {
            +        display: flex;
            +        align-items: center;
            +        border-top: 1px solid $border-color;
            +        > *:not(:first-child){
            +            position: relative;
            +            padding: 11px 0;
            +            border-left: 1px solid $border-color;
            +        }
            +        > *:first-child{
            +            margin-left: 20px;
            +            flex: 1;
            +        }
            +    }
            +    .property-toggle-favorite{
            +        width: 52px;
            +        text-align: center;
            +    }
            +    @media screen and (max-width:767px){
            +        .entry-content{
            +            padding: $grid-gutter-width $padding-base $padding-base;
            +        }
            +        .property-meta-list{
            +            padding: 23px $padding-base 17px $padding-base;
            +        }
            +        .property-meta-bottom{
            +            margin-left: $padding-base;
            +        }
            +        .property-group-label{
            +            left: $padding-base;
            +        }
            +    }
            +}
            +//Header Inner Author Link
            +.property-grid, .property-featured{ 
            +    .author-link{
            +        line-height: 1;
            +        display: flex;
            +        align-items: center;
            +        &:hover{
            +            color: $link-hover-color;
            +        }
            +    }
            +    .author-avatar{
            +        width: 35px;
            +        margin-right: 8px;
            +    }
            +    .author-name{
            +        font-size: 13px;
            +        font-weight: $headings-font-weight;
            +    }
            +}
            +/** Grid Layout 1**/
            +.property-grid-v1{
            +    .author-link{
            +        position: absolute;
            +        bottom: 10px;
            +        left: 20px;
            +        color: $white;
            +    }
            +}
            +/** Grid Layout 2**/
            +.property-grid-v2{
            +    .property-group-label{
            +        top: 10px;
            +    }
            +    .author-name{
            +        display: none;
            +    }
            +    .property-meta-list.list-inline{
            +        li{
            +            flex-basis: unset;
            +            &:not(:last-child){
            +                margin-right: 25px;
            +            }
            +        }
            +    }
            +    .entry-content-bottom{
            +        .author-link{
            +            padding: 0;
            +            width: 52px;
            +            justify-content: center;
            +        }
            +    }
            +    
            +    .author-avatar{
            +        margin: 0;
            +        width: 30px;
            +        padding: 11px 0;
            +    }
            +}
            +
            +/** Grid Layout 3**/
            +.property-grid-v3{
            +    .property-meta-bottom{
            +        position: absolute;
            +        bottom: $padding-base;
            +        padding-left: $padding-base;
            +        width: 100%;
            +    }
            +    .entry-title{
            +        margin: 17px 0 6px;
            +    }
            +    header{
            +        padding: 5px 5px 0;
            +    }
            +    .entry-summary{
            +        margin-bottom: 20px;
            +    }
            +    .property-price{
            +        color: $white;
            +        line-height: 1;
            +        .property-regular-price,.property-saleprice{
            +            color: $white;
            +            font-size: 18px;
            +        }
            +        .property-price-label{
            +            font-size: 13px;
            +        }
            +        .property-regular-price.has-saleprice{
            +            font-size: $font-size-base;
            +        }
            +    }
            +    .entry-content{
            +        padding: 0 20px;
            +    }
            +    .property-meta-list.list-inline{
            +        padding: 0;
            +        .info-meta{
            +            .label-property {
            +                display: none;
            +            }
            +        }
            +        li{
            +            flex-basis: unset;
            +            &:not(:last-child){
            +                margin-right: $grid-gutter-width;
            +            }
            +        }
            +    }
            +    .entry-content-bottom{
            +        border: none;
            +        padding: 10px 20px;
            +        background-color: #f4f4f4;
            +        & > *:not(:first-child){
            +            border: none;
            +            padding: 0;
            +            width: 30px;
            +            background-color: rgba(126, 126, 126, 0.2);
            +            border-radius: 3px;
            +            color: #fff;
            +            &:hover{
            +                background-color: $link-hover-color;
            +            }
            +        }
            +        & > *:first-child{
            +            margin-left: 0;
            +        }
            +    }
            +    .author-avatar{
            +        width: 30px;
            +    }
            +}
            +
            +//Mark Hover Item
            +.property-mark-hover-item{
            +    .property-grid__header {
            +        min-height: 245px;
            +    }
            +    .list-inline{
            +        padding: 0;
            +    }
            +    header{
            +        &::before{
            +            content: "";
            +            position: absolute;
            +            top: 0;
            +            left: 0;
            +            right: 0;
            +            bottom: 0;
            +            background-image: -webkit-gradient(linear, left top, left bottom, from(transparent), to(rgba(0, 0, 0, 0.95)));
            +            background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.95));
            +            z-index: 1;
            +        }
            +    }
            +    .property-price-wrapper,.property-areasize{
            +        display: inline-block;
            +        margin-right: 30px;
            +    }
            +    
            +    .entry-content{
            +        position: absolute;
            +        bottom: 0;
            +        left: 0;
            +        z-index: 2;
            +        padding: 0 15px 15px;
            +        color: $white;
            +    }
            +    .entry-title{
            +        color:inherit;
            +        a{
            +            color:inherit;
            +        }
            +    }
            +    .property-price{
            +        .property-regular-price,.property-saleprice{
            +            font-size: 18px;
            +            color: inherit;
            +        }
            +    }
            +}
            +
            +/** Featured Property **/
            +.property-featured{
            +    display: flex;
            +    flex-wrap: wrap;
            +    .featured-info{
            +        background-color: $headings-color;
            +        color: $white;
            +        flex-basis: 50%;
            +        padding: 52px 75px 49px 100px;
            +        @media screen and (max-width:992px) {
            +            flex-basis: 100%;
            +        }
            +        @media screen and (max-width:1024px) {
            +            padding: $grid-gutter-width;
            +        }
            +    }
            +    .author-link{
            +        position: absolute;
            +        bottom: 10px;
            +        left: 15px;
            +        color: $white;
            +    }
            +    .property-view-map{
            +        color: $white;
            +        i {
            +            color: $white;
            +        }
            +        a{
            +            color: $white;
            +        }
            +    }
            +    header{
            +        flex-basis: 100%;
            +        @media screen and (min-width:992px) {
            +            flex-basis: 50%;
            +        }
            +    }
            +    ul.property-meta-list{
            +        padding: 0;
            +        > li {
            +            margin-right: 0;
            +            width: 50%;
            +        }
            +        i{
            +            color: $secondary;
            +            width: auto;
            +        }
            +        .icon-box {
            +            font-size: 30px;
            +            width: auto;
            +        }
            +        .info-meta{
            +            span {
            +                display: block;
            +                margin-bottom: 5px;
            +            }
            +        }
            +    }
            +    
            +    .entry-title{
            +        margin-top: 14px;
            +        margin-bottom: 8px;
            +        a{
            +            color: $white;
            +            &:hover{
            +                color: $link-hover-color;
            +            }
            +        }
            +        
            +    }
            +    .property-address{
            +        margin: 0 0 20px;
            +    }
            +    .property-description{
            +        margin-bottom: $grid-gutter-width;
            +    }
            +    .property-price{
            +        .property-regular-price,.property-saleprice{
            +            font-size: 24px;
            +            color: $white;
            +        }
            +        .property-regular-price.has-saleprice{
            +            font-size: 18px;
            +        }
            +    }
            +    .property-toggle-favorite{
            +        display: none;
            +        width: 22px;
            +        line-height: 22px;
            +        border-radius: 3px;
            +        color: $white;
            +        text-align: center;
            +        cursor: pointer;
            +        font-size: 12px;
            +        background-color: $headings-color;
            +        position: absolute;
            +        right: 10px;
            +        top: 10px;
            +
            +        &:hover{
            +            background-color: $link-hover-color;
            +        }
            +    }
            +    @media(min-width: 1200px) {
            +        .featured-info {
            +           margin-top: 50px;
            +        }
            +        header {
            +            flex-basis: calc(50% + 50px);
            +            margin-bottom: 50px;
            +            margin-left: -50px;
            +        }
            +    }
            +}
            +header{
            +    &:hover{
            +        .property-bg-thumbnail{
            +            a{
            +                transform: scale(1.1);
            +            }
            +        }
            +    }
            +}
            +.property-bg-thumbnail{
            +    height: 100%;
            +    overflow: hidden;
            +    a{
            +        background-repeat: no-repeat;
            +        background-size: cover;
            +        position: relative;
            +        display: block;
            +        height: 100%;
            +        min-height: 340px;
            +        transform: scale(1);
            +        transition: opacity 0.5s ease, transform 1s cubic-bezier(0, 0, 0.44, 1.18), -webkit-transform 1s cubic-bezier(0, 0, 0.44, 1.18);
            +        background-position: center center;
            +        &::before{
            +            content: "";
            +            position: absolute;
            +            width: 100%;
            +            height: 100%;
            +            background-color: rgba(0, 0, 0, 0.3);
            +            top: 0;
            +            left: 0;
            +        }
            +    }
            +}
            +
            +.opalestate-pagination {
            +  text-align: center;
            +  margin: $theme-margin 0;
            +  ul {
            +    margin: 0 auto;
            +    li {
            +      list-style: none;
            +      display: inline-block;
            +      .page-numbers {
            +        padding:5px 15px;
            +        display: block;
            +        &:hover,
            +        &.current {
            +          background: $secondary;
            +          color: $white;
            +        }
            +      }
            +    }
            +  }
            +}
            diff --git a/assets/scss/opalestate/_shortcodes.scss b/assets/scss/opalestate/_shortcodes.scss
            new file mode 100755
            index 00000000..1b12617c
            --- /dev/null
            +++ b/assets/scss/opalestate/_shortcodes.scss
            @@ -0,0 +1,164 @@
            +// split map search //// 
            +.maps-container-fixed {
            +    position: relative;
            +    width: 100%;
            +    @media (min-width:1024px){
            +        position:fixed;
            +        z-index:0;
            +        width:50%;
            +        top:0;
            +        min-height:600px;
            +    }
            +}
            +
            +/** Shortcodes **/
            +.opalestate-search-properties{
            +	.search-properies-form{
            +		margin-top: $grid-gutter-width;
            +	}
            +}
            +
            +// my account form /// 
            +
            +.opalestate-my-account-form {
            +    position: relative;
            +    background: $white;
            +    padding: $grid-gutter-width;
            +    width:auto;
            +    max-width: 550px;
            +    margin: 20px auto;
            +    .submit{
            +        a{
            +            display: block;
            +            margin-top: 10px;
            +        }
            +    }
            +    .opalestate-button{
            +        padding: 17px 35px 14px 35px;
            +        width: 100%;
            +    }
            +    h3 {
            +        display:none;
            +    }
            +}
            +
            +.opalesate-properties-results {
            +    min-height:800px;   
            +}
            +
            +.membership-packages{
            +    padding-top: 40px;
            +    padding-bottom: 50px;
            +}
            +
            +.pricing.pricing-v3{
            +    border: 1px solid $border-color;
            +    border-radius:5px;
            +    padding: 0;
            +    margin-bottom: $grid-gutter-width;
            +    overflow: hidden;
            +    .pricing-header{
            +        text-align: center;
            +        background: $primary;
            +        color: $white;
            +        position: relative;
            +        padding: $grid-gutter-width/2 0px 0px;
            +    }
            +    .plan-price{
            +        color: $white;
            +        line-height: 2.3rem;
            +        margin-top: $grid-gutter-width/2;
            +        p{
            +            display: inline-block;
            +        }
            +    }
            +    .pricing-body {
            +        padding: $grid-gutter-width/2 $grid-gutter-width;
            +    }
            +    .plan-figure{
            +        font-size: 36px;
            +        color: $white;
            +        display: block;
            +        font-weight: bold;
            +    }
            +    .plain-info{
            +        & > div{
            +            padding: 10px 0;
            +            font-size: 14px;
            +        }
            +        .item-info{
            +            border-bottom: 1px solid $border-color;
            +            padding-bottom: $padding-base;
            +            margin-bottom: $padding-base;
            +            color: $headings-color;
            +            font-weight: $headings-font-weight;
            +            text-transform: uppercase;
            +            &:last-child{
            +                margin-bottom: 0;
            +            }
            +        }
            +        i{
            +            margin-right: 10px;
            +        }
            +    }
            +    .membership-form-wrapper{
            +        color: $white;
            +    }
            +    .membership-add-to-purchase{
            +        width: 100%;
            +        border: 0;
            +        text-align: center;
            +        background-color: #999;
            +        line-height: 42px;
            +        text-transform: capitalize;
            +        &:hover{
            +            background-color: gray;
            +        }
            +    }
            +    .pricing-footer{
            +        padding: 0 $grid-gutter-width $grid-gutter-width;
            +        text-align: center;
            +    }
            +    .plan-title{
            +        color: $white;
            +        font-size: 18px;
            +        margin: 0;
            +        border: none;
            +        font-weight: $headings-font-weight;
            +        letter-spacing: -0.5px;
            +        position: relative;
            +    }
            +
            +}
            +.package-hightlighted{
            +    .plan-subtitle{
            +        background-color: $secondary;
            +        color:$black;
            +        font-size: 12px;
            +        text-transform: uppercase;
            +        letter-spacing: 2px;
            +        position: absolute;
            +        bottom: -10px;
            +        display: block !important;
            +        margin: 0 auto;
            +        max-width: 150px;
            +        left: 0;
            +        right: 0;
            +        font-weight: $headings-font-weight;
            +    }
            +    .pricing.pricing-v3{
            +        @media screen and (min-width:992px) {
            +            //margin-top: -40px;
            +        }
            +        .membership-add-to-purchase{
            +            background-color: $secondary;
            +            &:hover{
            +                background-color: $primary;
            +            }
            +        }
            +        .pricing-footer{
            +            //padding-bottom: $grid-gutter-width *2;
            +        }
            +    }   
            +    
            +}
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_single.scss b/assets/scss/opalestate/_single.scss
            new file mode 100755
            index 00000000..4be788f6
            --- /dev/null
            +++ b/assets/scss/opalestate/_single.scss
            @@ -0,0 +1,1065 @@
            +.property-date{
            +	display: inline-block;
            +}
            +
            +.entry-summary-tabs{
            +	margin-top: 62px;
            +}
            +.property-meta {
            +	flex-basis: 100%;
            +}
            +
            +.property-types-list,
            +.property-categories-list {
            +  display: inline-block;
            +  margin-right: $padding-base;
            +}
            +
            +.property-address {
            +	display: inline-block;
            +	margin-top: 12px;
            +	margin-right: $padding-base;
            +	.property-view-map {
            +		i {
            +			color: $body-color;
            +		}
            +		a {
            +			margin-right: 4px;
            +		}
            +	}
            +}
            +
            +.box-inner-summary{
            +	padding: $grid-gutter-width;
            +	@media screen and (max-width:767px){
            +		padding: $grid-gutter-width 0;
            +	}
            +}
            +
            +.opalestate-box{
            +	padding-bottom: $grid-gutter-width;
            +	@media screen and (min-width:768px){
            +		padding: $grid-gutter-width;
            +		border: 1px solid $border-color;
            +	}
            +	.opalestate_property{
            +		&:last-of-type{
            +			margin-bottom: 0;
            +		}
            +	}
            +}
            +.opalestate-sidebar-box{
            +	margin-bottom: $grid-gutter-width;
            +	@media screen and (min-width:768px){
            +		padding: $grid-gutter-width;
            +		border: 1px solid $border-color;
            +	}
            +	@media screen and (max-width:768px){
            +		margin-top: $grid-gutter-width;
            +	}
            +}
            +.property-information{
            +	ul.list-info {
            +		padding:0;
            +		margin-bottom: 0;
            +		li {
            +			list-style: none;
            +			
            +			h6 {
            +				margin-bottom: 0;
            +				flex: 1;
            +				color: $body-color;
            +			}
            +			a{
            +				color: inherit;
            +			}
            +			&:not(:last-child){
            +				div[class*="property-label-"]{
            +					border-bottom: 1px solid $border-color;
            +				}
            +			}
            +		}
            +		div[class*="property-label-"]{
            +			padding: 4px 0;
            +			overflow: hidden;
            +			display: flex;
            +			align-items: center;
            +			h6{
            +				line-height: 1;
            +			}
            +			i{
            +				width: $font-size-base;
            +				margin-right: $padding-base;
            +			}
            +		}
            +	}
            +}
            +
            +
            +// Amenity
            +.property-amenities, .property-facilities {
            +	.list-group-item-text {
            +		line-height: 23px;
            +		margin-top: 21px;
            +		
            +			i {
            +				margin-right: 2px;
            +			}
            +			div[class*="col-"]{
            +				line-height: 40px;
            +			}
            +			div.active {
            +				i {
            +					color: $secondary;
            +				}
            +			}
            +		}
            +}
            +.property-amenities{
            +	img{
            +		width: 15px;
            +		margin-right: 5px;
            +	}
            +}
            +// Attachments
            +.property-attachments{
            +	i{
            +		font-size:36px;
            +		margin-right: $padding-base;
            +		float:left;
            +	}
            +	a{
            +		vertical-align: top;
            +		line-height: 1;
            +		display: block;
            +		text-transform: capitalize;
            +		padding-bottom:5px;
            +	}
            +	.list-group-item-text{
            +		margin-top: 36px;
            +	}
            +}
            +//Single Property Map
            +.google-map-tabs{
            +	.opalestate-tab-head{
            +		margin: 0;
            +		background: transparent;
            +	}
            +	position: relative;
            +	.tab-item {
            +		&.active,&:hover {
            +		   background-color: $primary;
            +		   color: $white;
            +		}
            +		border: none;
            +		padding: 5px 10px;
            +		margin-right: 10px;
            +		color: $white;
            +		background-color: $secondary;
            +		font-weight: $font-weight-base;
            +	}
            +	.opalestate-tab-wrap{
            +		position: absolute;
            +		top: 10px;
            +		right: 50px;
            +		z-index: 2;
            +	}
            +}
            +
            +/// near by
            +#property-search-places {
            +		bottom: 25px;
            +		left: 10px;
            +		position: absolute;
            +		z-index: 1;
            +		.btn-map-search {
            +			cursor: pointer;
            +			background-color: $white;
            +			text-align: center;
            +			@include square(40px);
            +			position: relative;
            +			i {
            +				display: block;
            +				line-height: 40px;
            +				&.fa-hospital-o {
            +					color: #b3e180;
            +				}
            +				&.fa-plus-square {
            +					color: #ec8f73;
            +				}
            +				&.fa-graduation-cap {
            +					color: #8fbfe4;
            +				}
            +				&.fa-shopping-basket {
            +					color: #9d4cfa;
            +				}
            +				&.fa-subway {
            +					color: #fabd47;
            +				}
            +				&.fa-bank {
            +					color: #6eadfb;
            +				}
            +			}
            +			em{
            +				background:$primary;
            +				margin-left: 10px;
            +				font-size: 10px;
            +				color:#FFF;
            +				padding: 1px 3px;
            +			}
            +			span {
            +				width: 0;
            +				display: block;
            +				visibility: hidden;
            +				@include transition(.35s);
            +				position: absolute;
            +				left: 50%;
            +				top: 0;
            +				background-color: $white;
            +				line-height: 40px;
            +				padding: 0 10px;
            +				z-index: -1;
            +				@include opacity(0);
            +				font-size: 12px;
            +			}
            +			&:hover,
            +			&.active {
            +				span {
            +					visibility: visible;
            +					width: 200px;
            +					left: 100%;
            +					z-index: 1;
            +					@include opacity(1);
            +				}
            +			}
            +		}
            +	}
            +
            +
            +/// agent 
            +.agent-sidebar{
            +	@media screen and (min-width:992px){
            +		margin-top: -286px;
            +	}
            +}
            +.single-agent{
            +	margin-top: $grid-gutter-width;
            +}
            +.agent-address-map{
            +	border-top: none;
            +}
            +
            +//agency profile
            +.agency-preview{
            +	display: none;
            +}
            + 
            + 
            +.property-agency-contact{
            +	@media screen and (max-width:1024px){
            +		margin-top: $grid-gutter-width;
            +	}
            +	p{
            +		margin-bottom: 0;
            +	}
            +	.entry-title{
            +		margin-bottom: 6px;
            +	}
            +	.opalestate-social-icons{
            +		margin: 0 0 0 $padding-base;
            +		[class^="opalestate-social-"]{
            +			margin: 4px 0 0;
            +		}
            +	}
            +	.agency-top-meta{
            +		display: flex;
            +		flex-wrap: wrap;
            +		padding-bottom: 12px;
            +		margin-bottom: 20px;
            +		position: relative;
            +		
            +	}
            +	.agency-top-meta,.agency-excerpt{
            +		&::before{
            +			content: "";
            +			@media screen and (max-width:1024px){
            +				width: 100%;
            +				left: 0;
            +				right: auto;
            +			}
            +			width: calc( 100% + #{$grid-gutter-width});
            +			height: 1px;
            +			background-color: $border-color;
            +			bottom: 0;
            +			position: absolute;
            +			right: -$grid-gutter-width;
            +		}
            +	}
            +	.agency-top-info{
            +		flex: 1;
            +	}
            +	.agency-excerpt{
            +		padding-bottom: 20px;
            +		margin-bottom: 13px;
            +		position: relative;
            +	}
            +}
            +/**
            + * Single property
            + */
            +.opalestate-box-content{
            +	margin: $grid-gutter-width 0 0;
            +	@media screen and (min-width:768px){
            +		margin: $grid-gutter-width*2 0 0;
            +	}
            +}
            +
            +.opalestate-rows {
            +	.opal-row {
            +		display: flex;
            +		flex-flow: wrap;
            +	}
            +}
            +
            +.outbox-title{
            +	margin-bottom: $padding-base;
            +	display: inline-block;
            +	line-height: 1;
            +}
            +.property-single-info{
            +	display: flex;
            +    flex-wrap: wrap;
            +	align-items: flex-end;
            +	justify-content: space-between;
            +	margin-top: 40px;
            +	margin-bottom: 50px;
            +}
            +
            +.group-items{
            +	display: flex;
            +	align-items: center;
            +	flex-wrap: wrap;
            +	@media screen and (min-width:768px){
            +		flex: 1;
            +	}
            +	.entry-title{
            +		margin-bottom: 0;
            +	}
            +	.property-status{
            +		position: relative;
            +		display: flex;
            +		top: 0;
            +		left: 0;
            +		li{
            +			line-height: 14px;
            +		}
            +		span{
            +			margin-bottom: 0;
            +		}
            +	}
            +}
            +
            +//Swiper
            +.swiper-container{
            +	[class*="swiper-button-"]{
            +		display: block;
            +		color: $secondary;
            +		width: 62px;
            +		height: 62px;
            +		text-align: center;
            +		background-color: rgba(255, 255, 255, 0.8);
            +		transition: all .5s ease-in-out;
            +		background-size: 10px 20px;
            +		opacity: 0;
            +		&:hover{
            +			background-color: $white;
            +		}
            +	}
            +	.swiper-button-next{
            +		right: -62px;
            +	}
            +	.swiper-button-prev{
            +		left: -62px;
            +	}
            +	&:hover{
            +		[class*="swiper-button-"]{
            +			opacity: 1;
            +		}
            +		.swiper-button-next{
            +			right: 20px;
            +		}
            +		.swiper-button-prev{
            +			left: 20px;
            +		}
            +	}
            +}
            +
            +[class*="swiper-button-"]{
            +
            +}
            +
            +.swiper-pagination{
            +	display: none !important;
            +}
            +.opalestate-single-property {
            +	&.opalestate_property{
            +		
            +		border: none;
            +	} 
            +	.owl-thumb-wrapper{
            +		padding-top: 10px;
            +		.owl-item:not(:last-of-type){
            +			padding-right: 10px;
            +		}
            +	}
            +	 
            +	.entry-summary{
            +		@media screen and (min-width:768px){
            +			border: 1px solid $border-color;
            +			padding-bottom: 40px;
            +		}
            +		
            +	}
            +	.property-meta-list{
            +		border-bottom: 1px solid $border-color;
            +		padding: $grid-gutter-width $grid-gutter-width 0;
            +		@media screen and (max-width:767px){
            +			padding: $grid-gutter-width 0 0;
            +			border:none;
            +		}
            +		i{
            +			color: $secondary;
            +		}
            +		li:not(:last-child){
            +			margin-right: $grid-gutter-width;
            +		}
            +	}
            +	.entry-content{
            +		@media screen and (min-width:768px){
            +			padding: $grid-gutter-width $grid-gutter-width 0;
            +		}
            +	}
            +	.box-heading{
            +		line-height: 1;
            +		margin-bottom: 16px;
            +	}
            +	
            +}
            +
            +//Print single property
            +.opalestate-single-property--print{
            +	.table-responsive{
            +		table{
            +			tr{
            +				td:last-child,th:last-child{
            +					display: none;
            +				}
            +			}
            +		}
            +	}
            +	.opalestate-tab-head{
            +		display: none;
            +	}
            +	.opalestate-tab-content, .plan-name{
            +		display: block;
            +	}
            +}
            +
            +//Single Layout 2
            +.opalestate-single-property--version-2{
            +	.entry-summary{
            +		border: none;
            +		padding-bottom: 0;
            +	}
            +	.single-property-sidebar{
            +		.opalestate-box-content{
            +			&:first-of-type{
            +				margin-top: 0;
            +			}
            +		}
            +	}
            +}
            +
            +.opalestate-tab-content{
            +	.opalestate-box-content{
            +		&:first-of-type{
            +			margin-top: 28px;
            +		}
            +	}
            +}
            +.property-tab-content{
            +	@media screen and (min-width:768px){
            +		border: 1px solid $border-color;
            +	}
            +}
            +
            +//Single Layout 3
            +.opalestate-single-property--version-3{
            +	.property-single-info{
            +		margin-bottom: 0;
            +		display: block;
            +	}
            +	.single-price-content{
            +		.property-price{
            +			text-align: left;
            +			margin-bottom: 7px;
            +			span{
            +				display: inline;
            +			}
            +		}
            +	}
            +	
            +}
            +
            +
            +//Single Layout 5
            +.opalestate-single-property--version-5{
            +	.property-single-info{
            +		margin-bottom: 0;
            +		display: block;
            +	}
            +	.single-price-content{
            +		.property-price{
            +			text-align: left;
            +			margin-bottom: 7px;
            +			span{
            +				display: inline;
            +			}
            +		}
            +	}
            +	
            +}
            +
            +//yelp nearby
            +.opalestate-yelp-bussines_wrapper{
            +	&:not(:last-of-type){
            +		margin-bottom: $grid-gutter-width;
            +	}
            +}
            +.opalestate-yelp-unit{
            +	display: flex;
            +	flex-wrap: wrap;
            +	&:not(:last-of-type){
            +		margin-bottom: $grid-gutter-width;
            +	}
            +}
            +.opalestate-yelp-title{
            +	line-height: 1;
            +	padding-bottom: 20px;
            +	border-bottom: 1px solid $border-color;
            +	margin-bottom: $grid-gutter-width;
            +}
            +.opalestate-yelp-icon{
            +	display: none;
            +	width: $font-size-base;
            +	margin-right: $padding-base;
            +}
            +.opalestate-yelp-category{
            +	display: inline-block;
            +	margin-bottom: 0;
            +	line-height: 1;
            +}
            +.opalestate-yelp-unit__name{
            +	line-height: 1;
            +	margin-bottom: 9px;
            +	margin-right: $padding-base;
            +}
            +.opalestate-yelp-unit-distance{
            +	display: none;
            +	line-height: 1;
            +    margin: 10px 0;
            +}
            +.opalestate-yelp-unit__info{
            +	flex: 1;
            +}
            +.opalestate-yelp-unit__address{
            +	line-height: 1;
            +}
            +.opalestate-yelp-unit__avatar{
            +	width: 50px;
            +    height: 50px;
            +	margin-right: 20px;
            +	img{
            +		width: 100%;
            +		height: 100%;
            +	}
            +}
            +.opalestate-yelp-unit__ratings{
            +	.opalestate-rating__stars{
            +		margin-left: auto;
            +		span{
            +			&::before{
            +				color: #d32323;
            +			}
            +		}
            +	}
            +}
            +
            +//walkscores
            +.walkscores-logo{
            +	float: right;
            +    line-height: 24px;
            +    margin-bottom: $padding-base;
            +}
            +.walk_details{
            +	display: flex;
            +	align-items: center;
            +	flex-wrap: wrap;
            +	&:not(:last-of-type){
            +		margin-bottom: $grid-gutter-width;
            +	}
            +}
            +.text-holder{
            +	flex: 1;
            +	h6{
            +		margin-bottom: 0;
            +	}
            +}
            +.number-holder{
            +	margin-right: 10px;
            +}
            +.scores-label{
            +	margin-bottom: 0;
            +	line-height: 24px;
            +	width: 60px;
            +    height: 60px;
            +    text-align: center;
            +    border-radius: 50%;
            +    border: 2px solid $primary;
            +	color: $primary;
            +}
            +.walk-more-details{
            +	text-transform: capitalize;
            +}
            +.single-price-content{
            +	.property-price {
            +		padding-top: 17px;
            +		span{
            +			line-height: 1;
            +		}
            +		@media screen and (min-width:768px){
            +			text-align: right;
            +			.property-regular-price,.property-saleprice{
            +				font-size: 36px;
            +			}
            +			.property-regular-price.has-saleprice{
            +				font-size: 24px;
            +			}
            +			.property-before-price-label,.property-price-label{
            +				display: block;
            +			}
            +		}
            +		.property-price-label {
            +			margin-top: 12px;
            +		}
            +		.property-before-price-label{
            +			margin-bottom: 12px;
            +		}
            +	}
            +	.call-to-price{
            +		font-size: 18px;
            +		font-weight: 500;
            +		color: $headings-color;
            +	}
            +}
            +.property-meta-top{
            +	line-height: 52px;
            +	.property-meta-top__list{
            +		margin-bottom: 0;
            +		align-items: center;
            +		.property-meta-top__button{
            +			width: 52px;
            +			text-align: center;
            +			margin-right: 0;
            +		}
            +	}
            +	.list-inline__print{
            +		span{
            +			display: none;
            +		}
            +	}
            +	.list-inline__sku{
            +		@media screen and (max-width:767px){
            +			flex-basis: 100%;
            +		}
            +	}
            +	@media screen and (min-width:768px) {
            +		border-bottom: 1px solid $border-color;
            +		padding-left: $grid-gutter-width;
            +		.property-meta-top__list{
            +			justify-content: flex-end;
            +			li:first-child:not(.property-meta-top__button){
            +				flex: 1;
            +			}
            +		}
            +		.property-meta-top__button{
            +			border-left: 1px solid $border-color;
            +		}
            +		
            +	}
            +}
            +.property-sku{
            +	font-weight: $headings-font-weight;
            +	color: $headings-color;
            +}
            +
            +//Reviews
            +.opalestate-reviews{
            +	padding-top: 0;
            +	padding-bottom: 0;
            +	.comment-form-comment{
            +		margin-bottom: 10px;
            +	}
            +	#respond{
            +		padding: 0;
            +	}
            +}
            +.opalestate-rating-percent__item{
            +	display: flex;
            +	flex-wrap: wrap;
            +	margin: 11px 0;
            +	&:last-of-type{
            +		margin-bottom: 0;
            +	}
            +	&:first-of-type{
            +		margin-top: 0;
            +	}
            +}
            +.opalestate-rating-percent__label{
            +	line-height: 1;
            +	margin-right: 15px;
            +	margin-bottom: 0;
            +}
            +.opalestate-process-bar{
            +	display: flex;
            +    height: 5px;
            +    overflow: hidden;
            +    font-size: 13px;
            +	background-color: #eeeeee;
            +	flex: 1;
            +}
            +.opalestate-process-bar__item{
            +	text-align: center;
            +	background-color: $primary;
            +}
            +.opalestate-process-text{
            +	display: block;
            +	line-height: 1;
            +	margin-left: 17px;
            +	width: 34px;
            +}
            +.opalestate-rating-header{
            +	display: flex;
            +	flex-wrap: wrap;
            +	font-size: 13px;
            +	font-weight: 500;
            +	
            +	margin-bottom: 58px;
            +	@media screen and (min-width:768px){
            +		border-bottom: 1px solid $border-color;
            +	}
            +	& > div{
            +		
            +		padding-bottom: 26px;
            +		@media screen and (max-width:767px){
            +			flex-basis: 100%;
            +			padding: 30px 0 0;
            +			border: none;
            +		}
            +	}
            +}
            +.opalestate-rating-percent{
            +	padding-right: $grid-gutter-width;
            +	flex-basis: 38%;
            +	border-right: 1px solid $border-color;
            +	padding-top: $grid-gutter-width;
            +}
            +.opalestate-overall{
            +	padding-left: $grid-gutter-width;
            +	flex-basis: 62%;
            +	padding-top: 25px;
            +}
            +.opalestate-overall__info{
            +	display: flex;
            +	flex-wrap: wrap;
            +	margin-bottom: 21px;
            +}
            +.opalestate-overall__point{
            +	margin-right: 40px;
            +	.point-number{
            +		margin-bottom: 0;
            +		line-height: 1;
            +		color: $primary;
            +	}
            +}
            +.opalestate-overall__star{
            +	display: flex;
            +    flex-wrap: wrap;
            +    align-items: center;
            +	flex: 1;
            +	.opalestate-overall__heading{
            +		flex-basis: 100%;
            +		margin-bottom: 11px;
            +	}
            +	.opalestate-rating, .opalestate-overall__rating-count{
            +		margin-right: 5px;
            +	}
            +}
            +.opalestate-overall-features{
            +	display: flex;
            +	flex-wrap: wrap;
            +}
            +.opalestate-overall-features__item{
            +	line-height: 1;
            +	&:not(:last-of-type){
            +		margin-right: 53px;
            +	}
            +}
            +.opalestate-overall-features__label{
            +	margin-bottom: 0;
            +	text-transform: uppercase;
            +	margin-bottom: 11px;
            +}
            +.opalestate-overall-features__percent{
            +	color: $headings-color;
            +}
            +.commentlist{
            +	padding: 0;
            +	margin-bottom: 28px;
            +	margin-top: 58px;
            +	> li{
            +		padding-bottom: 22px;
            +		display: block;
            +		&:not(:last-of-type){
            +			margin-bottom: $grid-gutter-width;
            +			border-bottom: 1px solid $border-color;
            +		}
            +	}
            +}
            +.opalestate-noreviews{
            +	margin-bottom: 25px;
            +}
            +.comment_container{
            +	display: flex;
            +    flex-wrap: wrap;
            +	align-items: flex-start;
            +	p{
            +		margin-bottom: 0;
            +	}
            +	.avatar{
            +		width: 50px;
            +		border-radius: 50%;
            +		margin-right: 28px;
            +	}
            +	.comment-text{
            +		flex: 1;
            +	}
            +	.meta{
            +		margin-bottom: $padding-base;
            +		line-height: 1;
            +	}
            +	.opalestate-rating{
            +		display: inline-block;
            +	}
            +}
            +.opalestate-review__ratings{
            +	margin-bottom: 31px;
            +}
            +.opalestate-review__author{
            +	font-weight: 500;
            +	color: $headings-color;
            +}
            +.comment-form-rating{
            +	display: inline-block;
            +	@media screen and (min-width:480px) {
            +		width: 33.3333%;
            +	}
            +}
            +
            +//Virtual 360
            +.property-360-virtual-session{
            +	iframe{
            +		width: 100%;
            +		min-height: 500px;
            +		display: block;
            +	}
            +}
            +
            +//video
            +.property-video-session{
            + 	iframe{
            +		@media screen and (min-width:768px) {
            +			width: 100%;
            +			min-height: 400px;
            +		}
            +		display: block;
            +		height: auto;
            + 	}
            +}
            +
            +/*
            + * Preview layout
            + */
            +.property-preview-custom-size {
            +	position:relative;
            +	overflow: hidden;
            +	height: 580px;
            +	.property-preview-map, .opalestate-tab-content, iframe {
            +		height: 100%;
            +		width: 100%;
            +		border: none;
            +	}
            +}
            +.property-preview{
            +	.swiper-pagination-images{
            +		margin-top: 10px;
            +	}
            +}
            +.property-preview-street-map{
            +	height: 100%;
            +}
            +.property-abs-info {
            +	position:absolute;
            +	padding:$padding-base;
            +	bottom:10%;
            +	left:9%;
            +	background:$white;
            +	z-index:99
            +} 
            +.gallery-metro-preview {
            +	display:flex;
            +	height: 100%;
            +	a {
            +		display:block;
            +		width:100%;
            +		height:100%;
            +		background-size:cover;
            +		background-repeat:no-repeat;
            +		background-position: center center;
            +	}
            +	.no-image {
            +		background-color:$primary;	
            +
            +	}
            +	span {
            +		display:block;
            +		background-color:#000;
            +		width:100%;
            +		height:100%;
            +		@include opacity(0.7);
            +		color:#FFF;
            + 
            +		position:relative;
            +		em {
            +			
            +		}
            +	}
            +	.metro-big {
            +		width:50%;
            +
            +	}
            +	.metro-group-small {
            +		width:50%;
            +		display:flex;
            +		flex-wrap:wrap;
            +	}
            +	.metro-small {
            +		width:33%;
            +		height:auto;
            +		text-align: center;
            +	}
            +} 
            +//Mark Picture
            +.opalestate-swiper-wrap {
            +	position:relative;
            +}
            +
            +.swiper-slide {
            +	.thumb-nav {
            +		width:100%;
            +		height:100px;
            +		background-size:cover;
            +		background-repeat:no-repeat;
            +		background-position:center center
            +	}
            +}	
            +
            +.property-mark-pics-preview{
            +	.property-heading-top{
            +		position: absolute;
            +		bottom: 0;
            +		left: 50%;
            +		transform: translateX(-50%);
            +	}
            +	.property-single-info{
            +		margin-bottom: 46px;
            +	}
            +	.property-thumbnail{
            +		position: relative;
            +		&::before{
            +			content: "";
            +			position: absolute;
            +			width: 100%;
            +			height: 100%;
            +			background-color: rgba(0, 0, 0, 0.4);
            +			transition: all .5s ease-in-out;
            +		}
            +	}
            +	.entry-title, a, .property-single-info, .property-price > span:first-child{
            +		color: $white;
            +	}
            +}
            +
            +//Apartment
            +.property-apartments-session{
            +	padding-top: 6px;
            +}
            +.table-responsive{
            +	overflow-x: auto;
            +    min-height: 0.01%;
            +    table{
            +		table-layout: unset;
            +		text-align: center;
            +		margin-bottom: 0;
            +		th{
            +			padding: 14px 3px;
            +			border-style: solid;
            +			border-color: $border-color;
            +			border-width: 0 0 1px 0;
            +			font-weight: 500;
            +		}
            +		td{
            +			border:none;
            +			padding: 12px 3px 10px;
            +		}
            +		tbody{
            +			tr:nth-of-type(2n+2){
            +				background-color: #f8f8f8;
            +			}
            +		}
            +	}
            +	@media screen and (max-width: 767px){
            +		width: 100%;
            +		margin-bottom: 15px;
            +		overflow-y: hidden;
            +		border: 1px solid $border-color;
            +		position: relative;
            +		z-index: 30;
            +		table{
            +			width: 730px;
            +		}
            +	}
            +}
            +
            +//single agency
            +.agency-box-top{
            +	.agency-grid-style{
            +		.agency-info{
            +			border-bottom: none;
            +		}
            +	}
            +}
            +.opalestate_single_agency{
            +	padding-bottom: $grid-gutter-width;
            +}
            +
            diff --git a/assets/scss/opalestate/_styles.scss b/assets/scss/opalestate/_styles.scss
            new file mode 100755
            index 00000000..e8c0a388
            --- /dev/null
            +++ b/assets/scss/opalestate/_styles.scss
            @@ -0,0 +1,14 @@
            +.opalestate-note {
            +	font-size:90%;
            +	color:#888;
            +}
            +.list-inline {
            +    list-style: none;
            +    display: flex;
            +    flex-wrap: wrap;
            +    li{
            +        &:not(:last-child){
            +            margin-right: $grid-gutter-width;
            +        }
            +    }
            +}
            \ No newline at end of file
            diff --git a/assets/scss/opalestate/_vars.scss b/assets/scss/opalestate/_vars.scss
            new file mode 100755
            index 00000000..805e1721
            --- /dev/null
            +++ b/assets/scss/opalestate/_vars.scss
            @@ -0,0 +1,23 @@
            +$headings-font-weight: 500;
            +$input-height: 50px;
            +$input-padding-y: .65rem;
            +$input-padding-x: 1rem;
            +$input-line-height: $input-height;
            +
            +$primary:   #2f73e9 !default;
            +$secondary: #02ce76 !default;
            +$white	 :  #FFF !default;
            +
            +$headings-color:   #0a1938;
            +$border-color:     #ebebeb;
            +$box-shadow-base: 0px 2px 8px 4px rgba(0, 0, 0, 0.12);
            +
            +$padding-base:        ($grid-gutter-width/2);
            +$grid-gutter-width:   30px;
            +
            +
            +$price-color:red;
            +$link-hover-color: $primary;
            +$input-border-color: #ebebeb;
            +$body-color: #7e7e7e;
            +$body-color-light: #bbb;
            \ No newline at end of file
            diff --git a/assets/scss/submission.scss b/assets/scss/submission.scss
            new file mode 100755
            index 00000000..bcb1c04c
            --- /dev/null
            +++ b/assets/scss/submission.scss
            @@ -0,0 +1,302 @@
            +@import "bootstrap/variables";
            +@import "bootstrap/mixins";
            +
            +@import "bootstrap/grid";
            +@import "opalestate/vars";
            +
            +.cmb2-id-opalestate-ppt-enablemapview{
            +	p.cmb2-metabox-description{
            +		display: inline;
            +	}
            +}
            +.opalestate-submission-form {
            +	label {
            +		.required {
            +			color:red ;
            +		}
            +	}
            +	input.required {
            +		border: 1px solid rgb(255, 0, 0);
            +	}
            +	.opal-map-desc {
            +		display: none;
            +	}
            +	.cmb2-wrap{
            +		input.cmb2-datepicker{
            +			width: 100%;
            +		}
            +	}
            +	
            +}
            +
            +#property-thumbs-container {
            +	width:100%;
            +	clear:both;
            +}
            +
            +#property-thumbs-container .gallery-thumbnail{
            + 
            +	margin-bottom: 15px;
            +	position: relative;
            +	width:180px;
            +	height:180px;
            +}
            +
            +#property-thumbs-container .icon-delete{
            +	position: absolute;
            +	bottom: 6px;
            +	left: 0;
            +	z-index: 99;
            +	padding: 5px; 
            +	background: #CCC;
            +}
            +
            +
            +#property-thumbs-container .icon-featured{
            +	position: absolute;
            +	bottom: 6px;
            +	right: 0;
            +	z-index: 99;
            +	padding: 5px; 
            +	background: #CCC;
            +}
            +#property-thumbs-container .icon-featured .fa-star{
            +	color:#fc8826;
            +}
            +
            +
            +.media-drag-drop {
            +  background-color: #efefef;
            +  border: 2px dashed #dfdfdf;
            +  text-align: center;
            +  padding: 30px;
            +}
            +.media-drag-drop h4 {
            +  color: #8b9293;
            +  font-size: 18px;
            +  line-height: 18px;
            +  margin: 0 0 20px;
            +  font-weight: 400;
            +  text-transform: inherit;
            +  text-align: inherit;
            +}
            +.media-drag-drop .fa {
            +  margin-right: 8px;
            +}
            +.property-submission-form{
            +	margin-bottom: 80px;
            +	max-width: 90%;
            +    margin-left: auto;
            +	margin-right: auto;
            +	.alert{
            +		padding: $padding-base;
            +		p{
            +			margin-bottom: 0;
            +			a{
            +				padding: 0;
            +				background-color: transparent;
            +				text-transform: unset;
            +				font-weight: $headings-font-weight;
            +				color: $white;
            +				&:hover{
            +					color: $link-hover-color;
            +				}
            +			}
            +		}
            +		
            +	}
            +}
            +
            +//
            +
            +//Submission tab
            +.opalestate-submission-tab-head{
            +	display: flex;
            +	flex-wrap: wrap;
            +	margin-bottom: $grid-gutter-width;
            +	justify-content: center;
            +	.tab-item{
            +		color: $headings-color;
            +		padding: 0;
            +		border: none;
            +		position: relative;
            +		padding-right: 30px;
            +		@media screen and (max-width:1024px){
            +			padding-right: 20px;
            +		}
            +		@media screen and (max-width:992px){
            +			flex-basis: 25%;
            +			margin-bottom: 10px;
            +			&:last-of-type{
            +				&::before{
            +					content: none;
            +				}
            +			}
            +		}
            +		@media screen and (max-width:767px){
            +			flex-basis: 50%;
            +		}
            +		span{
            +			padding-bottom: 10px;
            +			display: inline-block;
            +			position: relative;
            +			&::before{
            +				content: "";
            +				position: absolute;
            +				width: 100%;
            +				height: 3px;
            +				bottom: 0;
            +				left: 0;
            +				background-color: #f0f0f0;
            +			}
            +		}
            +		&:last-of-type{
            +			padding-right: 0;
            +			&::after{
            +				width: 100%;
            +			}
            +		}
            +		&::before{
            +			content: "";
            +			position: absolute;
            +			width: 100%;
            +			height: 3px;
            +			bottom: 0;
            +			left: 0;
            +			background-color: #f0f0f0;
            +		}
            +		
            +		&.active{
            +			span::before{
            +				background-color: $primary;
            +			}
            +		}
            +		&.passed:not(.active){
            +			&::before{
            +				background-color: $primary;
            +			}
            +			span::before{
            +				background-color: transparent;
            +			}
            +		}
            +		&.passed.active ~ .passed{
            +			&::before{
            +				background-color: #f0f0f0;
            +			}
            +		}
            +	}
            +}
            +
            +.opalestate-submission-tab{
            +	.cmb-type-opal-map{
            +		@media screen and (max-width:767px) {
            +			.form-group{
            +				padding: 0 15px;
            +			}
            +			.opalestate-map-wrap ~ div{
            +				width: 100%;
            +			}
            +		}
            +	}
            +	.cmb-add-row{
            +		margin-top: 0;
            +	}
            +	.cmb-multicheck-toggle{
            +		font-style: italic;
            +		text-decoration: underline;
            +		cursor: pointer;
            +		transition: all .3s ease-in-out;
            +		&:hover{
            +			color: $link-hover-color;
            +		}
            +	}
            +	.cmb2-checkbox-list{
            +		li{
            +			@media screen and (min-width:768px) {
            +				flex-basis: 50%;
            +			}
            +			flex-basis: 100%;
            +			margin-right: 0;
            +			font-size: $font-size-base;
            +			line-height: 1;
            +			display: inline-block;
            +			position: relative;
            +			padding-left: 0;
            +			margin-bottom: $padding-base;
            +			margin-top: $padding-base;
            +			cursor: pointer;
            +			-webkit-user-select: none;
            +			-moz-user-select: none;
            +			-ms-user-select: none;
            +			user-select: none;
            +			img{
            +				width: $font-size-base;
            +				height: $font-size-base;
            +				vertical-align: top;
            +			}
            +			label{
            +				margin-bottom: 0;
            +				padding-left: 25px;
            +				cursor: pointer;
            +			}	
            +			input[type="checkbox"]{
            +				position: absolute;
            +				opacity: 0;
            +				cursor: pointer;
            +				&:checked ~ span.custom-checkbox-label{
            +					background-color: $primary;
            +					&::after{
            +						display: block;
            +					}
            +				}
            +			}
            +			.custom-checkbox-label{
            +				z-index: -1;
            +			}
            +		}
            +	}
            +	button.btn.submission-next-btn{
            +		position: relative;
            +		padding: 19px 25px 17px 20px;
            +		&::before{
            +			content: "\f138";
            +			font-family: Fontawesome;
            +			margin-right: 18px;
            +			padding-right: 20px;
            +		}
            +		&::after{
            +			content: "";
            +			width: 52px;
            +			position: absolute;
            +			top: 0;
            +			left: 0;
            +			height: 100%;
            +			background-color: transparent;
            +			-webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +			box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +		}
            +	}
            +	.submission-back-btn{
            +		position: relative;
            +		padding-left: 25px;
            +		padding-right: 20px;
            +		&::after{
            +			content: "\f137";
            +			font-family: Fontawesome;
            +			margin-left: 18px;
            +			padding-left: 20px;
            +		}
            +		&::before{
            +			content: "";
            +			width: 52px;
            +			position: absolute;
            +			top: 0;
            +			right: 0;
            +			height: 100%;
            +			background-color: transparent;
            +			-webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +			box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +			transform: rotate(180deg);
            +		}
            +	}
            +}
            diff --git a/assets/submission.css b/assets/submission.css
            new file mode 100755
            index 00000000..41579ba5
            --- /dev/null
            +++ b/assets/submission.css
            @@ -0,0 +1,431 @@
            +@media (min-width: 768px) {
            +  .opal-row, .row {
            +    margin-left: -15px;
            +    margin-right: -15px;
            +  }
            +  .opal-row .col-sm-1, .opal-row .col-sm-2, .opal-row .col-sm-3, .opal-row .col-sm-4, .opal-row .col-sm-5, .opal-row .col-sm-6, .opal-row .col-sm-7, .opal-row .col-sm-8, .opal-row .col-sm-9, .opal-row .col-sm-10, .opal-row .col-sm-11, .opal-row .col-sm-12, .row .col-sm-1, .row .col-sm-2, .row .col-sm-3, .row .col-sm-4, .row .col-sm-5, .row .col-sm-6, .row .col-sm-7, .row .col-sm-8, .row .col-sm-9, .row .col-sm-10, .row .col-sm-11, .row .col-sm-12 {
            +    float: left;
            +  }
            +  .opal-row .col-sm-1, .row .col-sm-1 {
            +    width: 8.33333%;
            +  }
            +  .opal-row .col-sm-2, .row .col-sm-2 {
            +    width: 16.66667%;
            +  }
            +  .opal-row .col-sm-3, .row .col-sm-3 {
            +    width: 25%;
            +  }
            +  .opal-row .col-sm-4, .row .col-sm-4 {
            +    width: 33.33333%;
            +  }
            +  .opal-row .col-sm-5, .row .col-sm-5 {
            +    width: 41.66667%;
            +  }
            +  .opal-row .col-sm-6, .row .col-sm-6 {
            +    width: 50%;
            +  }
            +  .opal-row .col-sm-7, .row .col-sm-7 {
            +    width: 58.33333%;
            +  }
            +  .opal-row .col-sm-8, .row .col-sm-8 {
            +    width: 66.66667%;
            +  }
            +  .opal-row .col-sm-9, .row .col-sm-9 {
            +    width: 75%;
            +  }
            +  .opal-row .col-sm-10, .row .col-sm-10 {
            +    width: 83.33333%;
            +  }
            +  .opal-row .col-sm-11, .row .col-sm-11 {
            +    width: 91.66667%;
            +  }
            +  .opal-row .col-sm-12, .row .col-sm-12 {
            +    width: 100%;
            +  }
            +  .opal-row .col-sm-1, .opal-row .col-sm-2, .opal-row .col-sm-3, .opal-row .col-sm-4, .opal-row .col-sm-5, .opal-row .col-sm-6, .opal-row .col-sm-7, .opal-row .col-sm-8, .opal-row .col-sm-9, .opal-row .col-sm-10, .opal-row .col-sm-11, .opal-row .col-sm-12, .row .col-sm-1, .row .col-sm-2, .row .col-sm-3, .row .col-sm-4, .row .col-sm-5, .row .col-sm-6, .row .col-sm-7, .row .col-sm-8, .row .col-sm-9, .row .col-sm-10, .row .col-sm-11, .row .col-sm-12 {
            +    position: relative;
            +    min-height: 1px;
            +    padding-left: 15px;
            +    padding-right: 15px;
            +  }
            +  .opal-row:before, .opal-row:after, .row:before, .row:after {
            +    content: " ";
            +    display: table;
            +  }
            +  .opal-row:after, .row:after {
            +    clear: both;
            +  }
            +}
            +@media (min-width: 992px) {
            +  .opal-row .col-md-1, .opal-row .col-md-2, .opal-row .col-md-3, .opal-row .col-md-4, .opal-row .col-md-5, .opal-row .col-md-6, .opal-row .col-md-7, .opal-row .col-md-8, .opal-row .col-md-9, .opal-row .col-md-10, .opal-row .col-md-11, .opal-row .col-md-12, .row .col-md-1, .row .col-md-2, .row .col-md-3, .row .col-md-4, .row .col-md-5, .row .col-md-6, .row .col-md-7, .row .col-md-8, .row .col-md-9, .row .col-md-10, .row .col-md-11, .row .col-md-12 {
            +    float: left;
            +  }
            +  .opal-row .col-md-1, .row .col-md-1 {
            +    width: 8.33333%;
            +  }
            +  .opal-row .col-md-2, .row .col-md-2 {
            +    width: 16.66667%;
            +  }
            +  .opal-row .col-md-3, .row .col-md-3 {
            +    width: 25%;
            +  }
            +  .opal-row .col-md-4, .row .col-md-4 {
            +    width: 33.33333%;
            +  }
            +  .opal-row .col-md-5, .row .col-md-5 {
            +    width: 41.66667%;
            +  }
            +  .opal-row .col-md-6, .row .col-md-6 {
            +    width: 50%;
            +  }
            +  .opal-row .col-md-7, .row .col-md-7 {
            +    width: 58.33333%;
            +  }
            +  .opal-row .col-md-8, .row .col-md-8 {
            +    width: 66.66667%;
            +  }
            +  .opal-row .col-md-9, .row .col-md-9 {
            +    width: 75%;
            +  }
            +  .opal-row .col-md-10, .row .col-md-10 {
            +    width: 83.33333%;
            +  }
            +  .opal-row .col-md-11, .row .col-md-11 {
            +    width: 91.66667%;
            +  }
            +  .opal-row .col-md-12, .row .col-md-12 {
            +    width: 100%;
            +  }
            +  .opal-row .col-md-1, .opal-row .col-md-2, .opal-row .col-md-3, .opal-row .col-md-4, .opal-row .col-md-5, .opal-row .col-md-6, .opal-row .col-md-7, .opal-row .col-md-8, .opal-row .col-md-9, .opal-row .col-md-10, .opal-row .col-md-11, .opal-row .col-md-12, .row .col-md-1, .row .col-md-2, .row .col-md-3, .row .col-md-4, .row .col-md-5, .row .col-md-6, .row .col-md-7, .row .col-md-8, .row .col-md-9, .row .col-md-10, .row .col-md-11, .row .col-md-12 {
            +    position: relative;
            +    min-height: 1px;
            +    padding-left: 15px;
            +    padding-right: 15px;
            +  }
            +}
            +@media (min-width: 1200px) {
            +  .opal-row .col-lg-1, .opal-row .col-lg-2, .opal-row .col-lg-3, .opal-row .col-lg-4, .opal-row .col-lg-5, .opal-row .col-lg-6, .opal-row .col-lg-7, .opal-row .col-lg-8, .opal-row .col-lg-9, .opal-row .col-lg-10, .opal-row .col-lg-11, .opal-row .col-lg-12, .row .col-lg-1, .row .col-lg-2, .row .col-lg-3, .row .col-lg-4, .row .col-lg-5, .row .col-lg-6, .row .col-lg-7, .row .col-lg-8, .row .col-lg-9, .row .col-lg-10, .row .col-lg-11, .row .col-lg-12 {
            +    float: left;
            +  }
            +  .opal-row .col-lg-1, .row .col-lg-1 {
            +    width: 8.33333%;
            +  }
            +  .opal-row .col-lg-2, .row .col-lg-2 {
            +    width: 16.66667%;
            +  }
            +  .opal-row .col-lg-3, .row .col-lg-3 {
            +    width: 25%;
            +  }
            +  .opal-row .col-lg-4, .row .col-lg-4 {
            +    width: 33.33333%;
            +  }
            +  .opal-row .col-lg-5, .row .col-lg-5 {
            +    width: 41.66667%;
            +  }
            +  .opal-row .col-lg-6, .row .col-lg-6 {
            +    width: 50%;
            +  }
            +  .opal-row .col-lg-7, .row .col-lg-7 {
            +    width: 58.33333%;
            +  }
            +  .opal-row .col-lg-8, .row .col-lg-8 {
            +    width: 66.66667%;
            +  }
            +  .opal-row .col-lg-9, .row .col-lg-9 {
            +    width: 75%;
            +  }
            +  .opal-row .col-lg-10, .row .col-lg-10 {
            +    width: 83.33333%;
            +  }
            +  .opal-row .col-lg-11, .row .col-lg-11 {
            +    width: 91.66667%;
            +  }
            +  .opal-row .col-lg-12, .row .col-lg-12 {
            +    width: 100%;
            +  }
            +  .opal-row .col-lg-1, .opal-row .col-lg-2, .opal-row .col-lg-3, .opal-row .col-lg-4, .opal-row .col-lg-5, .opal-row .col-lg-6, .opal-row .col-lg-7, .opal-row .col-lg-8, .opal-row .col-lg-9, .opal-row .col-lg-10, .opal-row .col-lg-11, .opal-row .col-lg-12, .row .col-lg-1, .row .col-lg-2, .row .col-lg-3, .row .col-lg-4, .row .col-lg-5, .row .col-lg-6, .row .col-lg-7, .row .col-lg-8, .row .col-lg-9, .row .col-lg-10, .row .col-lg-11, .row .col-lg-12 {
            +    position: relative;
            +    min-height: 1px;
            +    padding-left: 15px;
            +    padding-right: 15px;
            +  }
            +}
            +
            +.cmb2-id-opalestate-ppt-enablemapview p.cmb2-metabox-description {
            +  display: inline;
            +}
            +
            +.opalestate-submission-form label .required {
            +  color: red;
            +}
            +.opalestate-submission-form input.required {
            +  border: 1px solid red;
            +}
            +.opalestate-submission-form .opal-map-desc {
            +  display: none;
            +}
            +.opalestate-submission-form .cmb2-wrap input.cmb2-datepicker {
            +  width: 100%;
            +}
            +
            +#property-thumbs-container {
            +  width: 100%;
            +  clear: both;
            +}
            +
            +#property-thumbs-container .gallery-thumbnail {
            +  margin-bottom: 15px;
            +  position: relative;
            +  width: 180px;
            +  height: 180px;
            +}
            +
            +#property-thumbs-container .icon-delete {
            +  position: absolute;
            +  bottom: 6px;
            +  left: 0;
            +  z-index: 99;
            +  padding: 5px;
            +  background: #CCC;
            +}
            +
            +#property-thumbs-container .icon-featured {
            +  position: absolute;
            +  bottom: 6px;
            +  right: 0;
            +  z-index: 99;
            +  padding: 5px;
            +  background: #CCC;
            +}
            +
            +#property-thumbs-container .icon-featured .fa-star {
            +  color: #fc8826;
            +}
            +
            +.media-drag-drop {
            +  background-color: #efefef;
            +  border: 2px dashed #dfdfdf;
            +  text-align: center;
            +  padding: 30px;
            +}
            +
            +.media-drag-drop h4 {
            +  color: #8b9293;
            +  font-size: 18px;
            +  line-height: 18px;
            +  margin: 0 0 20px;
            +  font-weight: 400;
            +  text-transform: inherit;
            +  text-align: inherit;
            +}
            +
            +.media-drag-drop .fa {
            +  margin-right: 8px;
            +}
            +
            +.property-submission-form {
            +  margin-bottom: 80px;
            +  max-width: 90%;
            +  margin-left: auto;
            +  margin-right: auto;
            +}
            +.property-submission-form .alert {
            +  padding: 15px;
            +}
            +.property-submission-form .alert p {
            +  margin-bottom: 0;
            +}
            +.property-submission-form .alert p a {
            +  padding: 0;
            +  background-color: transparent;
            +  text-transform: unset;
            +  font-weight: 500;
            +  color: #FFF;
            +}
            +.property-submission-form .alert p a:hover {
            +  color: #2f73e9;
            +}
            +
            +.opalestate-submission-tab-head {
            +  display: flex;
            +  flex-wrap: wrap;
            +  margin-bottom: 30px;
            +  justify-content: center;
            +}
            +.opalestate-submission-tab-head .tab-item {
            +  color: #0a1938;
            +  padding: 0;
            +  border: none;
            +  position: relative;
            +  padding-right: 30px;
            +}
            +@media screen and (max-width: 1024px) {
            +  .opalestate-submission-tab-head .tab-item {
            +    padding-right: 20px;
            +  }
            +}
            +@media screen and (max-width: 992px) {
            +  .opalestate-submission-tab-head .tab-item {
            +    flex-basis: 25%;
            +    margin-bottom: 10px;
            +  }
            +  .opalestate-submission-tab-head .tab-item:last-of-type::before {
            +    content: none;
            +  }
            +}
            +@media screen and (max-width: 767px) {
            +  .opalestate-submission-tab-head .tab-item {
            +    flex-basis: 50%;
            +  }
            +}
            +.opalestate-submission-tab-head .tab-item span {
            +  padding-bottom: 10px;
            +  display: inline-block;
            +  position: relative;
            +}
            +.opalestate-submission-tab-head .tab-item span::before {
            +  content: "";
            +  position: absolute;
            +  width: 100%;
            +  height: 3px;
            +  bottom: 0;
            +  left: 0;
            +  background-color: #f0f0f0;
            +}
            +.opalestate-submission-tab-head .tab-item:last-of-type {
            +  padding-right: 0;
            +}
            +.opalestate-submission-tab-head .tab-item:last-of-type::after {
            +  width: 100%;
            +}
            +.opalestate-submission-tab-head .tab-item::before {
            +  content: "";
            +  position: absolute;
            +  width: 100%;
            +  height: 3px;
            +  bottom: 0;
            +  left: 0;
            +  background-color: #f0f0f0;
            +}
            +.opalestate-submission-tab-head .tab-item.active span::before {
            +  background-color: #2f73e9;
            +}
            +.opalestate-submission-tab-head .tab-item.passed:not(.active)::before {
            +  background-color: #2f73e9;
            +}
            +.opalestate-submission-tab-head .tab-item.passed:not(.active) span::before {
            +  background-color: transparent;
            +}
            +.opalestate-submission-tab-head .tab-item.passed.active ~ .passed::before {
            +  background-color: #f0f0f0;
            +}
            +
            +@media screen and (max-width: 767px) {
            +  .opalestate-submission-tab .cmb-type-opal-map .form-group {
            +    padding: 0 15px;
            +  }
            +  .opalestate-submission-tab .cmb-type-opal-map .opalestate-map-wrap ~ div {
            +    width: 100%;
            +  }
            +}
            +.opalestate-submission-tab .cmb-add-row {
            +  margin-top: 0;
            +}
            +.opalestate-submission-tab .cmb-multicheck-toggle {
            +  font-style: italic;
            +  text-decoration: underline;
            +  cursor: pointer;
            +  transition: all .3s ease-in-out;
            +}
            +.opalestate-submission-tab .cmb-multicheck-toggle:hover {
            +  color: #2f73e9;
            +}
            +.opalestate-submission-tab .cmb2-checkbox-list li {
            +  flex-basis: 100%;
            +  margin-right: 0;
            +  font-size: 15px;
            +  line-height: 1;
            +  display: inline-block;
            +  position: relative;
            +  padding-left: 0;
            +  margin-bottom: 15px;
            +  margin-top: 15px;
            +  cursor: pointer;
            +  -webkit-user-select: none;
            +  -moz-user-select: none;
            +  -ms-user-select: none;
            +  user-select: none;
            +}
            +@media screen and (min-width: 768px) {
            +  .opalestate-submission-tab .cmb2-checkbox-list li {
            +    flex-basis: 50%;
            +  }
            +}
            +.opalestate-submission-tab .cmb2-checkbox-list li img {
            +  width: 15px;
            +  height: 15px;
            +  vertical-align: top;
            +}
            +.opalestate-submission-tab .cmb2-checkbox-list li label {
            +  margin-bottom: 0;
            +  padding-left: 25px;
            +  cursor: pointer;
            +}
            +.opalestate-submission-tab .cmb2-checkbox-list li input[type="checkbox"] {
            +  position: absolute;
            +  opacity: 0;
            +  cursor: pointer;
            +}
            +.opalestate-submission-tab .cmb2-checkbox-list li input[type="checkbox"]:checked ~ span.custom-checkbox-label {
            +  background-color: #2f73e9;
            +}
            +.opalestate-submission-tab .cmb2-checkbox-list li input[type="checkbox"]:checked ~ span.custom-checkbox-label::after {
            +  display: block;
            +}
            +.opalestate-submission-tab .cmb2-checkbox-list li .custom-checkbox-label {
            +  z-index: -1;
            +}
            +.opalestate-submission-tab button.btn.submission-next-btn {
            +  position: relative;
            +  padding: 19px 25px 17px 20px;
            +}
            +.opalestate-submission-tab button.btn.submission-next-btn::before {
            +  content: "\f138";
            +  font-family: Fontawesome;
            +  margin-right: 18px;
            +  padding-right: 20px;
            +}
            +.opalestate-submission-tab button.btn.submission-next-btn::after {
            +  content: "";
            +  width: 52px;
            +  position: absolute;
            +  top: 0;
            +  left: 0;
            +  height: 100%;
            +  background-color: transparent;
            +  -webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +  box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +}
            +.opalestate-submission-tab .submission-back-btn {
            +  position: relative;
            +  padding-left: 25px;
            +  padding-right: 20px;
            +}
            +.opalestate-submission-tab .submission-back-btn::after {
            +  content: "\f137";
            +  font-family: Fontawesome;
            +  margin-left: 18px;
            +  padding-left: 20px;
            +}
            +.opalestate-submission-tab .submission-back-btn::before {
            +  content: "";
            +  width: 52px;
            +  position: absolute;
            +  top: 0;
            +  right: 0;
            +  height: 100%;
            +  background-color: transparent;
            +  -webkit-box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +  box-shadow: 3px 0px 7px 0px rgba(0, 0, 0, 0.15);
            +  transform: rotate(180deg);
            +}
            diff --git a/changelog.txt b/changelog.txt
            new file mode 100755
            index 00000000..118d965e
            --- /dev/null
            +++ b/changelog.txt
            @@ -0,0 +1,2 @@
            += 1.0.0 - 2019-09-03 =
            +* Release.
            diff --git a/config.rb b/config.rb
            new file mode 100755
            index 00000000..ba647168
            --- /dev/null
            +++ b/config.rb
            @@ -0,0 +1,25 @@
            +
            +# Require any additional compass plugins here.
            +
            +# Set this to the root of your project when deployed:
            +http_path = "/"
            +css_dir = "assets"
            +sass_dir = "assets/scss"
            +images_dir = "images"
            +javascripts_dir = "js"
            +
            +# You can select your preferred output style here (can be overridden via the command line):
            +# output_style = :expanded or :nested or :compact or :compressed
            +
            +# To enable relative paths to assets via compass helper functions. Uncomment:
            +# relative_assets = true
            +
            +# To disable debugging comments that display the original location of your selectors. Uncomment:
            + line_comments = false
            +
            +
            +# If you prefer the indented syntax, you might want to regenerate this
            +# project again passing --syntax sass, or you can uncomment this:
            +# preferred_syntax = :sass
            +# and then run:
            +# sass-convert -R --from sass --to sass sass scss && rm -rf sass && mv scss sass
            diff --git a/inc/.DS_Store b/inc/.DS_Store
            new file mode 100755
            index 00000000..85240704
            Binary files /dev/null and b/inc/.DS_Store differ
            diff --git a/inc/admin/agency/class-agency.php b/inc/admin/agency/class-agency.php
            new file mode 100755
            index 00000000..ddba2db9
            --- /dev/null
            +++ b/inc/admin/agency/class-agency.php
            @@ -0,0 +1,156 @@
            +ID) && $post->ID ){
            +					OpalEstate_Agency::update_data_from_user( $related_id );
            +				}
            +			}
            +		}
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public function metaboxes_fields( $prefix = '' ){
            + 
            +		if ( ! $prefix ) {
            +			$prefix = OPALESTATE_AGENCY_PREFIX;
            +		}
            +
            +		$fields =  array(
            +			
            +			
            +			
            +			array(
            +			    'name'     => esc_html__('Gallery' ,'opalestate-pro'),
            +			    'desc'     => esc_html__('Select one, to add new you create in location of estate panel','opalestate-pro'),
            +			    'id'       => $prefix."gallery",
            +			    'type'     => 'file_list',
            +			) ,
            +			 
            +			array(
            +				'name' => esc_html__( 'slogan', 'opalestate-pro' ),
            +				'id'   => "{$prefix}slogan",
            +				'type' => 'text'
            +			)
            +		);
            +
            +		return apply_filters( 'opalestate_postype_agency_metaboxes_fields' , $fields );
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public function metaboxes( ){
            +
            +		global $pagenow; 
            +
            +		if( ($pagenow == 'post.php' || $pagenow == 'post-new.php') ) {
            +		
            +			$prefix = OPALESTATE_AGENCY_PREFIX;
            +
            +			$metabox = new Opalestate_Agency_MetaBox(); 
            +			
            +			$fields = $this->metaboxes_fields(); 
            +			$fields = array_merge_recursive( $fields , 
            +				$metabox->get_office_fields( $prefix ),  
            +				$metabox->get_address_fields( $prefix )
            +			);
            +
            +
            +			$box_options = array(
            +				'id'           => $prefix . 'edit',
            +				'title'        => esc_html__( 'Metabox', 'opalestate-pro' ),
            +				'object_types' => array( 'opalestate_agency' ),
            +				'show_names'   => true,
            +			);
            +
            +			// Setup meta box
            +			$cmb = new_cmb2_box( $box_options );
            +
            +			// Setting tabs
            +			$tabs_setting           = array(
            +				'config' => $box_options,
            +				'layout' => 'vertical', // Default : horizontal
            +				'tabs'   => array()
            +			);
            +
            +
            +			$tabs_setting['tabs'][] = array(
            +				'id'     => 'p-general',
            +				'icon'	 => 'dashicons-admin-home',
            +				'title'  => esc_html__( 'General', 'opalestate-pro' ),
            +				'fields' => $fields
            +			);
            +
            +			$tabs_setting['tabs'][] = array(
            +				'id'     => 'p-socials',
            +				'icon'	 => 'dashicons-admin-home',
            +				'title'  => esc_html__( 'Socials', 'opalestate-pro' ),
            +				'fields' => $metabox->get_social_fields( $prefix )
            +			);
            +
            +
            +			$tabs_setting['tabs'][] = array(
            +				'id'     => 'p-target',
            +				'icon'	 => 'dashicons-admin-tools',
            +				'title'  => esc_html__( 'Team', 'opalestate-pro' ),
            +				'fields' => $metabox->metaboxes_target()
            +			);
            +			// Set tabs
            +			$cmb->add_field( array(
            +				'id'   => '__tabs',
            +				'type' => 'tabs',
            +				'tabs' => $tabs_setting
            +			) );
            +		}
            +	}
            +}
            +new Opalestate_Admin_Agency();
            diff --git a/inc/admin/agent/class-agent.php b/inc/admin/agent/class-agent.php
            new file mode 100755
            index 00000000..95c000fa
            --- /dev/null
            +++ b/inc/admin/agent/class-agent.php
            @@ -0,0 +1,123 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            +
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +class Opalestate_Admin_Agent {
            +
            +	/**
            +	 * Auto update meta information to post from user data updated or created
            +	 */
            +	public function __construct() {
            +
            +		add_action( 'cmb2_admin_init', [ $this, 'metaboxes' ] );
            +		add_action( 'save_post', [ $this, 'save_post' ], 10, 3 );
            +
            +		add_action( 'user_register', [ $this, 'on_update_user' ], 10, 1 );
            +		add_action( 'profile_update', [ $this, 'on_update_user' ], 10, 1 );
            +	}
            +
            +	/**
            +	 * Auto update meta information to post from user data updated or created
            +	 */
            +	public function on_update_user() {
            +		if ( isset( $_POST['user_id'] ) && (int) $_POST['user_id'] && isset( $_POST['role'] ) ) {
            +			if ( $_POST['role'] == 'opalestate_agent' ) {
            +				$user_id    = absint( $_POST['user_id'] );
            +				$related_id = get_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', true );
            +				$post       = get_post( $related_id );
            +
            +				if ( isset( $post->ID ) && $post->ID ) {
            +					OpalEstate_Agent::update_data_from_user( $related_id );
            +				}
            +			}
            +		}
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public function metaboxes() {
            +		global $pagenow;
            +		if ( ( $pagenow == 'post.php' || $pagenow == 'post-new.php' ) ) {
            +			$prefix = OPALESTATE_AGENT_PREFIX;
            +
            +			$metabox = new Opalestate_Agent_MetaBox();
            +
            +			// echo '
            ' . print_r( $metabox->get_social_fields( $prefix ) ,1 );die;
            +			$box_options = [
            +				'id'           => $prefix . 'edit',
            +				'title'        => esc_html__( 'Metabox', 'opalestate-pro' ),
            +				'object_types' => [ 'opalestate_agent' ],
            +				'show_names'   => true,
            +			];
            +
            +			// Setup meta box
            +			$cmb = new_cmb2_box( $box_options );
            +
            +			// Setting tabs
            +			$tabs_setting = [
            +				'config' => $box_options,
            +				'layout' => 'vertical', // Default : horizontal
            +				'tabs'   => [],
            +			];
            +
            +			$tabs_setting['tabs'][] = [
            +				'id'     => 'p-general',
            +				'icon'   => 'dashicons-admin-home',
            +				'title'  => esc_html__( 'General', 'opalestate-pro' ),
            +				'fields' => $metabox->metaboxes_admin_fields(),
            +			];
            +
            +			$tabs_setting['tabs'][] = [
            +				'id'     => 'p-socials',
            +				'icon'   => 'dashicons-admin-home',
            +				'title'  => esc_html__( 'Socials', 'opalestate-pro' ),
            +				'fields' => $metabox->get_social_fields( $prefix ),
            +			];
            +
            +			$tabs_setting['tabs'][] = [
            +				'id'     => 'p-prices-target',
            +				'icon'   => 'dashicons-admin-tools',
            +				'title'  => esc_html__( 'Target Search', 'opalestate-pro' ),
            +				'fields' => $metabox->metaboxes_target(),
            +			];
            +			// Set tabs
            +			$cmb->add_field( [
            +				'id'   => '__tabs',
            +				'type' => 'tabs',
            +				'tabs' => $tabs_setting,
            +			] );
            +		}
            +	}
            +
            +	public function save_post( $post_id, $post, $update ) {
            +		///
            +		$post_type = get_post_type( $post_id );
            +		if ( $post_type == 'opalestate_agent' ) {
            +			if ( isset( $_POST[ OPALESTATE_AGENT_PREFIX . 'user_id' ] ) && absint( $_POST[ OPALESTATE_AGENT_PREFIX . 'user_id' ] ) ) {
            +
            +				$user_id = absint( $_POST[ OPALESTATE_AGENT_PREFIX . 'user_id' ] );
            +				update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', $post_id );
            +
            +				OpalEstate_Agent::update_user_data( $user_id );
            +			}
            +
            +		}
            +	}
            +}
            +
            +new Opalestate_Admin_Agent();
            diff --git a/inc/admin/class-admin.php b/inc/admin/class-admin.php
            new file mode 100755
            index 00000000..53f9f290
            --- /dev/null
            +++ b/inc/admin/class-admin.php
            @@ -0,0 +1,101 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            +
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +/**
            + * @Class Wpopal_Core_Setup
            + *
            + * Entry point class to setup load all files and init working on frontend and process something logic in admin
            + */
            +class Opalestate_Admin {
            +	/**
            +	 * Opalestate_Admin constructor.
            +	 */
            +	public function __construct() {
            +		add_action( 'init', [ $this, 'setup' ] );
            +		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
            +	}
            +
            +	/**
            +	 * enqueue editor.js for edit mode
            +	 */
            +	public function enqueue_scripts() {
            +		wp_enqueue_style( 'opalestate-admin', OPALESTATE_PLUGIN_URL . 'assets/admin.css', [], '3.0.3' );
            +
            +		$suffix = '';
            +		wp_enqueue_style( 'select2', OPALESTATE_PLUGIN_URL . 'assets/3rd/select2/css/select2.min.css', null, '1.3' );
            +		wp_enqueue_script( 'select2', OPALESTATE_PLUGIN_URL . 'assets/3rd/select2/js/select2.min.js', null, '1.3', true );
            +
            +		wp_enqueue_script( 'opalestate-country-select', OPALESTATE_PLUGIN_URL . 'assets/js/country-select.js', [ 'jquery' ], null, true );
            +		wp_enqueue_script( 'opalestate-admin', OPALESTATE_PLUGIN_URL . 'assets/js/admin' . $suffix . '.js', [ 'jquery' ], null, true );
            +	}
            +
            +	/**
            +	 * Include all files from supported plugins.
            +	 */
            +	public function setup() {
            +		$this->includes( [
            +			'cron-jobs-functions.php',
            +			'agent/class-agent.php',
            +			'property/class-property.php',
            +			'agency/class-agency.php',
            +			'rating/class-rating.php',
            +			'class-user.php',
            +		] );
            +
            +		/// 
            +		$this->includes( [
            +			'settings/base.php',
            +			'settings/api_keys.php',
            +			'settings/email.php',
            +			'settings/3rd_party.php',
            +			'settings/searcharea.php',
            +			'settings/general.php',
            +			'settings/property.php',
            +		] );
            +
            +		// 
            +
            +		// Get it started
            +		$Opalestate_Settings = new Opalestate_Plugin_Settings();
            +
            +	}
            +
            +	/**
            +	 * Include list of collection files
            +	 *
            +	 * @var array $files
            +	 */
            +	public function includes( $files ) {
            +		foreach ( $files as $file ) {
            +			$this->_include( $file );
            +		}
            +	}
            +
            +	/**
            +	 * include single file if found
            +	 *
            +	 * @var string $file
            +	 */
            +	private function _include( $file = '' ) {
            +		$file = OPALESTATE_PLUGIN_DIR . 'inc/admin/' . $file;
            +		if ( file_exists( $file ) ) {
            +			include_once $file;
            +		}
            +	}
            +}
            +
            +new Opalestate_Admin();
            diff --git a/inc/admin/class-api-keys-table.php b/inc/admin/class-api-keys-table.php
            new file mode 100755
            index 00000000..362e59d9
            --- /dev/null
            +++ b/inc/admin/class-api-keys-table.php
            @@ -0,0 +1,327 @@
            + esc_html__( 'API Key', 'opalestate-pro' ),     // Singular name of the listed records
            +			'plural'   => esc_html__( 'API Keys', 'opalestate-pro' ),    // Plural name of the listed records
            +			'ajax'     => false                       // Does this table support ajax?
            +		) );
            +
            +		$this->query();
            +	}
            +
            +	/**
            +	 * This function renders most of the columns in the list table.
            +	 *
            +	 * @access public
            +	 * @since  1.1
            +	 *
            +	 * @param array $item Contains all the data of the keys
            +	 * @param string $column_name The name of the column
            +	 *
            +	 * @return string Column Name
            +	 */
            +	public function column_default( $item, $column_name ) {
            +		return $item[ $column_name ];
            +	}
            +
            +	/**
            +	 * Displays the public key rows
            +	 *
            +	 * @access public
            +	 * @since  1.1
            +	 *
            +	 * @param array $item Contains all the data of the keys
            +	 * @param string $column_name The name of the column
            +	 *
            +	 * @return string Column Name
            +	 */
            +	public function column_key( $item ) {
            +		return '';
            +	}
            +
            +	/**
            +	 * Displays the token rows
            +	 *
            +	 * @access public
            +	 * @since  1.1
            +	 *
            +	 * @param array $item Contains all the data of the keys
            +	 * @param string $column_name The name of the column
            +	 *
            +	 * @return string Column Name
            +	 */
            +	public function column_token( $item ) {
            +		return '';
            +	}
            +
            +	/**
            +	 * Displays the secret key rows
            +	 *
            +	 * @access public
            +	 * @since  1.1
            +	 *
            +	 * @param array $item Contains all the data of the keys
            +	 * @param string $column_name The name of the column
            +	 *
            +	 * @return string Column Name
            +	 */
            +	public function column_secret( $item ) {
            +		return '';
            +	}
            +
            +	/**
            +	 * Renders the column for the user field
            +	 *
            +	 * @access public
            +	 * @since  1.1
            +	 * @return void
            +	 */
            +	public function column_user( $item ) {
            +
            +		$actions = array();
            +
            +		if ( apply_filters( 'opalestate_api_log_requests', true ) ) {
            +			$actions['view'] = sprintf(
            +				'%s',
            +				esc_url( add_query_arg( array(
            +					'view'      => 'api_requests',
            +					'post_type' => 'opalestate_forms',
            +					'page'      => 'opalestate-reports',
            +					'tab'       => 'logs',
            +					's'         => $item['email']
            +				), 'edit.php' ) ),
            +				esc_html__( 'View API Log', 'opalestate-pro' )
            +			);
            +		}
            +
            +		$actions['reissue'] = sprintf(
            +			'%s',
            +			esc_url( wp_nonce_url( add_query_arg( array(
            +				'user_id'          => $item['id'],
            +				'opalestate_action'      => 'process_api_key',
            +				'opalestate_api_process' => 'regenerate'
            +			) ), 'opalestate-api-nonce' ) ),
            +			esc_html__( 'Reissue', 'opalestate-pro' )
            +		);
            +		$actions['revoke']  = sprintf(
            +			'%s',
            +			esc_url( wp_nonce_url( add_query_arg( array(
            +				'user_id'          => $item['id'],
            +				'opalestate_action'      => 'process_api_key',
            +				'opalestate_api_process' => 'revoke'
            +			) ), 'opalestate-api-nonce' ) ),
            +			esc_html__( 'Revoke', 'opalestate-pro' )
            +		);
            +
            +		$actions = apply_filters( 'opalestate_api_row_actions', array_filter( $actions ) );
            +
            +		return sprintf( '%1$s %2$s', $item['user'], $this->row_actions( $actions ) );
            +	}
            +
            +	/**
            +	 * Retrieve the table columns
            +	 *
            +	 * @access public
            +	 * @since  1.1
            +	 * @return array $columns Array of all the list table columns
            +	 */
            +	public function get_columns() {
            +		$columns = array(
            +			'user'   => esc_html__( 'Username'    , 'opalestate-pro' ),
            +			'key'    => esc_html__( 'Public Key'  , 'opalestate-pro' ),
            +			'token'  => esc_html__( 'Token'		  , 'opalestate-pro' ),
            +			'secret' => esc_html__( 'Secret Key'  , 'opalestate-pro' )
            +		);
            +
            +		return $columns;
            +	}
            +
            +	/**
            +	 * Generate the table navigation above or below the table
            +	 *
            +	 * @since 3.1.0
            +	 * @access protected
            +	 * @param string $which
            +	 */
            +	protected function display_tablenav( $which ) {
            +		if ( 'top' === $which ) {
            +			wp_nonce_field( 'bulk-' . $this->_args['plural'] );
            +			}
            +	?>
            +		
            + +
            + bulk_actions( $which ); ?> +
            + extra_tablenav( $which ); + $this->pagination( $which ); + ?> + +
            +
            + + + + + html->ajax_user_search(); ?> + + 'opalestate_user_secret_key', + 'number' => $this->per_page, + 'offset' => $this->per_page * ( $this->get_paged() - 1 ) + ) ); + $keys = array(); + + foreach ( $users as $user ) { + $keys[ $user->ID ]['id'] = $user->ID; + $keys[ $user->ID ]['email'] = $user->user_email; + $keys[ $user->ID ]['user'] = '' . $user->user_login . ''; + + $keys[ $user->ID ]['key'] = OpalEstate()->api->get_user_public_key( $user->ID ); + $keys[ $user->ID ]['secret'] = OpalEstate()->api->get_user_secret_key( $user->ID ); + $keys[ $user->ID ]['token'] = OpalEstate()->api->get_token( $user->ID ); + } + + return $keys; + } + + + /** + * Retrieve count of total users with keys + * + * @access public + * @since 1.1 + * @return int + */ + public function total_items() { + global $wpdb; + + if ( ! get_transient( 'opalestate_total_api_keys' ) ) { + $total_items = $wpdb->get_var( "SELECT count(user_id) FROM $wpdb->usermeta WHERE meta_value='opalestate_user_secret_key'" ); + + set_transient( 'opalestate_total_api_keys', $total_items, 60 * 60 ); + } + + return get_transient( 'opalestate_total_api_keys' ); + } + + /** + * Setup the final data for the table + * + * @access public + * @since 1.1 + * @return void + */ + public function prepare_items() { + $columns = $this->get_columns(); + + $hidden = array(); // No hidden columns + $sortable = array(); // Not sortable... for now + + $this->_column_headers = array( $columns, $hidden, $sortable, 'id' ); + + $data = $this->query(); + + $total_items = $this->total_items(); + + $this->items = $data; + + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'per_page' => $this->per_page, + 'total_pages' => ceil( $total_items / $this->per_page ) + ) + ); + } +} diff --git a/inc/admin/class-user.php b/inc/admin/class-user.php new file mode 100755 index 00000000..62738e33 --- /dev/null +++ b/inc/admin/class-user.php @@ -0,0 +1,187 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + + +class OpalEstate_Admin_User{ + + /** + * + */ + public function __construct( ){ + + add_action( 'cmb2_admin_init', array( $this, 'register_user_profile_metabox') ); + add_action( 'personal_options', array( $this, 'show_message_user_profile' ) ); + + } + + /** + * + */ + public function show_message_user_profile(){ + + $user_id = isset( $_GET['user_id'] ) ? intval( $_GET['user_id'] ) : 0; + $roles = opalestate_user_roles_by_user_id( $user_id ); + + if( $roles ): + if( in_array( 'opalestate_agency', $roles) ): + $agency_id = get_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', true ); + if( !$agency_id ){ + return ; + } + $link = get_edit_post_link( $agency_id ); + ?> +
            +

            Opal Estate Agency and click here to update Agency profile', 'opalestate-pro'), $link ); ?>

            +
            + +
            +

            Opal Estate Agent and click here to update Agent profile', 'opalestate-pro'), $link ); ?>

            +
            + + $prefix . 'edit', + 'title' => esc_html__( 'Metabox', 'opalestate-pro' ), + 'object_types' => array( 'user' ), + 'show_names' => true, + ); + + $cmb = new_cmb2_box( $box_options ); + + // Setting tabs + $tabs_setting = array( + 'config' => $box_options, + 'layout' => 'vertical', // Default : horizontal + 'tabs' => array() + ); + + + $tabs_setting['tabs'][] = array( + 'id' => 'p-general', + 'icon' => 'dashicons-admin-home', + 'title' => esc_html__( 'General', 'opalestate-pro' ), + 'fields' => $this->get_base_fields() + ); + + $tabs_setting['tabs'][] = array( + 'id' => 'p-socials', + 'icon' => 'dashicons-admin-home', + 'title' => esc_html__( 'Socials', 'opalestate-pro' ), + 'fields' => $metabox->get_social_fields( $prefix ), + ); + + + // Set tabs + $cmb->add_field( array( + 'id' => '__tabs', + 'type' => 'tabs', + 'tabs' => $tabs_setting + ) ); + + /** + * Metabox for the user profile screen + */ + $cmb_user = new_cmb2_box( array( + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'User Profile Metabox', 'cmb2' ), // Doesn't output for user boxes + 'object_types' => array( 'user' ), // Tells CMB2 to use user_meta vs post_meta + 'show_names' => true, + 'new_user_section' => 'add-new-user', // where form will show on new user page. 'add-existing-user' is only other valid option. + ) ); + + $fields = $this->extra_info_fields(); + foreach( $fields as $field ){ + $cmb_user->add_field( $field ); + } + } + } + + public function get_base_fields(){ + $prefix = OPALESTATE_USER_PROFILE_PREFIX; + + $metabox = new Opalestate_User_MetaBox(); + $fields = array_merge_recursive( + $metabox->get_base_fields( $prefix ), + $metabox->get_job_fields( $prefix ) , + $metabox->get_address_fields( $prefix ) + ); + + return $fields; + } + /** + * + */ + public function extra_info_fields(){ + + + $prefix = OPALESTATE_USER_PROFILE_PREFIX; + + $management = array(); + + + $admin_fields = array(); + $admin_fields[] = array( + 'id' => "{$prefix}block_submission", + 'name' => esc_html__( 'Block Submssion', 'opalestate-pro' ), + 'type' => 'checkbox', + 'description' => esc_html__( 'Disable Submssion Functions to not allow submit property', 'opalestate-pro' ), + 'before_row' => '
            ' + + ); + $admin_fields[] = array( + 'id' => "{$prefix}block_submission_msg", + 'name' => esc_html__( 'Block Submssion Message', 'opalestate-pro' ), + 'type' => 'textarea', + 'description' => esc_html__( 'Show message for disabled user', 'opalestate-pro' ), + ); + $management = array_merge_recursive( $admin_fields, $management ); + + + return $management; + } +} + +new OpalEstate_Admin_User(); diff --git a/inc/admin/cron-jobs-functions.php b/inc/admin/cron-jobs-functions.php new file mode 100755 index 00000000..e69de29b diff --git a/inc/admin/functions.php b/inc/admin/functions.php new file mode 100755 index 00000000..b09f1c49 --- /dev/null +++ b/inc/admin/functions.php @@ -0,0 +1,599 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * Wrapper function around cmb2_get_option + * + * @param string $key Options array key + * + * @return mixed Option value + * @since 0.1.0 + * + */ +function opalestate_get_option( $key = '', $default = false ) { + global $opalestate_options; + $value = ! empty( $opalestate_options[ $key ] ) ? $opalestate_options[ $key ] : $default; + $value = apply_filters( 'opalestate_get_option', $value, $key, $default ); + + return apply_filters( 'opalestate_get_option_' . $key, $value, $key, $default ); +} + +/** + * Update an option + * + * Updates an opalestate setting value in both the db and the global variable. + * Warning: Passing in an empty, false or null string value will remove + * the key from the opalestate_options array. + * + * @param string $key The Key to update + * @param string|bool|int $value The value to set the key to + * + * @return boolean True if updated, false if not. + * @since 1.0 + * + */ +function opalestate_update_option( $key = '', $value = false ) { + + // If no key, exit + if ( empty( $key ) ) { + return false; + } + + if ( empty( $value ) ) { + $remove_option = opalestate_delete_option( $key ); + + return $remove_option; + } + + // First let's grab the current settings + $options = get_option( 'opalestate_settings' ); + + // Let's let devs alter that value coming in + $value = apply_filters( 'opalestate_update_option', $value, $key ); + + // Next let's try to update the value + $options[ $key ] = $value; + $did_update = update_option( 'opalestate_settings', $options ); + + // If it updated, let's update the global variable + if ( $did_update ) { + global $opalestate_options; + $opalestate_options[ $key ] = $value; + } + + return $did_update; +} + +/** + * Remove an option + * + * Removes an opalestate setting value in both the db and the global variable. + * + * @param string $key The Key to delete + * + * @return boolean True if updated, false if not. + * @since 1.0 + * + */ +function opalestate_delete_option( $key = '' ) { + + // If no key, exit + if ( empty( $key ) ) { + return false; + } + + // First let's grab the current settings + $options = get_option( 'opalestate_settings' ); + + // Next let's try to update the value + if ( isset( $options[ $key ] ) ) { + + unset( $options[ $key ] ); + + } + + $did_update = update_option( 'opalestate_settings', $options ); + + // If it updated, let's update the global variable + if ( $did_update ) { + global $opalestate_options; + $opalestate_options = $options; + } + + return $did_update; +} + + +/** + * Get Settings + * + * Retrieves all Opalestate plugin settings + * + * @return array Opalestate settings + * @since 1.0 + */ +function opalestate_get_settings() { + + $settings = get_option( 'opalestate_settings' ); + + return (array) apply_filters( 'opalestate_get_settings', $settings ); + +} + +/** + * Gateways Callback + * + * Renders gateways fields. + * + * @return void + * @global $opalestate_options Array of all the Opalestate Options + * @since 1.0 + * + */ +function opalestate_enabled_gateways_callback( $field_object, $escaped_value, $object_id, $object_type, $field_type_object ) { + + $id = $field_type_object->field->args['id']; + $field_description = $field_type_object->field->args['desc']; + $gateways = opalestate_get_payment_gateways(); + + echo '
              '; + + foreach ( $gateways as $key => $option ) : + + if ( is_array( $escaped_value ) && array_key_exists( $key, $escaped_value ) ) { + $enabled = '1'; + } else { + $enabled = null; + } + + echo '
            •  '; + echo '
            • '; + + endforeach; + + if ( $field_description ) { + echo '

              ' . $field_description . '

              '; + } + + echo '
            '; + + +} + +/** + * Gateways Callback (drop down) + * + * Renders gateways select menu + * + * @param $field_object , $escaped_value, $object_id, $object_type, $field_type_object Arguments passed by CMB2 + * + * @return void + * @since 1.0 + * + */ +function opalestate_default_gateway_callback( $field_object, $escaped_value, $object_id, $object_type, $field_type_object ) { + + $id = $field_type_object->field->args['id']; + $field_description = $field_type_object->field->args['desc']; + $gateways = opalestate_get_enabled_payment_gateways(); + + echo ''; + + echo '

            ' . $field_description . '

            '; + +} + +/** + * Opalestate Title + * + * Renders custom section titles output; Really only an
            because CMB2's output is a bit funky + * + * @param $field_object , $escaped_value, $object_id, $object_type, $field_type_object + * + * @return void + * @since 1.0 + * + */ +function opalestate_title_callback( $field_object, $escaped_value, $object_id, $object_type, $field_type_object ) { + + $id = $field_type_object->field->args['id']; + $title = $field_type_object->field->args['name']; + $field_description = $field_type_object->field->args['desc']; + + echo '
            '; + +} + +/** + * Gets a number of posts and displays them as options + * + * @param array $query_args Optional. Overrides defaults. + * @param bool $force Force the pages to be loaded even if not on settings + * + * @return array An array of options that matches the CMB2 options array + * @see: https://github.com/WebDevStudios/CMB2/wiki/Adding-your-own-field-types + */ +function opalestate_cmb2_get_post_options( $query_args, $force = false ) { + + $post_options = [ '' => '' ]; // Blank option + + if ( ( ! isset( $_GET['page'] ) || 'opalestate-settings' != $_GET['page'] ) && ! $force ) { + return $post_options; + } + + $args = wp_parse_args( $query_args, [ + 'post_type' => 'page', + 'numberposts' => 10, + ] ); + + $posts = get_posts( $args ); + + if ( $posts ) { + foreach ( $posts as $post ) { + + $post_options[ $post->ID ] = $post->post_title; + + } + } + + return $post_options; +} + + +/** + * Modify CMB2 Default Form Output + * + * @param string @args + * + * @since 1.0 + */ + +add_filter( 'cmb2_get_metabox_form_format', 'opalestate_modify_cmb2_form_output', 10, 3 ); + +function opalestate_modify_cmb2_form_output( $form_format, $object_id, $cmb ) { + + //only modify the opalestate settings form + if ( 'opalestate_settings' == $object_id && 'options_page' == $cmb->cmb_id ) { + + return '
            %3$s
            '; + } + + return $form_format; + +} + + +/** + * Opalestate License Key Callback + * + * @description Registers the license field callback for EDD's Software Licensing + * @param array $field_object , $escaped_value, $object_id, $object_type, $field_type_object Arguments passed by CMB2 + * + * @return void + * @since 1.0 + * + */ +if ( ! function_exists( 'opalestate_license_key_callback' ) ) { + function opalestate_license_key_callback( $field_object, $escaped_value, $object_id, $object_type, $field_type_object ) { + + $id = $field_type_object->field->args['id']; + $field_description = $field_type_object->field->args['desc']; + $license_status = get_option( $field_type_object->field->args['options']['is_valid_license_option'] ); + $field_classes = 'regular-text opalestate-license-field'; + $type = empty( $escaped_value ) ? 'text' : 'password'; + + if ( $license_status === 'valid' ) { + $field_classes .= ' opalestate-license-active'; + } + + $html = $field_type_object->input( [ + 'class' => $field_classes, + 'type' => $type, + ] ); + + //License is active so show deactivate button + if ( $license_status === 'valid' ) { + $html .= ''; + } else { + //This license is not valid so delete it + opalestate_delete_option( $id ); + } + + $html .= ''; + + wp_nonce_field( $id . '-nonce', $id . '-nonce' ); + + echo $html; + } +} + + +/** + * Display the API Keys + * + * @return void + * @since 2.0 + */ +function opalestate_api_keys_callback() { + if ( ! current_user_can( 'manage_opalestate_settings' ) ) { + return; + } + + do_action( 'opalestate_tools_api_keys_keys_before' ); + + require_once OPALESTATE_PLUGIN_DIR . 'inc/admin/class-api-keys-table.php'; + + $keys_table_list = new Opalestate_API_Keys_Table(); + $keys_table_list->prepare_items(); + + echo ''; + echo ''; + echo ''; + + $keys_table_list->views(); + $keys_table_list->search_box( esc_html__( 'Search Key', 'opalestate-pro' ), 'key' ); + $keys_table_list->display(); + ?> + + +

            + Opalestate REST API to retrieve donation data in JSON or XML for external applications or devices, such as Zapi_keyser.', + 'opalestate-pro' ), + 'https://wpopal.com/opalestate/documentation/opalestate-api_keys-reference/', + 'https://wpopal.com/addons/opalestate/' + ); ?> +

            + + + 'attachment', + 'post_status' => 'inherit', + 'date_query' => [ + 'column' => 'post_date', + 'before' => date( 'Y-m-d', strtotime( '-1 days' ) ), + ], + 'meta_query' => [ + [ + 'key' => '_pending_to_use_', + 'value' => 1, + 'compare' => '>=', + ], + ], + ] + ); + // clean up per day + if ( $query->have_posts() ) { + while ( $query->have_posts() ) { + $query->the_post(); + wp_delete_attachment( get_the_ID() ); + } + } + wp_reset_postdata(); +} + +/** + * Searches for users via ajax and returns a list of results + * + * @return void + * @since 1.0 + * + */ +function opalestate_ajax_search_agencies() { + if ( current_user_can( 'manage_opalestate_settings' ) ) { + $search_query = trim( $_GET['q'] ); + + $agents_objects = Opalestate_Query::get_agencies( [ + 'posts_per_page' => -1, + 's' => $search_query, + ] ); + + $agents = []; + if ( ! empty( $agents_objects->posts ) && is_array( $agents_objects->posts ) ) { + foreach ( $agents_objects->posts as $object ) { + $agents[] = [ + 'id' => $object->ID, + 'name' => $object->post_title, + 'avatar_url' => 'https://avatars1.githubusercontent.com/u/9919?v=4', + 'full_name' => $object->post_title, + 'description' => 'okokok', + ]; + } + } + $output = [ + 'total_count' => count( $agents ), + 'items' => $agents, + 'incomplete_results' => false, + ]; + echo json_encode( $output ); + } + die(); +} + +add_action( 'wp_ajax_opalestate_search_agencies', 'opalestate_ajax_search_agencies' ); + + +/** + * Searches for users via ajax and returns a list of results + * + * @return void + * @since 1.0 + * + */ +function opalestate_ajax_search_agents() { + if ( current_user_can( 'manage_opalestate_settings' ) ) { + $search_query = trim( $_GET['q'] ); + + $agents_objects = Opalestate_Query::get_agents( [ + 'posts_per_page' => -1, + 's' => $search_query, + ] ); + + $agents = []; + if ( ! empty( $agents_objects->posts ) && is_array( $agents_objects->posts ) ) { + foreach ( $agents_objects->posts as $object ) { + $agents[] = [ + 'id' => $object->ID, + 'name' => $object->post_title, + 'avatar_url' => 'https://avatars1.githubusercontent.com/u/9919?v=4', + 'full_name' => $object->post_title, + 'description' => 'okokok', + ]; + } + } + $output = [ + 'total_count' => count( $agents ), + 'items' => $agents, + 'incomplete_results' => false, + ]; + echo json_encode( $output ); + } + die(); +} + +add_action( 'wp_ajax_opalestate_search_agents', 'opalestate_ajax_search_agents' ); + + +/** + * Searches for users via ajax and returns a list of results + * + * @return void + * @since 1.0 + * + */ +function opalestate_ajax_search_users() { + + if ( current_user_can( 'manage_opalestate_settings' ) ) { + + $search_query = trim( $_GET['q'] ); + + $get_users_args = [ + 'number' => 9999, + 'search' => $search_query . '*', + ]; + + if ( ! empty( $exclude ) ) { + $exclude_array = explode( ',', $exclude ); + $get_users_args['exclude'] = $exclude_array; + } + + $get_users_args = apply_filters( 'opalestate_search_users_args', $get_users_args ); + + $found_users = apply_filters( 'opalestate_ajax_found_users', get_users( $get_users_args ), $search_query ); + + $user_list = '
              '; + if ( $found_users ) { + foreach ( $found_users as $user ) { + $user_list .= '
            • ' . esc_html( $user->user_login ) . '
            • '; + } + } else { + $user_list .= '
            • ' . esc_html__( 'No users found', 'opalestate-pro' ) . '
            • '; + } + $user_list .= '
            '; + + echo json_encode( [ 'results' => $user_list ] ); + + } + die(); +} + +add_action( 'wp_ajax_opalestate_search_users', 'opalestate_ajax_search_users' ); + +function opalestate_ajax_search_username() { + + $search_query = trim( $_POST['user_name'] ); + $user = get_userdatabylogin( $search_query ); + + $output = []; + + if ( $user ) { + $data = $user->data; + $data->author_link = get_author_posts_url( $user->data->ID ); + $data->avatar = get_avatar_url( $user->data->ID ); + $output['message'] = esc_html__( 'We could find this user', 'opalestate-pro' ); + $output['status'] = true; + $output['user'] = $data; + } else { + $output['message'] = esc_html__( 'We could not find this user', 'opalestate-pro' ); + $output['status'] = false; + } + + echo json_encode( $output ); + exit; + +} + +add_action( 'wp_ajax_opalestate_ajax_search_username', 'opalestate_ajax_search_username' ); \ No newline at end of file diff --git a/inc/admin/property/class-property.php b/inc/admin/property/class-property.php new file mode 100755 index 00000000..17e904eb --- /dev/null +++ b/inc/admin/property/class-property.php @@ -0,0 +1,163 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Admin_Property { + /** + * @var $tab + */ + private $tab; + + /** + * Opalestate_Admin_Property constructor. + */ + public function __construct() { + + add_filter( 'cmb2_admin_init', [ $this, 'metaboxes' ] ); + + add_action( 'transition_opalestate_property_status', [ $this, 'process_publish_property' ], 10, 1 ); + /* property column */ + add_filter( 'manage_opalestate_property_posts_columns', [ $this, 'columns' ] ); + add_action( 'manage_opalestate_property_posts_custom_column', [ $this, 'custom_columns' ], 10, 2 ); + + add_action( 'admin_menu', [ $this, 'remove_meta_boxes' ] ); + + // add_action( 'transition_post_status', array( __CLASS__, 'save_post' ), 10, 3 ); + } + /** + * + */ + public static function save_post( $new_status, $old_status, $post ){ + if ( $new_status == 'publish' && $post->post_type == "opalestate_property" ) { + $user_id = $post->post_author; + $user = get_user_by( 'id', $user_id ); + if ( ! is_object( $user ) ) { + $from_name = opalestate_get_option( 'from_name' ); + $from_email = opalestate_get_option( 'from_email' ); + $subject = opalestate_get_option( 'publish_submission_email_subject' ); + + $headers = sprintf( "From: %s <%s>\r\n Content-type: text/html", $from_name, $from_email ); + + $property_link = get_permalink( $post ); + $tags = [ "{first_name}", "{last_name}", "{property_link}" ]; + $values = [ $user->first_name, $user->last_name, $property_link ]; + + $body = opalestate_get_option( 'publish_submission_email_body' ); + $body = html_entity_decode( $body ); + $message = str_replace( $tags, $values, $body ); + + return wp_mail( $user->user_email, $subject, $message, $headers ); + } + } + } + + /** + * + */ + public function metaboxes() { + + global $pagenow; + if ( ( $pagenow == 'post.php' || $pagenow == 'post-new.php' ) ) { + $metabox = new Opalestate_Property_MetaBox(); + + return $metabox->register_admin_fields(); + } + } + + + private function add_fields_to_tab( $fields, $tab ) { + + foreach ( $fields as $field ) { + $field['tab'] = $tab; + $field['render_row_cb'] = [ 'CMB2_Tabs', 'tabs_render_row_cb' ]; + + $this->tab->add_field( $field ); + + } + } + + /** + * + */ + public function columns( $columns ) { + $comments = $columns['comments']; + unset( $columns['author'], $columns['date'], $columns['comments'] ); + $columns['featured'] = esc_html__( 'Featured', 'opalestate-pro' ); + $columns['sku'] = esc_html__( 'Sku', 'opalestate-pro' ); + $columns['address'] = esc_html__( 'Address', 'opalestate-pro' ); + $columns['comments'] = $comments; + $columns['author'] = esc_html__( 'Author', 'opalestate-pro' ); + $columns['date'] = esc_html__( 'Date', 'opalestate-pro' ); + + return $columns; + } + + /** + * + */ + public function custom_columns( $column, $post_id ) { + $property = new Opalestate_Property( $post_id ); + $nonce = wp_create_nonce( 'opalestate_property' ); + switch ( $column ) { + case 'featured': + if ( $property->featured ) { + $url = add_query_arg( [ + 'action' => 'opalestate_remove_feature_property', + 'property_id' => $post_id, + 'nonce' => $nonce, + ], admin_url( 'admin-ajax.php' ) ); + echo ''; + echo ''; + echo ''; + } else { + $url = add_query_arg( [ + 'action' => 'opalestate_set_feature_property', + 'property_id' => $post_id, + 'nonce' => $nonce, + ], admin_url( 'admin-ajax.php' ) ); + echo ''; + echo ''; + echo ''; + } + break; + + case 'sku': + if ( $property->sku ) { + echo sprintf( '%s', $property->sku ); + } + break; + + case 'address': + if ( $property->address ) { + echo sprintf( '%s', $property->address ); + } + break; + + default: + # code... + break; + } + } + + public function remove_meta_boxes() { + remove_meta_box( 'authordiv', 'opalestate_property', 'normal' ); + } + +} + +new Opalestate_Admin_Property(); +?> diff --git a/inc/admin/rating/class-rating.php b/inc/admin/rating/class-rating.php new file mode 100755 index 00000000..dd4ebf9a --- /dev/null +++ b/inc/admin/rating/class-rating.php @@ -0,0 +1,101 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Admin_Rating { + /** + * Opalestate_Admin_Rating constructor. + */ + public function __construct() { + add_action( 'cmb2_admin_init', [ $this, 'comment_metaboxes' ] ); + add_action( 'cmb2_admin_init', [ $this, 'feature_metaboxes' ] ); + add_filter( 'opalestate_settings_tabs', [ $this, 'register_admin_setting_tab' ], 1 ); + add_filter( 'opalestate_registered_review_settings', [ $this, 'register_admin_settings' ], 10, 1 ); + + // Save Rating Meta Boxes. + add_filter( 'wp_update_comment_data', 'Opalestate_Rating_MetaBox::save', 1 ); + } + + public function comment_metaboxes() { + $metabox = new Opalestate_Rating_MetaBox(); + + return $metabox->register_admin_comment_fields(); + } + + public function feature_metaboxes() { + $metabox = new Opalestate_Rating_MetaBox(); + + return $metabox->register_admin_feature_fields(); + } + + public function register_admin_setting_tab( $tabs ) { + $tabs['review'] = esc_html__( 'Review', 'opalestate-pro' ); + + return $tabs; + } + + public function register_admin_settings( $fields ) { + $fields = [ + 'id' => 'options_page_review', + 'title' => esc_html__( 'Review Settings', 'opalestate-pro' ), + 'show_on' => [ 'key' => 'options-page', 'value' => [ 'opalestate_settings' ], ], + 'fields' => apply_filters( 'opalestate_settings_review', [ + [ + 'name' => esc_html__( 'Review Settings', 'opalestate-pro' ), + 'desc' => '
            ', + 'id' => 'opalestate_title_review_settings', + 'type' => 'title', + ], + [ + 'name' => esc_html__( 'Enable property reviews', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable property reviews', 'opalestate-pro' ), + 'id' => 'enable_property_reviews', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable agency reviews', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable agency reviews', 'opalestate-pro' ), + 'id' => 'enable_agency_reviews', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable agent reviews', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable agent reviews', 'opalestate-pro' ), + 'id' => 'enable_agent_reviews', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + ] + ), + ]; + + return $fields; + } +} + +new Opalestate_Admin_Rating(); diff --git a/inc/admin/register-settings.php b/inc/admin/register-settings.php new file mode 100755 index 00000000..b0e20cf7 --- /dev/null +++ b/inc/admin/register-settings.php @@ -0,0 +1,306 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Plugin_Settings { + + /** + * Option key, and option page slug + * + * @var string + */ + private $key = 'opalestate_settings'; + + /** + * Array of metaboxes/fields + * + * @var array + */ + protected $option_metabox = []; + + /** + * Options Page title + * + * @var string + */ + protected $title = ''; + + /** + * Options Page hook + * + * @var string + */ + protected $options_page = ''; + + protected $subtabs = array(); + + protected $setting_object = array(); + /** + * Constructor + * + * @since 1.0 + */ + public function __construct() { + + add_action( 'admin_menu', [ $this, 'admin_menu' ], 10 ); + + add_action( 'admin_init', [ $this, 'init' ] ); + + //Custom CMB2 Settings Fields + add_action( 'cmb2_render_opalestate_title', 'opalestate_title_callback', 10, 5 ); + + // add_action( 'cmb2_render_api_keys', 'opalestate_api_keys_callback', 10, 5 ); + // add_action( 'cmb2_render_license_key', 'opalestate_license_key_callback', 10, 5 ); + add_action( "cmb2_save_options-page_fields", [ $this, 'settings_notices' ], 10, 3 ); + + + add_action( 'cmb2_render_api_keys', 'opalestate_api_keys_callback', 10, 5 ); + + // Include CMB CSS in the head to avoid FOUC + add_action( "admin_print_styles-opalestate_properties_page_opalestate-settings", [ 'CMB2_hookup', 'enqueue_cmb_css' ] ); + } + + public function admin_menu() { + //Settings + $opalestate_settings_page = add_submenu_page( 'edit.php?post_type=opalestate_property', esc_html__( 'Settings', 'opalestate-pro' ), esc_html__( 'Settings', 'opalestate-pro' ), 'manage_opalestate_settings', + 'opalestate-settings', + [ $this, 'admin_page_display' ] ); + + // addons setting + $opalestate_settings_page = add_submenu_page( 'edit.php?post_type=opalestate_property', esc_html__( 'Addons', 'opalestate-pro' ), esc_html__( 'Addons', 'opalestate-pro' ), 'manage_options', 'opalestate-addons', + [ $this, 'admin_addons_page_display' ] ); + + } + + /** + * Register our setting to WP + * + * @since 1.0 + */ + public function init() { + register_setting( $this->key, $this->key ); + + } + + /** + * Retrieve settings tabs + * + * @return array $tabs + * @since 1.0 + */ + public function opalestate_get_settings_tabs() { + + $settings = $this->opalestate_settings( null ); + + $tabs = []; + $tabs['general'] = esc_html__( 'General', 'opalestate-pro' ); + + $tabs['property'] = esc_html__( 'Property', 'opalestate-pro' ); + + if ( ! empty( $settings['addons']['fields'] ) ) { + $tabs['addons'] = esc_html__( 'Add-ons', 'opalestate-pro' ); + } + + if ( ! empty( $settings['licenses']['fields'] ) ) { + $tabs['licenses'] = esc_html__( 'Licenses', 'opalestate-pro' ); + } + + $tabs['api_keys'] = esc_html__( 'API', 'opalestate-pro' ); + $tabs['3rd_party'] = esc_html__( '3rd Party', 'opalestate-pro' ); + + return apply_filters( 'opalestate_settings_tabs', $tabs ); + } + + public function admin_addons_page_display() { + require_once opalestate_get_admin_view( 'addons/list.php' ); + } + + public function get_subtabs_link ( $tab_id , $stab_id ) { + $tab_url = esc_url( add_query_arg( [ + 'settings-updated' => false, + 'tab' => $tab_id, + 'subtab' => $stab_id + ] ) ); + + return $tab_url; + } + /** + * Admin page markup. Mostly handled by CMB2 + * + * @since 1.0 + */ + public function admin_page_display() { + + $active_tab = isset( $_GET['tab'] ) && array_key_exists( $_GET['tab'], $this->opalestate_get_settings_tabs() ) ? $_GET['tab'] : 'general'; + + $sub_active_tab = isset( $_GET['subtab'] ) ? sanitize_text_field( $_GET['subtab'] ): ''; + + $tabs_fields = $this->opalestate_settings( $active_tab ); + $sub_tabs_fields = array(); + + if( empty($sub_active_tab) && $this->subtabs ){ + $first = array_flip( $this->subtabs ); + $sub_active_tab = reset( $first ); + } + + if( $this->subtabs ){ + $sub_tabs_fields = $this->setting_object->get_subtabs_content( $sub_active_tab ); + } + ?> + +
            + +
            + subtabs ): ?> +
            + +
            + + +
            + + key ); ?> + + key ); ?> + +
            +
            + + +
            + + 'page', + 'numberposts' => -1, + ] ); + + $general = array(); + $opalestate_settings = array(); + + //Return all settings array if necessary + + if ( $active_tab === null ) { + return apply_filters( 'opalestate_registered_settings', $opalestate_settings ); + } + + $output = apply_filters( 'opalestate_registered_' . $active_tab . '_settings', isset( $opalestate_settings[ $active_tab ] ) ? $opalestate_settings[ $active_tab ] : [] ); + + if( empty($output) ){ + $class = "Opalestate_Settings_".ucfirst( $active_tab )."_Tab"; + + if( class_exists($class) ){ + $tab = new $class( $this->key ); + $this->setting_object = $tab; + $this->subtabs = $tab->get_subtabs(); + + return $tab->get_tab_content( $this->key ); + } + return array( $active_tab => array() ); + } + // Add other tabs and settings fields as needed + return $output; + + } + + + /** + * Show Settings Notices + * + * @param $object_id + * @param $updated + * @param $cmb + */ + public function settings_notices( $object_id, $updated, $cmb ) { + + //Sanity check + if ( $object_id !== $this->key ) { + return; + } + + if ( did_action( 'cmb2_save_options-page_fields' ) === 1 ) { + settings_errors( 'opalestate-notices' ); + } + + add_settings_error( 'opalestate-notices', 'global-settings-updated', esc_html__( 'Settings updated.', 'opalestate-pro' ), 'updated' ); + + } + + + /** + * Public getter method for retrieving protected/private variables + * + * @param string $field Field to retrieve + * + * @return mixed Field value or exception is thrown + * @since 1.0 + * + */ + public function __get( $field ) { + + // Allowed fields to retrieve + if ( in_array( $field, [ 'key', 'fields', 'opalestate_title', 'options_page' ], true ) ) { + return $this->{$field}; + } + if ( 'option_metabox' === $field ) { + return $this->option_metabox(); + } + + throw new Exception( 'Invalid property: ' . $field ); + } +} \ No newline at end of file diff --git a/inc/admin/settings/3rd_party.php b/inc/admin/settings/3rd_party.php new file mode 100755 index 00000000..22e77a64 --- /dev/null +++ b/inc/admin/settings/3rd_party.php @@ -0,0 +1,137 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + + +class Opalestate_Settings_3rd_party_Tab extends Opalestate_Settings_Base_Tab { + + + public function get_subtabs () { + + $tabs = (array)apply_filters ( + 'opalestate_settings_3rd_party_subtabs_nav', array() + ); + + $tabs = array_merge_recursive( $tabs, array( + 'yelp' => "Yelp", + 'walkcore' => "Walkcore" + ) ); + + return $tabs; + } + + public function get_subtabs_content( $key ="" ) { + // echo $key;die; + $fields = apply_filters ( 'opalestate_settings_3rd_party_subtabs_'.$key.'_fields', array() ); + + if( $key == 'yelp' ){ + $fields = $this->get_yelp_fields(); + }else if( $key == 'walkcore' ){ + $fields = $this->get_walkscore_fields(); + } + + return [ + 'id' => 'options_page', + 'opalestate_title' => esc_html__( '3rd Party Settings', 'opalestate-pro' ), + 'show_on' => [ 'key' => 'options-page', 'value' => [ $key ], ], + 'fields' => (array)$fields + ]; + } + + public function get_walkscore_fields(){ + return array( + [ + 'name' => esc_html__( 'Walk Score', 'opalestate-pro' ), + 'desc' => '', + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_walkscore', + 'before_row' => '
            ', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Walk Score APi Key', 'opalestate-pro' ), + 'desc' => esc_html__( 'Add Walk Score API key. To get your Walk Score API key, go to your Walk Score Account.', 'opalestate-pro' ), + 'id' => 'walkscore_api_key', + 'type' => 'text', + ] + ); + } + + public function get_yelp_fields(){ + return array( + [ + 'name' => esc_html__( 'Yelp', 'opalestate-pro' ), + 'desc' => '', + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_yelp', + 'before_row' => '
            ', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Yelp API Client ID', 'opalestate-pro' ), + 'desc' => esc_html__( 'Add Yelp client ID. To get your Yelp Api Client ID, go to your Yelp Account. Register here', + 'opalestate-pro' ), + 'id' => 'yelp_app_id', + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Yelp API Secret', 'opalestate-pro' ), + 'desc' => esc_html__( 'Add Yelp API Secret. Register here', + 'opalestate-pro' ), + 'id' => 'yelp_app_secret', + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Yelp App key', 'opalestate-pro' ), + 'desc' => esc_html__( 'You can find it in your Yelp Application Dashboard. Register here', + 'opalestate-pro' ), + 'id' => 'yelp_app_key', + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Yelp Categories', 'opalestate-pro' ), + 'desc' => esc_html__( 'Yelp Categories to show on front page', 'opalestate-pro' ), + 'id' => 'yelp_categories', + 'type' => 'multicheck', + 'options' => OpalEstate_Yelp::get_all_categories_options(), + ], + [ + 'name' => esc_html__( 'Yelp - Number of results', 'opalestate-pro' ), + 'desc' => esc_html__( 'Number of results to show on listing page for each category.', 'opalestate-pro' ), + 'id' => 'yelp_number_results', + 'type' => 'text', + 'default' => 3, + 'attributes' => [ + 'type' => 'number', + 'min' => 1, + ], + ], + [ + 'name' => esc_html__( 'Yelp Distance Measurement Unit', 'opalestate-pro' ), + 'desc' => esc_html__( 'Yelp Distance Measurement Unit', 'opalestate-pro' ), + 'id' => 'yelp_measurement_unit', + 'type' => 'select', + 'options' => [ + 'miles' => esc_html__( 'miles', 'opalestate-pro' ), + 'kilometers' => esc_html__( 'kilometers', 'opalestate-pro' ), + ], + 'default' => 'miles', + ] + ); + } + +} \ No newline at end of file diff --git a/inc/admin/settings/api_keys.php b/inc/admin/settings/api_keys.php new file mode 100755 index 00000000..2dd0d6d2 --- /dev/null +++ b/inc/admin/settings/api_keys.php @@ -0,0 +1,46 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Settings_Api_keys_Tab extends Opalestate_Settings_Base_Tab { + + public function get_tabnav () { + + } + + public function get_tab_content( $key= '' ) { + return [ + 'id' => 'api_keys', + 'opalestate_title' => esc_html__( 'API', 'opalestate-pro' ), + 'show_on' => [ 'key' => 'options-page', 'value' => [ $key ], ], + 'show_names' => false, // Hide field names on the left + 'fields' => apply_filters( 'opalestate_settings_api', [ + [ + 'id' => 'api_keys', + 'name' => esc_html__( 'API', 'opalestate-pro' ), + 'type' => 'api_keys', + ], + ] + ), + ]; + } + + public function get_tab_fields () { + + } + +} \ No newline at end of file diff --git a/inc/admin/settings/base.php b/inc/admin/settings/base.php new file mode 100755 index 00000000..87b2c5d9 --- /dev/null +++ b/inc/admin/settings/base.php @@ -0,0 +1,47 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Settings_Base_Tab { + public $key; + + public function __construct ( $key ='' ){ + + $this->key = $key; + } + + public function get_tabnav () { + + } + + public function get_tab_content( $key= '' ) { + + } + + public function get_subtabs(){ + + } + + public function get_tab_fields () { + + } + + public function get_subtabs_content( $subtab ) { + + } + +} \ No newline at end of file diff --git a/inc/admin/settings/email.php b/inc/admin/settings/email.php new file mode 100755 index 00000000..5d67c917 --- /dev/null +++ b/inc/admin/settings/email.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Settings_Email_Tab extends Opalestate_Settings_Base_Tab { + + public function get_tabnav () { + + } + + public function get_tab_content( $key='' ) { + return [ + 'id' => 'options_page', + 'opalestate_title' => esc_html__( 'General Settings', 'opalestate-pro' ), + 'show_on' => [ 'key' => 'options-page', 'value' => [ $key ], ], + 'fields' => $this->get_tab_fields() + ]; + } + + public function get_tab_fields () { + + } + +} \ No newline at end of file diff --git a/inc/admin/settings/general.php b/inc/admin/settings/general.php new file mode 100755 index 00000000..9b4fbaa8 --- /dev/null +++ b/inc/admin/settings/general.php @@ -0,0 +1,257 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Settings_General_Tab extends Opalestate_Settings_Base_Tab { + + public function get_tabnav() { + + } + + public function get_tab_content( $key = '' ) { + return [ + 'id' => 'options_page', + 'opalestate_title' => esc_html__( 'General Settings', 'opalestate-pro' ), + 'show_on' => [ 'key' => 'options-page', 'value' => [ $key, ], ], + 'fields' => $this->get_tab_fields(), + ]; + } + + public function get_tab_fields( $key = '' ) { + $pages = opalestate_cmb2_get_post_options( [ + 'post_type' => 'page', + 'numberposts' => -1, + ] ); + + return apply_filters( 'opalestate_settings_general', [ + [ + 'name' => esc_html__( 'General Settings', 'opalestate-pro' ), + + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_1', + 'before_row' => '
            ', + 'after_row' => '
            ', + ], + + [ + 'name' => esc_html__( 'User Management Page', 'opalestate-pro' ), + 'desc' => esc_html__( 'This is page use User Management Page using for show content of management page such as profile, my properties', 'opalestate-pro' ), + 'id' => 'user_management_page', + 'type' => 'select', + 'options' => $pages, + ], + [ + 'name' => esc_html__( 'My Account Page', 'opalestate-pro' ), + 'desc' => esc_html__( 'This is page use User login and register an account, or reset password.', 'opalestate-pro' ), + 'id' => 'user_myaccount_page', + 'type' => 'select', + 'options' => $pages, + ], + [ + 'name' => esc_html__( 'Enable Message Database', 'opalestate-pro' ), + 'desc' => esc_html__( 'Allow User send message Contact/Equire via email and saved into database to exchange theirs message direct in User Message Management', 'opalestate-pro' ), + 'id' => 'message_log', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + + ], + + [ + 'name' => esc_html__( 'Maximun Upload Image Size', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set maximun volumn size having < x MB', 'opalestate-pro' ), + + 'id' => 'upload_image_max_size', + 'type' => 'text', + 'default' => '0.5', + ], + [ + 'name' => esc_html__( 'Maximun Upload Image Files', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set maximun volumn size having < x MB', 'opalestate-pro' ), + + 'id' => 'upload_image_max_files', + 'type' => 'text', + 'default' => '10', + ], + [ + 'name' => esc_html__( 'Maximun Upload Other Size', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set maximun volumn size having < x MB for upload docx, pdf...', 'opalestate-pro' ), + + 'id' => 'upload_other_max_size', + 'type' => 'text', + 'default' => '0.8' + ], + [ + 'name' => esc_html__( 'Maximun Upload Other Files', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set maximun volumn size having < x MB for upload docx, pdf...', 'opalestate-pro' ), + + 'id' => 'upload_other_max_files', + 'type' => 'text', + 'default' => '10', + 'after_row' => '
            ' + ], + [ + 'name' => esc_html__( 'Agent Image Size', 'opalestate-pro' ), + 'desc' => esc_html__( 'The Loop Image is an Agent that is chosen as the representative Agent in grid and list.', 'opalestate-pro' ), + + 'id' => 'agent_image_size', + 'type' => 'select', + 'default' => 'medium', + 'options' => opalestate_get_featured_image_sizes(), + + ], + + [ + 'name' => esc_html__( 'Agent Image Size', 'opalestate-pro' ), + 'desc' => esc_html__( 'The Loop Image is an Agent that is chosen as the representative Agent in grid and list.', 'opalestate-pro' ), + + 'id' => 'agent_image_size', + 'type' => 'select', + 'default' => 'medium', + 'options' => opalestate_get_featured_image_sizes(), + + ], + + + [ + 'name' => esc_html__( 'Loop Image Size', 'opalestate-pro' ), + 'desc' => esc_html__( 'The Loop Image is an image that is chosen as the representative image in grid and list.', 'opalestate-pro' ), + + 'id' => 'loop_image_size', + 'type' => 'select', + 'default' => 'large', + 'options' => opalestate_get_featured_image_sizes(), + ], + + + [ + 'name' => esc_html__( 'Featured Image Size', 'opalestate-pro' ), + 'desc' => esc_html__( 'The Featured Image is an image that is chosen as the representative image in single page. .', 'opalestate-pro' ), + 'id' => 'featured_image_size', + 'type' => 'select', + 'default' => 'full', + 'options' => opalestate_get_featured_image_sizes(), + 'after_row' => '' . esc_html__( 'To generate images with new image sizes, you can use this Force Regenerate Thumbnails', + 'opalestate-pro' ) . '', + ], + [ + 'name' => esc_html__( 'Minimum of Target Price For Agent', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enter minimum of price for starting search agent by target', 'opalestate-pro' ), + 'id' => 'search_agent_min_price', + 'type' => 'text_medium', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 0, + ], + [ + 'name' => esc_html__( 'Maximum of Target Price For Agent', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enter maximum of price for starting search agent by target', 'opalestate-pro' ), + 'id' => 'search_agent_max_price', + 'type' => 'text_medium', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 1000000, + ], + [ + 'name' => esc_html__( 'Single Layout Page', 'opalestate-pro' ), + 'desc' => esc_html__( 'Choose layout for single property.', 'opalestate-pro' ), + 'id' => 'layout', + 'type' => 'select', + 'options' => apply_filters( 'opalestate_single_layout_templates', [ '' => esc_html__( 'Inherit', 'opalestate-pro' ) ] ), + ], + + + [ + 'name' => esc_html__( 'Currency Settings', 'opalestate-pro' ), + 'desc' => '', + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_2', + 'before_row' => '
            ', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Currency', 'opalestate-pro' ), + 'desc' => 'Choose your currency. Note that some payment gateways have currency restrictions.', + 'id' => 'currency', + 'type' => 'select', + 'options' => opalestate_get_currencies(), + 'default' => 'USD', + ], + [ + 'name' => esc_html__( 'Currency Position', 'opalestate-pro' ), + 'desc' => 'Choose the position of the currency sign.', + 'id' => 'currency_position', + 'type' => 'select', + 'options' => [ + 'before' => esc_html__( 'Before - $10', 'opalestate-pro' ), + 'after' => esc_html__( 'After - 10$', 'opalestate-pro' ), + ], + 'default' => 'before', + ], + [ + 'name' => esc_html__( 'Thousands Separator', 'opalestate-pro' ), + 'desc' => esc_html__( 'The symbol (typically , or .) to separate thousands', 'opalestate-pro' ), + 'id' => 'thousands_separator', + 'type' => 'text_small', + 'default' => ',', + ], + [ + 'name' => esc_html__( 'Decimal Separator', 'opalestate-pro' ), + 'desc' => esc_html__( 'The symbol (usually , or .) to separate decimal points', 'opalestate-pro' ), + 'id' => 'decimal_separator', + 'type' => 'text_small', + 'default' => '.', + ], + [ + 'name' => esc_html__( 'Number of Decimals', 'opalestate-pro' ), + 'desc' => esc_html__( 'This sets the number of decimal points shown in displayed prices.', 'opalestate-pro' ), + 'id' => 'number_decimals', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 2, + ], + [ + 'name' => esc_html__( 'Measurement Unit', 'opalestate-pro' ), + 'desc' => esc_html__( 'Measurement Unit', 'opalestate-pro' ), + 'id' => 'measurement_unit', + 'type' => 'select', + 'options' => apply_filters( 'opalestate_measurement_unit', [ + 'sq ft' => esc_html__( 'sq ft', 'opalestate-pro' ), + 'sq m' => esc_html__( 'sq m', 'opalestate-pro' ), + 'mq' => esc_html__( 'mq', 'opalestate-pro' ), + 'm2' => esc_html__( 'm2', 'opalestate-pro' ), + ] ), + 'default' => 'sq ft', + ], + [ + 'name' => esc_html__( 'Google Map API', 'opalestate-pro' ), + 'desc' => __( 'You need to register Google API Key, then put the key in this setting.', + 'opalestate-pro' ), + 'id' => 'google_map_api_keys', + 'type' => 'text', + 'default' => 'AIzaSyCfMVNIa7khIqYHCw6VBn8ShUWWm4tjbG8', + ], + ] + ); + } +} diff --git a/inc/admin/settings/property.php b/inc/admin/settings/property.php new file mode 100755 index 00000000..17443ad9 --- /dev/null +++ b/inc/admin/settings/property.php @@ -0,0 +1,446 @@ + + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Settings_Property_Tab extends Opalestate_Settings_Base_Tab { + public function get_subtabs() { + return apply_filters( + 'opalestate_settings_property_subtabs_nav', + [ + 'property_general' => esc_html__( 'General', 'opalestate-pro' ), + 'property_search' => esc_html__( 'Search Page', 'opalestate-pro' ), + 'property_detail' => esc_html__( 'Single Page', 'opalestate-pro' ), + ] + ); + } + + public function get_subtabs_content( $key = "" ) { + $fields = apply_filters( 'opalestate_settings_property_subtabs_' . $key . '_fields', [] ); + if ( $fields ) { + + } else { + switch ( $key ) { + case 'property_search': + $fields = $this->get_subtab_search_fields(); + break; + + case 'property_detail': + $fields = $this->get_subtab_detail_fields(); + break; + + default: + $fields = $this->get_subtab_property_fields(); + break; + } + } + + return [ + 'id' => 'options_page', + 'opalestate_title' => esc_html__( 'Property Settings', 'opalestate-pro' ), + 'show_on' => [ 'key' => 'options-page', 'value' => [ $key ], ], + 'fields' => $fields, + ]; + } + + private function get_subtab_property_fields() { + $fields = []; + + $fields[] = [ + 'name' => esc_html__( 'Enable User Submission', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable to allow user post/submit properties in front-end', 'opalestate-pro' ), + 'id' => 'enable_submission', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + // show setting short meta infox + $metabox = new Opalestate_Property_MetaBox(); + $metas = $metabox->metaboxes_info_fields(); + + $checkes = []; + + foreach ( $metas as $key => $field ) { + $id = str_replace( OPALESTATE_PROPERTY_PREFIX, '', $field['id'] ); + $checkes [ $id ] = $field['name']; + } + + $fields[] = [ + 'name' => esc_html__( 'Show Meta Information in Grid and Single Page', 'opalestate-pro' ), + 'id' => 'show_property_meta', + 'type' => 'multicheck', + 'options' => $checkes, + ]; + + $fields[] = [ + 'name' => esc_html__( 'Archive Grid layout', 'opalestate-pro' ), + 'id' => 'property_archive_grid_layout', + 'type' => 'select', + 'options' => opalestate_get_loop_property_grid_layouts(), + ]; + + $fields[] = [ + 'name' => esc_html__( 'Archive List layout', 'opalestate-pro' ), + 'id' => 'property_archive_list_layout', + 'type' => 'select', + 'options' => opalestate_get_loop_property_list_layouts(), + ]; + + return $fields; + } + + private function get_subtab_search_fields() { + $pages = opalestate_cmb2_get_post_options( [ + 'post_type' => 'page', + 'numberposts' => -1, + ] ); + + $metabox = new Opalestate_Property_MetaBox(); + $metas = $metabox->metaboxes_info_fields(); + + $fields = []; + + if ( $metas ) { + $fields[] = [ + 'name' => esc_html__( 'User Share Search', 'opalestate-pro' ), + 'desc' => esc_html__( 'Display Share Search Link Management', 'opalestate-pro' ), + 'id' => 'enable_share_earch', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'User Saved Search', 'opalestate-pro' ), + 'desc' => esc_html__( 'Display Save Search Link Management', 'opalestate-pro' ), + 'id' => 'enable_saved_usersearch', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + + $fields[] = [ + 'name' => esc_html__( 'Search Properties Page', 'opalestate-pro' ), + 'desc' => esc_html__( 'This is page to display result of properties after user searching via form.', + 'opalestate-pro' ), + 'id' => 'search_map_properties_page', + 'type' => 'select', + 'options' => opalestate_cmb2_get_post_options( [ + 'post_type' => 'page', + 'numberposts' => -1, + ] ), + 'default' => '', + ]; + + $fields[] = [ + 'name' => esc_html__( 'Properties Per Page', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enter min of properties display in search page', 'opalestate-pro' ), + 'id' => 'search_property_per_page', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 9, + ]; + + + $fields[] = [ + 'name' => esc_html__( 'Show Featured First', 'opalestate-pro' ), + 'id' => 'show_featured_first', + 'desc' => esc_html__( 'Show featured first in page result, as default Newest is showed', 'opalestate-pro' ), + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'Disable', 'opalestate-pro' ), + 1 => esc_html__( 'Enable', 'opalestate-pro' ), + ], + 'default' => 0, + ]; + $fields[] = [ + 'name' => esc_html__( 'Minimum of Search Price', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enter minimum of price for starting search', 'opalestate-pro' ), + 'id' => 'search_min_price', + 'type' => 'text_medium', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 0, + ]; + $fields[] = [ + 'name' => esc_html__( 'Maximum of Search Price', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enter maximum of price for starting search', 'opalestate-pro' ), + 'id' => 'search_max_price', + 'type' => 'text_medium', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 10000000, + ]; + + + $fields[] = [ + 'name' => esc_html__( 'Minimum of Search Aea', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enter minimum of area for starting search', 'opalestate-pro' ), + 'id' => 'search_min_area', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 0, + ]; + $fields[] = [ + 'name' => esc_html__( 'Maximum of Search Aea', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enter maximum of area for starting search', 'opalestate-pro' ), + 'id' => 'search_max_area', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 1000, + ]; + + $fields[] = [ + 'name' => esc_html__( 'Search Grid layout', 'opalestate-pro' ), + 'id' => 'property_search_grid_layout', + 'type' => 'select', + 'options' => opalestate_get_loop_property_grid_layouts(), + ]; + + $fields[] = [ + 'name' => esc_html__( 'Search List layout', 'opalestate-pro' ), + 'id' => 'property_search_list_layout', + 'type' => 'select', + 'options' => opalestate_get_loop_property_list_layouts(), + ]; + + $fields[] = [ + 'name' => esc_html__( 'Horizontal Search Fields', 'opalestate-pro' ), + 'desc' => esc_html__( 'Disable or enable fields appearing in search form', 'opalestate-pro' ), + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_1', + 'before_row' => '
            ', + 'after_row' => '
            ', + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Price', 'opalestate-pro' ), + 'id' => OPALESTATE_PROPERTY_PREFIX . 'price_opt', + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'Disable', 'opalestate-pro' ), + 1 => esc_html__( 'Enable', 'opalestate-pro' ), + ], + ]; + + foreach ( $metas as $key => $meta ) { + $fields[] = [ + 'name' => $meta['name'], + 'id' => $meta['id'] . '_opt', + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'Disable', 'opalestate-pro' ), + 1 => esc_html__( 'Enable', 'opalestate-pro' ), + ], + ]; + } + + $fields[] = [ + 'name' => esc_html__( 'Vertical Search Fields', 'opalestate-pro' ), + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_2', + 'before_row' => '
            ', + 'after_row' => '
            ', + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Price', 'opalestate-pro' ), + 'id' => OPALESTATE_PROPERTY_PREFIX . 'price_opt_v', + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'Disable', 'opalestate-pro' ), + 1 => esc_html__( 'Enable', 'opalestate-pro' ), + ], + ]; + + foreach ( $metas as $key => $meta ) { + $fields[] = [ + 'name' => $meta['name'], + 'id' => $meta['id'] . '_opt_v', + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'Disable', 'opalestate-pro' ), + 1 => esc_html__( 'Enable', 'opalestate-pro' ), + ], + + ]; + } + } + + return $fields; + } + + /** + * + */ + private function get_subtab_detail_fields() { + $fields = []; + + $fields[] = [ + 'name' => esc_html__( 'Show Amenities tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Amenities tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_amenities', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Facilities tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Facilities tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_facilities', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Attachments tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Attachments tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_attachments', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Video tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Video tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_video', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Map tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Map tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_map', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Nearby tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Nearby tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_nearby', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Walk Scores tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Walk Scores tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_walkscores', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Apartments tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Apartments tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_apartments', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Floor Plans tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Floor Plans tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_floor_plans', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Show Views Statistics tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Views Statistics tab in the single property page.', 'opalestate-pro' ), + 'id' => 'enable_single_views_statistics', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ]; + + $fields[] = [ + 'name' => esc_html__( 'Views Statistics time limit (days)', 'opalestate-pro' ), + 'desc' => esc_html__( 'The number of days will be saved to the database.', 'opalestate-pro' ), + 'id' => 'single_views_statistics_limit', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + 'min' => 1, + 'max' => 365, + ], + 'default' => 8, + ]; + + $fields[] = [ + 'name' => esc_html__( 'Related properties layout', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select a layout for related properties.', 'opalestate-pro' ), + 'id' => 'single_related_properties_layout', + 'type' => 'select', + 'options' => opalestate_get_loop_property_layouts(), + ]; + + $fields[] = [ + 'name' => esc_html__( 'Nearby properties layout', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select a layout for nearby properties.', 'opalestate-pro' ), + 'id' => 'single_nearby_properties_layout', + 'type' => 'select', + 'options' => opalestate_get_loop_property_layouts(), + ]; + + return $fields; + } +} diff --git a/inc/admin/views/addons/list.php b/inc/admin/views/addons/list.php new file mode 100755 index 00000000..ca41b666 --- /dev/null +++ b/inc/admin/views/addons/list.php @@ -0,0 +1,348 @@ +
            +

            + +

            + + $tag, + ] ); + + if ( ! is_wp_error( $plugins_api ) ) { + $plugins = $plugins_api->plugins; + $plugins_allowedtags = [ + 'a' => [ + 'href' => [], + 'title' => [], + 'target' => [], + ], + 'abbr' => [ 'title' => [] ], + 'acronym' => [ 'title' => [] ], + 'code' => [], + 'pre' => [], + 'em' => [], + 'strong' => [], + 'ul' => [], + 'ol' => [], + 'li' => [], + 'p' => [], + 'br' => [], + ]; + + $plugins_group_titles = [ + 'Performance' => _x( 'Performance', 'Plugin installer group title' ), + 'Social' => _x( 'Social', 'Plugin installer group title' ), + 'Tools' => _x( 'Tools', 'Plugin installer group title' ), + ]; + $group = null; + ?> + +
            + + groups[ $plugin['group'] ] ) ) { + $group_name = $this->groups[ $plugin['group'] ]; + if ( isset( $plugins_group_titles[ $group_name ] ) ) { + $group_name = $plugins_group_titles[ $group_name ]; + } + } else { + $group_name = $plugin['group']; + } + + // Starting a new group, close off the divs of the last one + if ( ! empty( $group ) ) { + echo '
            '; + } + + echo '

            ' . esc_html( $group_name ) . '

            '; + // needs an extra wrapping div for nth-child selectors to work + echo '
            '; + + $group = $plugin['group']; + } + $title = wp_kses( $plugin['name'], $plugins_allowedtags ); + + // Remove any HTML from the description. + $description = strip_tags( $plugin['short_description'] ); + $version = wp_kses( $plugin['version'], $plugins_allowedtags ); + + $name = strip_tags( $title . ' ' . $version ); + + $author = wp_kses( $plugin['author'], $plugins_allowedtags ); + if ( ! empty( $author ) ) { + $author = ' ' . sprintf( __( 'By %s' ), $author ) . ''; + } + + $requires_php = isset( $plugin['requires_php'] ) ? $plugin['requires_php'] : null; + $requires_wp = isset( $plugin['requires'] ) ? $plugin['requires'] : null; + + $compatible_php = is_php_version_compatible( $requires_php ); + $compatible_wp = is_wp_version_compatible( $requires_wp ); + $tested_wp = ( empty( $plugin['tested'] ) || version_compare( get_bloginfo( 'version' ), $plugin['tested'], '<=' ) ); + + $action_links = []; + + if ( current_user_can( 'install_plugins' ) || current_user_can( 'update_plugins' ) ) { + $status = install_plugin_install_status( $plugin ); + + switch ( $status['status'] ) { + case 'install': + if ( $status['url'] ) { + if ( $compatible_php && $compatible_wp ) { + $action_links[] = sprintf( + '%s', + esc_attr( $plugin['slug'] ), + esc_url( $status['url'] ), + /* translators: %s: plugin name and version */ + esc_attr( sprintf( __( 'Install %s now' ), $name ) ), + esc_attr( $name ), + __( 'Install Now' ) + ); + } else { + $action_links[] = sprintf( + '', + _x( 'Cannot Install', 'plugin' ) + ); + } + } + break; + + case 'update_available': + if ( $status['url'] ) { + if ( $compatible_php && $compatible_wp ) { + $action_links[] = sprintf( + '%s', + esc_attr( $status['file'] ), + esc_attr( $plugin['slug'] ), + esc_url( $status['url'] ), + /* translators: %s: plugin name and version */ + esc_attr( sprintf( __( 'Update %s now' ), $name ) ), + esc_attr( $name ), + __( 'Update Now' ) + ); + } else { + $action_links[] = sprintf( + '', + _x( 'Cannot Update', 'plugin' ) + ); + } + } + break; + + case 'latest_installed': + case 'newer_installed': + if ( is_plugin_active( $status['file'] ) ) { + $action_links[] = sprintf( + '', + _x( 'Active', 'plugin' ) + ); + } elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) { + $button_text = __( 'Activate' ); + /* translators: %s: plugin name */ + $button_label = _x( 'Activate %s', 'plugin' ); + $activate_url = add_query_arg( + [ + '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $status['file'] ), + 'action' => 'activate', + 'plugin' => $status['file'], + ], + network_admin_url( 'plugins.php' ) + ); + + if ( is_network_admin() ) { + $button_text = __( 'Network Activate' ); + /* translators: %s: plugin name */ + $button_label = _x( 'Network Activate %s', 'plugin' ); + $activate_url = add_query_arg( [ 'networkwide' => 1 ], $activate_url ); + } + + $action_links[] = sprintf( + '%3$s', + esc_url( $activate_url ), + esc_attr( sprintf( $button_label, $plugin['name'] ) ), + $button_text + ); + } else { + $action_links[] = sprintf( + '', + _x( 'Installed', 'plugin' ) + ); + } + break; + } + } + + $details_link = self_admin_url( + 'plugin-install.php?tab=plugin-information&plugin=' . $plugin['slug'] . + '&TB_iframe=true&width=600&height=550' + ); + + $action_links[] = sprintf( + '%s', + esc_url( $details_link ), + /* translators: %s: plugin name and version */ + esc_attr( sprintf( __( 'More information about %s' ), $name ) ), + esc_attr( $name ), + __( 'More Details' ) + ); + + if ( ! empty( $plugin['icons']['svg'] ) ) { + $plugin_icon_url = $plugin['icons']['svg']; + } elseif ( ! empty( $plugin['icons']['2x'] ) ) { + $plugin_icon_url = $plugin['icons']['2x']; + } elseif ( ! empty( $plugin['icons']['1x'] ) ) { + $plugin_icon_url = $plugin['icons']['1x']; + } else { + $plugin_icon_url = $plugin['icons']['default']; + } + + /** + * Filters the install action links for a plugin. + * + * @param string[] $action_links An array of plugin action links. Defaults are links to Details and Install Now. + * @param array $plugin The plugin currently being listed. + * @since 2.7.0 + * + */ + $action_links = apply_filters( 'plugin_install_action_links', $action_links, $plugin ); + + $last_updated_timestamp = strtotime( $plugin['last_updated'] ); + ?> +
            +

            '; + if ( ! $compatible_php && ! $compatible_wp ) { + _e( 'This plugin doesn’t work with your versions of WordPress and PHP.' ); + if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { + printf( + /* translators: 1: "Update WordPress" screen URL, 2: "Update PHP" page URL */ + ' ' . __( 'Please update WordPress, and then learn more about updating PHP.' ), + self_admin_url( 'update-core.php' ), + esc_url( wp_get_update_php_url() ) + ); + wp_update_php_annotation( '

            ', '' ); + } elseif ( current_user_can( 'update_core' ) ) { + printf( + /* translators: %s: "Update WordPress" screen URL */ + ' ' . __( 'Please update WordPress.' ), + self_admin_url( 'update-core.php' ) + ); + } elseif ( current_user_can( 'update_php' ) ) { + printf( + /* translators: %s: "Update PHP" page URL */ + ' ' . __( 'Learn more about updating PHP.' ), + esc_url( wp_get_update_php_url() ) + ); + wp_update_php_annotation( '

            ', '' ); + } + } elseif ( ! $compatible_wp ) { + _e( 'This plugin doesn’t work with your version of WordPress.' ); + if ( current_user_can( 'update_core' ) ) { + printf( + /* translators: %s: "Update WordPress" screen URL */ + ' ' . __( 'Please update WordPress.' ), + self_admin_url( 'update-core.php' ) + ); + } + } elseif ( ! $compatible_php ) { + _e( 'This plugin doesn’t work with your version of PHP.' ); + if ( current_user_can( 'update_php' ) ) { + printf( + /* translators: %s: "Update PHP" page URL */ + ' ' . __( 'Learn more about updating PHP.' ), + esc_url( wp_get_update_php_url() ) + ); + wp_update_php_annotation( '

            ', '' ); + } + } + echo '

            '; + } + ?> +
            +
            +

            + + + + +

            +
            + +
            +

            +

            +
            +
            +
            +
            + $plugin['rating'], + 'type' => 'percent', + 'number' => $plugin['num_ratings'], + ] + ); + ?> + +
            +
            + +
            +
            + = 1000000 ) { + $active_installs_millions = floor( $plugin['active_installs'] / 1000000 ); + $active_installs_text = sprintf( + _nx( '%s+ Million', '%s+ Million', $active_installs_millions, 'Active plugin installations' ), + number_format_i18n( $active_installs_millions ) + ); + } elseif ( 0 == $plugin['active_installs'] ) { + $active_installs_text = _x( 'Less Than 10', 'Active plugin installations' ); + } else { + $active_installs_text = number_format_i18n( $plugin['active_installs'] ) . '+'; + } + printf( __( '%s Active Installations' ), $active_installs_text ); + ?> +
            +
            + ' . __( 'Untested with your version of WordPress' ) . ''; + } elseif ( ! $compatible_wp ) { + echo '' . __( 'Incompatible with your version of WordPress' ) . ''; + } else { + echo '' . __( 'Compatible with your version of WordPress' ) . ''; + } + ?> +
            +
            +
            + +
            + +

            ' . esc_html__( 'There was an error retrieving the Opalestate Add-ons list from the server. Please try again later.', 'opalestate-pro' ) . ''; + } + ?> + diff --git a/inc/agency/class-opalestate-agency-front.php b/inc/agency/class-opalestate-agency-front.php new file mode 100755 index 00000000..2b027d7f --- /dev/null +++ b/inc/agency/class-opalestate-agency-front.php @@ -0,0 +1,482 @@ + + */ + +// Exit if accessed directly +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +class Opalestate_Agency_Front { + + /** + * Instance. + * + * @access private + * @var Opalestate_Agent_Front + */ + static private $instance; + + /** + * Singleton pattern. + * + * @since $Id + * @access private + */ + private function __construct() { + } + + /** + * Get instance. + * + * @return Opalestate_Agent_Front + * @since $Id + * @access public + */ + public static function get_instance() { + if ( null === static::$instance ) { + self::$instance = new static(); + + self::$instance->init(); + } + + return self::$instance; + } + + public $new_attachmenet_ids; + + /** + * Auto update meta information to post from user data updated or created + */ + public function init() { + add_action( 'opalestate_on_set_role_agency', [ $this, 'on_set_role' ], 1, 9 ); + add_filter( 'opalestate_before_render_profile_agency_form', [ $this, 'render_front_form' ], 2, 2 ); + + add_action( 'save_post', [ $this, 'on_save_post' ], 13, 2 ); + add_filter( 'pre_get_posts', [ $this, 'archives_query' ], 1 ); + add_action( 'cmb2_after_init', [ $this, 'on_save_front_data' ] ); + + add_filter( 'opalestate_management_user_menu', [ $this, 'render_extra_profile_link' ] ); + + add_action( "opalestate_user_content_agency_profile_page", [ $this, 'render_profile' ] ); + add_action( "opalestate_user_content_agency_team_page", [ $this, 'render_team' ] ); + add_action( "opalestate_user_init", [ $this, 'process_action_member' ] ); + + $this->register_shortcodes(); + } + + /** + * + */ + public function render_extra_profile_link( $menu ) { + global $current_user; + + $user_roles = $current_user->roles; + $user_role = array_shift( $user_roles ); + + if ( $user_role == 'opalestate_agency' ) { + $menu['agency_profile'] = [ + 'icon' => 'fa fa-user', + 'link' => "agency_profile", + 'title' => esc_html__( 'Agency Profile', 'opalestate-pro' ), + 'id' => 0, + ]; + $menu['agency_team'] = [ + 'icon' => 'fa fa-users', + 'link' => "agency_team", + 'title' => esc_html__( 'Agency Team', 'opalestate-pro' ), + 'id' => 0, + ]; + } + + return $menu; + } + + /** + * Auto update meta information to post from user data updated or created + */ + public function archives_query( $query ) { + if ( $query->is_main_query() && is_post_type_archive( 'opalestate_agency' ) ) { + if ( isset( $_GET['location'] ) && $_GET['location'] != -1 ) { + $tax_query = []; + + $tax_query[] = [ + 'taxonomy' => 'opalestate_location', + 'field' => 'slug', + 'terms' => sanitize_text_field( $_GET['location'] ), + ]; + $args['tax_query'] = [ 'relation' => 'AND' ]; + $args['tax_query'] = array_merge( $args['tax_query'], $tax_query ); + $query->set( 'tax_query', $tax_query ); + } + if ( isset( $_GET['search_text'] ) ) { + $query->set( 's', sanitize_text_field( $_GET['search_text'] ) ); + } + } + + return $query; + } + + /** + * + */ + private function update_data_agent_or_agency( $prefix ) { + + global $current_user; + + $post_id = isset( $_POST['object_id'] ) && absint( $_POST['object_id'] ) ? $_POST['object_id'] : 0; + $user_id = get_current_user_id(); + $metaboxes = apply_filters( 'opalestate_before_render_profile_agency_form', [], $post_id ); + $metaboxes = apply_filters( 'cmb2_meta_boxes', $metaboxes ); + + + if ( isset( $metaboxes[ $prefix . 'front' ] ) ) { + if ( ! empty( $post_id ) ) { + $old_post = get_post( $post_id ); + $post_date = $old_post->post_date; + } else { + $post_date = ''; + } + $post = get_post( $post_id ); + $data = [ + 'ID' => $post->ID ? $post_id : null, + 'post_title' => sanitize_text_field( $_POST[ $prefix . 'title' ] ), + 'post_author' => $user_id, + 'post_type' => 'opalestate_agency', + 'post_date' => $post_date, + 'post_content' => wp_kses( $_POST[ $prefix . 'text' ], '

            ' ), + ]; + + unset( $_POST[ $prefix . 'title' ] ); + unset( $_POST[ $prefix . 'text' ] ); + + + if ( $data['ID'] > 0 ) { + $post_id = wp_update_post( $data, true ); + } else { + $data['post_status'] = 'pending'; + $post_id = wp_insert_post( $data, true ); + } + + $post = get_post( $post_id ); + + if ( empty( $post->post_content ) || empty( $post->post_title ) || ! has_post_thumbnail( $post_id ) ) { + + // $data['post_status'] = 'public'; + // $data['ID'] = $post_id; + // $post_id = wp_update_post( $data , true ); + } + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', $post_id ); + + /* + * Processing upload files + */ + $this->process_upload_files( $post_id, $_POST ); + + + cmb2_get_metabox_form( $metaboxes[ $prefix . 'front' ], $post_id ); + $cmb = cmb2_get_metabox( $prefix . 'front', $post_id ); + $sanitized_values = $cmb->get_sanitized_values( $_POST ); + $cmb->save_fields( $post_id, 'post', $sanitized_values ); + /// update + // Create featured image + $featured_image = get_post_meta( $post_id, $prefix . 'featured_image', true ); + + if ( ! empty( $_POST[ $prefix . 'featured_image' ] ) && isset( $_POST[ $prefix . 'featured_image' ] ) ) { + set_post_thumbnail( $post_id, sanitize_text_field( $_POST[ $prefix . 'featured_image' ] ) ); + unset( $_POST[ $prefix . 'featured_image' ] ); + } else { + delete_post_thumbnail( $post_id ); + } + + // set ready of attachment for use. + if ( $this->new_attachmenet_ids ) { + foreach ( $this->new_attachmenet_ids as $_id ) { + delete_post_meta( $_id, '_pending_to_use_', 1 ); + } + } + + return $post_id; + } + + return false; + } + + /** + * + * + */ + private function get_field_name( $field ) { + return OPALESTATE_AGENCY_PREFIX . $field; + } + + private function process_upload_files( $post_id ) { + + //upload images for featured and gallery images + if ( isset( $_FILES ) && ! empty( $_FILES ) ) { + + /// + $fields = [ + $this->get_field_name( 'avatar_id' ), + $this->get_field_name( 'gallery' ), + $this->get_field_name( 'featured_image' ), + ]; + + foreach ( $_FILES as $key => $value ) { + // allow processing in fixed collection + if ( in_array( $key, $fields ) ) { + $ufile = $_FILES[ $key ]; + + /// ///// + if ( isset( $ufile['name'] ) && is_array( $ufile['name'] ) ) { + $output = []; + + foreach ( $ufile['name'] as $f_key => $f_value ) { + $loop_file = [ + 'name' => $ufile['name'][ $f_key ], + 'type' => $ufile['type'][ $f_key ], + 'tmp_name' => $ufile['tmp_name'][ $f_key ], + 'error' => $ufile['error'][ $f_key ], + 'size' => $ufile['size'][ $f_key ], + ]; + $new_atm = $this->upload_image( $loop_file, $post_id ); + if ( $new_atm ) { + $_POST[ $key ] = isset( $_POST[ $key ] ) ? sanitize_text_field( $_POST[ $key ] ) : []; + $_POST[ $key ][ $new_atm['attachment_id'] ] = $new_atm['url']; + $this->new_attachmenet_ids[ $new_atm['attachment_id'] ] = $new_atm['attachment_id']; + } + } + + } /// + elseif ( isset( $ufile['name'] ) ) { + $new_atm = $this->upload_image( $ufile, $post_id ); + if ( $new_atm ) { + $_POST[ $key ] = $new_atm['attachment_id']; + + if ( preg_match( "#id#", $key ) ) { + $_key = str_replace( "_id", "", $key ); + $_POST[ $_key ] = $new_atm['url']; + } + $this->new_attachmenet_ids[ $new_atm['attachment_id'] ] = $new_atm['attachment_id']; + } + } + } + } + } + } + + /** + * Process upload images for properties + */ + public function upload_image( $submitted_file, $parent_id = 0 ) { + return opalesate_upload_image( $submitted_file, $parent_id ); + } + + public function on_save_front_data() { + + if ( isset( $_POST[ 'nonce_CMB2php' . OPALESTATE_AGENCY_PREFIX . 'front' ] ) ) { + + $post_id = isset( $_POST['object_id'] ) && $_POST['object_id'] ? absint( $_POST['object_id'] ) : 0; + + $post = get_post( $post_id ); + + $post_id = $this->update_data_agent_or_agency( OPALESTATE_AGENCY_PREFIX ); + + if ( $post_id ) { + OpalEstate_Agency::update_user_data( get_current_user_id() ); + } + + return opalestate_output_msg_json( true, + __( 'The data updated successful, please wait for redirecting', 'opalestate-pro' ), + [ + 'heading' => esc_html__( 'Update Information', 'opalestate-pro' ), + 'redirect' => opalestate_get_user_management_page_uri( [ 'tab' => 'agency_profile' ] ), + ] + ); + + return opalestate_output_msg_json( false, + __( 'Currently, The data could not save!', 'opalestate-pro' ), + [ 'heading' => esc_html__( 'Update Information', 'opalestate-pro' ) ] + ); + } + } + + /** + * + */ + public function register_shortcodes() { + + } + + /** + * + */ + public function render_profile() { + + $post_id = OpalEstate_User::get_member_id(); + + if ( isset( $post->ID ) && $post->post_status != 'publish' ) { + opalestate_add_notice( "warning", esc_html__( 'You account is under reviewing! it take some time to process' ) ); + add_action( "opalestate_profile_agency_form_before", "opalestate_print_notices" ); + } + + $metaboxes = $this->render_front_form( [], $post_id ); + + return opalestate_load_template_path( 'user/agency/profile-agency', [ 'metaboxes' => $metaboxes, 'post_id' => $post_id ] ); + } + + /** + * + */ + public function render_team() { + $user_id = get_current_user_id(); + $post_id = OpalEstate_User::get_member_id(); + + $metaboxes = $this->render_front_form( [], $post_id ); + + return opalestate_load_template_path( 'user/agency/agency-team', [ 'metaboxes' => $metaboxes, 'post_id' => $post_id ] ); + } + + /** + * + */ + public function process_action_member() { + if ( isset( $_POST['add_team_action'] ) && wp_verify_nonce( $_POST['add_team_action'], 'agency-add-member' ) ) { + + if ( isset( $_POST['user_id'] ) ) { + + $user_id = get_current_user_id(); + $post_id = OpalEstate_User::get_member_id(); + + $team = get_post_meta( $post_id, OPALESTATE_AGENCY_PREFIX . 'team', true ); + + if ( empty( $team ) ) { + $team = []; + } + $team[] = intval( $_POST['user_id'] ); + $team = array_unique( $team ); + + update_post_meta( $post_id, OPALESTATE_AGENCY_PREFIX . 'team', $team ); + + } + } + + if ( isset( $_GET['tab'] ) && $_GET['tab'] == "agency_team" && isset( $_GET['remove_id'] ) && $_GET['remove_id'] ) { + + $remove_id = intval( $_GET['remove_id'] ); + + $user_id = get_current_user_id(); + $post_id = OpalEstate_User::get_member_id(); + + $team = get_post_meta( $post_id, OPALESTATE_AGENCY_PREFIX . 'team', true ); + + if ( empty( $team ) ) { + $team = []; + } + $team[] = $user_id; + $team = array_unique( $team ); + foreach ( $team as $key => $id ) { + if ( $id == $remove_id ) { + unset( $team[ $key ] ); + } + } + update_post_meta( $post_id, OPALESTATE_AGENCY_PREFIX . 'team', $team ); + + wp_redirect( opalestate_get_user_management_page_uri( [ 'tab' => 'agency_team' ] ) ); + die; + } + + } + + /** + * + */ + public static function on_save_post( $post_id ) { + $post_type = get_post_type( $post_id ); + if ( $post_type == 'opalestate_agency' ) { + if ( isset( $_POST[ OPALESTATE_AGENCY_PREFIX . 'user_id' ] ) && $_POST[ OPALESTATE_AGENCY_PREFIX . 'user_id' ] ) { + update_user_meta( $_POST[ OPALESTATE_AGENCY_PREFIX . 'user_id' ], OPALESTATE_USER_PROFILE_PREFIX . 'related_id', $post_id ); + } + } + } + + public static function on_set_role( $user_id ) { + + if ( $user_id ) { + + $args = [ + 'post_type' => 'opalestate_agency', + 'posts_per_page' => 10, + ]; + + + $args['meta_key'] = OPALESTATE_AGENCY_PREFIX . 'user_id'; + $args['meta_value'] = $user_id; + $args['meta_compare'] = '='; + $args['post_status'] = [ 'publish', 'pending' ]; + + $post = get_posts( $args ); + + if ( empty( $post ) ) { + + $agency_id = self::create_agency( [], $user_id ); + update_post_meta( $agency_id, OPALESTATE_AGENCY_PREFIX . 'user_id', $user_id ); + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', $agency_id ); + } + } + } + + /** + * + */ + public static function create_agency( $args = [], $user_id ) { + $data = get_user_by( 'id', $user_id ); + + $args = wp_parse_args( $args, [ + 'first_name' => $data->first_name, + 'last_name' => $data->last_name, + 'avatar' => '', + 'job' => '', + 'email' => '', + 'phone' => '', + 'mobile' => '', + 'fax' => '', + 'web' => '', + 'address' => '', + 'twitter' => '', + 'facebook' => '', + 'google' => '', + 'linkedin' => '', + 'instagram' => '', + ] ); + + + $agency_id = wp_insert_post( [ + 'post_title' => $args['first_name'] && $args['last_name'] ? $args['first_name'] . ' ' . $args['last_name'] : esc_html__( 'User ID', 'opalestate-pro' ) . ': ' . $user_id, + 'post_content' => 'empty description', + 'post_excerpt' => 'empty excerpt', + 'post_type' => 'opalestate_agency', + 'post_status' => 'pending', + 'post_author' => $user_id, + ], true ); + + + do_action( 'opalesate_insert_user_agency', $agency_id ); + + return $agency_id; + } + + /** + * + */ + public function render_front_form( $metaboxes, $post_id = 0 ) { + $metabox = new Opalestate_Agency_MetaBox(); + + return $metabox->render_front_form( $metaboxes, $post_id ); + } +} + +Opalestate_Agency_Front::get_instance(); diff --git a/inc/agency/class-opalestate-agency-metabox.php b/inc/agency/class-opalestate-agency-metabox.php new file mode 100755 index 00000000..27529e44 --- /dev/null +++ b/inc/agency/class-opalestate-agency-metabox.php @@ -0,0 +1,389 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Agency_MetaBox extends Opalestate_User_MetaBox { + + /** + * + */ + public function metaboxes_target() { + + $prefix = OPALESTATE_AGENCY_PREFIX; + $fields = [ + [ + 'id' => "{$prefix}user_id", + 'name' => esc_html__( 'Link To User ID', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Set relationship to existed user, allow user can edit Agency profile in front-end and show account info in each property.', 'opalestate-pro' ), + + ], + [ + 'name' => esc_html__( 'Agent Team', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in location of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "team", + 'type' => 'adduser', + ], + ]; + + return $fields; + } + + /** + * + */ + public function metaboxes_admin_fields( $prefix = '' ) { + + if ( ! $prefix ) { + $prefix = OPALESTATE_AGENCY_PREFIX; + } + + $fields = [ + [ + 'id' => "{$prefix}featured", + 'name' => esc_html__( 'Is Featured', 'opalestate-pro' ), + 'type' => 'switch', + 'description' => esc_html__( 'Set this agent as featured', 'opalestate-pro' ), + 'options' => [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + ], + + ], + ]; + + $fields = array_merge_recursive( $fields, + $this->get_base_fields( $prefix ), + $this->get_address_fields( $prefix ) + ); + + return apply_filters( 'opalestate_postype_agency_metaboxes_fields', $fields ); + } + + /** + * + */ + public function get_front_fields( $prefix ) { + return [ + 'id' => $prefix . 'front', + 'title' => esc_html__( 'Name and Description', 'opalestate-pro' ), + 'object_types' => [ 'opalestate_property' ], + 'context' => 'normal', + 'object_types' => [ 'user' ], // Tells CMB2 to use user_meta vs post_meta + 'priority' => 'high', + 'show_names' => true, + 'fields' => $this->get_fields( $prefix ), + ]; + } + + /** + * + */ + public function get_fields( $prefix ) { + + $management = [ + [ + 'name' => esc_html__( 'Avatar Picture', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar', + 'type' => is_admin() ? 'file' : 'opal_upload', + 'avatar' => true, + 'before_row' => '

            ', + 'after_row' => '
            ', + ], + + [ + 'id' => 'first_name', + 'name' => esc_html__( 'First Name', 'opalestate-pro' ), + 'type' => 'text', + 'attributes' => [ + 'required' => 'required', + ], + 'before_row' => '
            ', + + ], + [ + 'id' => 'last_name', + 'name' => esc_html__( 'Last Name', 'opalestate-pro' ), + 'type' => 'text', + 'attributes' => [ + 'required' => 'required', + ], + ], + + [ + 'id' => 'description', + 'name' => esc_html__( 'Biographical Info', 'opalestate-pro' ), + 'type' => 'textarea', + 'description' => esc_html__( 'Share a little biographical information to fill out your profile. This may be shown publicly.', 'opalestate-pro' ), + + 'after_row' => '
            ', + ], + [ + 'id' => "{$prefix}job", + 'name' => esc_html__( 'Title/Job', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Please enter position or job in your company.', 'opalestate-pro' ), + 'before_row' => '

            ' . __( 'Information', 'opalestate-pro' ) . '

            ', // callback + ], + + [ + 'id' => "{$prefix}company", + 'name' => esc_html__( 'company', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Please enter company name.', 'opalestate-pro' ), + ], + [ + 'id' => "{$prefix}email", + 'name' => esc_html__( 'Contact email', 'opalestate-pro' ), + 'type' => 'text_email', + 'description' => esc_html__( 'Enter contact name that allow user contact you via the contact form of website.', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}phone", + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Enter your home phone.', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}skype", + 'name' => esc_html__( 'Skype', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Input for skype account.', 'opalestate-pro' ), + ], + + [ + 'id' => "url", + 'name' => esc_html__( 'Website URL', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Link to your website', 'opalestate-pro' ), + 'after_row' => '
            ', + ], + + [ + 'id' => "{$prefix}facebook", + 'name' => esc_html__( 'Facebook', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Enter your facebook profile or facebook newfeed', 'opalestate-pro' ), + 'before_row' => '

            ' . __( 'Social', 'opalestate-pro' ) . '

            ', // callback + ], + + [ + 'id' => "{$prefix}linkedin", + 'name' => esc_html__( 'Linkedin URL', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Input for linked in profile.', 'opalestate-pro' ), + ], + [ + 'id' => "{$prefix}instagram", + 'name' => esc_html__( 'Instagram URL', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Input for instagram profile.', 'opalestate-pro' ), + ], + [ + 'id' => "{$prefix}pinterest", + 'name' => esc_html__( 'Pinterest Url', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Input for pinterest feed', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}googleplus", + 'name' => esc_html__( 'Google Plus Url', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Input for goolge plus profile or your newfeed.', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}youtube", + 'name' => esc_html__( 'Youtube Url', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Input for your channel youtube.', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}vimeo", + 'name' => esc_html__( 'Vimeo Url', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Input for your channel Vimeo', 'opalestate-pro' ), + 'after_row' => '
            ', + ], + ]; + + return $management; + } + + /** + * + */ + public function metaboxes_front_fields( $prefix = '', $post_id = 0 ) { + if ( ! $prefix ) { + $prefix = OPALESTATE_AGENCY_PREFIX; + } + $post = get_post( $post_id ); + + $fields = [ + + [ + 'id' => $prefix . 'post_type', + 'type' => 'hidden', + 'default' => 'opalestate_agency', + ], + [ + 'id' => 'post_id', + 'type' => 'hidden', + 'default' => $post_id, + ], + + [ + 'name' => esc_html__( 'Title / Name', 'opalestate-pro' ), + 'id' => $prefix . 'title', + 'type' => 'text', + 'default' => ! empty( $post ) ? $post->post_title : '', + 'attributes' => [ + 'required' => 'required', + ], + ], + [ + 'name' => esc_html__( 'slogan', 'opalestate-pro' ), + 'id' => "{$prefix}slogan", + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Information', 'opalestate-pro' ), + 'id' => $prefix . 'text', + 'type' => 'wysiwyg', + 'default' => ! empty( $post ) ? $post->post_content : '', + 'attributes' => [ + 'required' => 'required', + ], + ], + + [ + 'name' => esc_html__( 'Types', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in location of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "type", + 'taxonomy' => 'opalestate_types', + 'type' => 'taxonomy_select', + + ] + ]; + + + $fields = array_merge_recursive( $fields, + $this->get_base_front_fields( $prefix ), + $this->get_address_fields( $prefix ), + $this->get_social_fields( $prefix ) + ); + + return apply_filters( 'opalestate_postype_office_metaboxes_fields', $fields ); + } + + public function get_base_front_fields( $prefix ) { + return [ + [ + 'id' => "{$prefix}featured_image", + 'name' => esc_html__( 'Banner', 'opalestate-pro' ), + 'type' => 'uploader', + 'is_featured' => true, + 'limit' => 1, + 'single' => 1, + 'description' => esc_html__( 'Select one or more images to show as gallery', 'opalestate-pro' ), + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Avatar Picture', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar', + 'type' => 'hidden', + 'single' => 1, + 'limit' => 1, + 'avatar' => true, + + ], + [ + 'name' => esc_html__( 'Avatar Picture', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar_id', + 'type' => 'uploader', + 'single' => 1, + 'limit' => 1, + 'avatar' => true, + + ], + [ + 'name' => esc_html__( 'Gallery', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in location of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "gallery", + 'type' => 'uploader', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Email', 'opalestate-pro' ), + 'id' => "{$prefix}email", + 'type' => 'text', + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Website', 'opalestate-pro' ), + 'id' => "{$prefix}web", + 'type' => 'text_url', + ], + [ + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'id' => "{$prefix}phone", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Mobile', 'opalestate-pro' ), + 'id' => "{$prefix}mobile", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Fax', 'opalestate-pro' ), + 'id' => "{$prefix}fax", + 'type' => 'text', + 'after_row' => '
            ', + ], + ]; + } + + /** + * + */ + public function render_front_form( $metaboxes, $post_id = 0 ) { + + $prefix = OPALESTATE_AGENCY_PREFIX; + + $metaboxes[ $prefix . 'front' ] = [ + 'id' => $prefix . 'front', + 'title' => esc_html__( 'Agency Information', 'opalestate-pro' ), + 'object_types' => [ 'opalestate_agency' ], + 'context' => 'normal', + 'priority' => 'high', + 'show_names' => true, + 'cmb_styles' => false, + 'fields' => $this->metaboxes_front_fields( $prefix, $post_id ), + ]; + + return $metaboxes; + } +} diff --git a/inc/agency/class-opalestate-agency-posttype.php b/inc/agency/class-opalestate-agency-posttype.php new file mode 100755 index 00000000..8059b2f9 --- /dev/null +++ b/inc/agency/class-opalestate-agency-posttype.php @@ -0,0 +1,103 @@ + + * @copyright Copyright (C) 2016 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * Class Opalestate_PostType_Agency + * + * @version 1.0 + */ +class Opalestate_PostType_Agency { + + /** + * Init + */ + public static function init() { + add_action( 'init', [ __CLASS__, 'definition' ] ); + } + + + /** + * Register Post type and taxonomies + */ + public static function definition() { + if ( ! is_blog_installed() || post_type_exists( 'opalestate_agency' ) ) { + return; + } + + $labels = [ + 'name' => esc_html__( 'Agencies', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Property', 'opalestate-pro' ), + 'add_new' => esc_html__( 'Add New Agency', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Agency', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Agency', 'opalestate-pro' ), + 'new_item' => esc_html__( 'New Agency', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Agencies', 'opalestate-pro' ), + 'view_item' => esc_html__( 'View Agency', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Agency', 'opalestate-pro' ), + 'not_found' => esc_html__( 'No Agencies found', 'opalestate-pro' ), + 'not_found_in_trash' => esc_html__( 'No Agencies found in Trash', 'opalestate-pro' ), + 'parent_item_colon' => '', + 'menu_name' => esc_html__( 'Agencies', 'opalestate-pro' ), + ]; + + $labels = apply_filters( 'opalestate_postype_agency_labels', $labels ); + + register_post_type( 'opalestate_agency', + apply_filters( 'opalestate_agency_post_type_parameters', [ + 'labels' => $labels, + 'supports' => [ 'title', 'editor', 'thumbnail', 'comments', 'author', 'excerpt' ], + 'public' => true, + 'has_archive' => true, + 'menu_position' => 51, + 'categories' => [], + 'menu_icon' => 'dashicons-groups', + 'rewrite' => [ 'slug' => esc_html_x( 'agency', 'agency slug', 'opalestate-pro' ) ], + ] ) + ); + + /// + $labels = [ + 'name' => esc_html__( 'Agency Categories', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Category', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Category', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Categories', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Category', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Category:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Category', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Category', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Category', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Category Name', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Agency Categories', 'opalestate-pro' ), + ]; + /// + register_taxonomy( 'opalestate_agency_cat', [ 'opalestate_agency' ], + [ + 'hierarchical' => true, + 'labels' => $labels, + 'show_ui' => true, + 'show_admin_column' => true, + 'query_var' => true, + 'show_in_nav_menus' => true, + 'rewrite' => [ + 'slug' => esc_html_x( 'agency-category', 'agency category slug', 'opalestate-pro' ), + ], + ] ); + } +} + +Opalestate_PostType_Agency::init(); diff --git a/inc/agency/class-opalestate-agency-query.php b/inc/agency/class-opalestate-agency-query.php new file mode 100755 index 00000000..65268752 --- /dev/null +++ b/inc/agency/class-opalestate-agency-query.php @@ -0,0 +1,20 @@ + + * @copyright Copyright (C) 2014 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +// Exit if accessed directly +if ( !defined( 'ABSPATH' ) ) exit; + +class Opalestate_Agency_Query extends OpalEstate_Abstract_Query { + +} \ No newline at end of file diff --git a/inc/agency/class-opalestate-agency.php b/inc/agency/class-opalestate-agency.php new file mode 100755 index 00000000..db25e1f0 --- /dev/null +++ b/inc/agency/class-opalestate-agency.php @@ -0,0 +1,306 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Agency + * + * @version 1.0 + */ +class OpalEstate_Agency { + + /** + * @var String $author_name + * + * @access protected + */ + protected $author_name; + + /** + * @var Boolean $is_featured + * + * @access protected + */ + protected $is_featured; + + /** + * Get A Instance Of Opalestate_Property + */ + public static function get_instance( $post_id = null ) { + static $_instance; + if ( ! $_instance ) { + $_instance = new OpalEstate_Agency( $post_id ); + } + + return $_instance; + } + + + /** + * Constructor + */ + public function __construct( $post_id = null ) { + + global $post; + + $this->post = $post; + $this->post_id = $post_id ? $post_id : get_the_ID(); + $this->author = get_userdata( $post->post_author ); + $this->author_name = ! empty( $this->author ) ? sprintf( '%s %s', $this->author->first_name, $this->author->last_name ) : null; + $this->is_featured = $this->get_meta( 'featured' ); + $this->is_trusted = $this->get_meta( 'trusted' ); + } + + public function get_id() { + return $this->post_id; + } + + /** + * Get Collection Of soicals with theirs values + */ + public function get_socials() { + $socials = [ + 'facebook' => '', + 'twitter' => '', + 'pinterest' => '', + 'google' => '', + 'instagram' => '', + 'linkedIn' => '', + ]; + + $output = []; + + foreach ( $socials as $social => $k ) { + + $data = $this->get_meta( $social ); + if ( $data && $data != "#" && ! empty( $data ) ) { + $output[ $social ] = $data; + } + } + + return $output; + } + + /** + * Get url of user avatar by agency id + */ + public static function get_avatar_url( $userID ) { + + return get_post_meta( $userID, OPALESTATE_AGENCY_PREFIX . "avatar", true ); + + } + + /** + * Render list of levels of agency + */ + public function render_level() { + $levels = wp_get_post_terms( $this->post_id, 'opalestate_agency_cat' ); + + if ( empty( $levels ) ) { + return; + } + + $output = ''; + foreach ( $levels as $key => $value ) { + $output .= '' . $value->name . ''; + } + $output .= ''; + + echo $output; + } + + /** + * get meta data value of key without prefix + */ + public function get_meta( $key ) { + return get_post_meta( $this->get_id(), OPALESTATE_AGENCY_PREFIX . $key, true ); + } + + + /** + * return true if this agency is featured + */ + public function is_featured() { + return $this->is_featured; + } + + + public function render_avatar() { + + } + + /** + * render block information by id + */ + public static function render_box_info( $post_id ) { + + } + + + public function get_gallery() { + return $this->get_meta( 'gallery' ); + } + + + public function get_trusted() { + return $this->is_trusted; + } + + public function get_members() { + $team = []; + $ids = get_post_meta( $this->post_id, OPALESTATE_AGENCY_PREFIX . 'team', true ); + + foreach ( $ids as $id ) { + $user = get_user_by( 'id', $id ); // echo '
            ' . print_r( $user, 1 );die;
            +			$team[] = [
            +				'id'          => $user->ID,
            +				'name'        => $user->display_name,
            +				'avatar_url'  => OpalEstate_User::get_author_picture( $user->ID ),
            +				'username'    => $user->user_login,
            +				'description' => 'okokok',
            +			];
            +		}
            +
            +		return $team;
            +	}
            +
            +	public static function get_link( $agency_id ) {
            +		$agency = get_post( $agency_id );
            +		$url    = self::get_avatar_url( $agency_id );
            +
            +		return [
            +			'name'   => $agency->post_title,
            +			'avatar' => $url,
            +			'link'   => get_permalink( $agency->ID ),
            +		];
            +	}
            +
            +	public static function metaboxes_fields() {
            +		$metabox = new Opalestate_Agency_MetaBox();
            +		$fields  = $metabox->metaboxes_admin_fields();
            +
            +		return array_merge_recursive( $fields, $metabox->get_social_fields( OPALESTATE_AGENCY_PREFIX ) );
            +	}
            +
            +	/**
            +	 * Get rating count.
            +	 *
            +	 * @param string $context What the value is for. Valid values are view and edit.
            +	 * @return int
            +	 */
            +	public function get_rating_counts() {
            +		return $this->get_meta( 'rating_count' ) ? $this->get_meta( 'rating_count' ) : 0;
            +	}
            +
            +	/**
            +	 * Get average rating.
            +	 *
            +	 * @param string $context What the value is for. Valid values are view and edit.
            +	 * @return float
            +	 */
            +	public function get_average_rating() {
            +		return $this->get_meta( 'average_rating' ) ? $this->get_meta( 'average_rating' ) : 0;
            +	}
            +
            +	/**
            +	 * Get review count.
            +	 *
            +	 * @param string $context What the value is for. Valid values are view and edit.
            +	 * @return int
            +	 */
            +	public function get_review_count() {
            +		return $this->get_meta( 'review_count' ) ? $this->get_meta( 'review_count' ) : 0;
            +	}
            +
            +	public function get_rating_count_stats() {
            +		return $this->get_meta( 'rating_count_stats' ) ? $this->get_meta( 'rating_count_stats' ) : [
            +			5 => 0,
            +			4 => 0,
            +			3 => 0,
            +			2 => 0,
            +			1 => 0,
            +		];
            +	}
            +
            +	public function get_rating_average_stats() {
            +		return $this->get_meta( 'rating_average_stats' );
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public static function update_user_data( $user_id ) {
            +
            +		$fields = self::metaboxes_fields();
            +
            +		$others = [
            +			'avatar_id' => '',
            +			'map'       => '',
            +		];
            +
            +		foreach ( $fields as $key => $field ) {
            +			$kpos = $field['id'];
            +			$tmp  = str_replace( OPALESTATE_AGENCY_PREFIX, "", $field['id'] );
            +			if ( isset( $_POST[ $kpos ] ) && $tmp ) {
            +				$data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ];
            +				update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . $tmp, $data );
            +			}
            +		}
            +
            +		// update for others 
            +		foreach ( $others as $key => $value ) {
            +			$kpos = OPALESTATE_AGENCY_PREFIX . $key;
            +			if ( isset( $_POST[ $kpos ] ) ) {
            +				$data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ];
            +				update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . $key, $data );
            +			}
            +		}
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public static function update_data_from_user( $related_id ) {
            +
            +
            +		$fields = self::metaboxes_fields();
            +
            +		$others = [
            +			'avatar_id' => '',
            +			'map'       => '',
            +		];
            +		foreach ( $fields as $key => $field ) {
            +
            +			$tmp  = str_replace( OPALESTATE_AGENCY_PREFIX, "", $field['id'] );
            +			$kpos = OPALESTATE_USER_PROFILE_PREFIX . $tmp;
            +
            +			if ( isset( $_POST[ $kpos ] ) && $tmp ) {
            +				$data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ];
            +				update_post_meta( $related_id, OPALESTATE_AGENCY_PREFIX . $tmp, $data );
            +			}
            +		}
            +
            +		// update for others 
            +		foreach ( $others as $key => $value ) {
            +			$kpos = OPALESTATE_USER_PROFILE_PREFIX . $key;
            +			if ( isset( $_POST[ $kpos ] ) ) {
            +				$data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ];
            +				update_post_meta( $related_id, OPALESTATE_AGENCY_PREFIX . $key, $data );
            +			}
            +		}
            +	}
            +}
            diff --git a/inc/agency/functions.php b/inc/agency/functions.php
            new file mode 100755
            index 00000000..e69de29b
            diff --git a/inc/agent/class-opalestate-agent-front.php b/inc/agent/class-opalestate-agent-front.php
            new file mode 100755
            index 00000000..d26f5b75
            --- /dev/null
            +++ b/inc/agent/class-opalestate-agent-front.php
            @@ -0,0 +1,508 @@
            +
            + * @copyright  Copyright (C) 2014 wpopal.com. All Rights Reserved.
            + */
            +
            +// Exit if accessed directly
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit;
            +}
            +
            +class Opalestate_Agent_Front {
            +
            +	/**
            +	 * Instance.
            +	 *
            +	 * @access private
            +	 * @var Opalestate_Agent_Front
            +	 */
            +	static private $instance;
            +
            +	/**
            +	 * Singleton pattern.
            +	 *
            +	 * @since  $Id
            +	 * @access private
            +	 */
            +	private function __construct() {
            +	}
            +
            +	public $new_attachmenet_ids;
            +
            +	/**
            +	 * Get instance.
            +	 *
            +	 * @access public
            +	 * @return Opalestate_Agent_Front
            +	 */
            +	public static function get_instance() {
            +		if ( null === static::$instance ) {
            +			self::$instance = new static();
            +
            +			self::$instance->init();
            +		}
            +
            +		return self::$instance;
            +	}
            +
            +	/**
            +	 * Auto update meta information to post from user data updated or created
            +	 */
            +	public function init() {
            +
            +		add_action( 'opalestate_on_set_role_agent', [ $this, 'on_set_role' ], 1, 9 );
            +		add_filter( 'opalestate_before_render_profile_agent_form', [ $this, 'render_front_form' ], 2, 2 );
            +		add_filter( 'pre_get_posts', [ $this, 'archives_query' ], 1 );
            +		add_action( 'cmb2_after_init', [ $this, 'on_save_front_data' ] );
            +
            +		add_action( 'opalestate_user_content_agent_profile_page', [ $this, 'render_profile' ] );
            +		add_filter( 'opalestate_management_user_menu', [ $this, 'render_extra_profile_link' ] );
            +
            +		$this->register_shortcodes();
            +	}
            +
            +
            +	/**
            +	 * render_extra_profile_link.
            +	 */
            +	public function render_extra_profile_link( $menu ) {
            +		global $current_user;
            +
            +		$user_roles = $current_user->roles;
            +		$user_role  = array_shift( $user_roles );
            +
            +		if ( $user_role == 'opalestate_agent' ) {
            +			$menu['extra_profile'] = [
            +				'icon'  => 'fa fa-user',
            +				'link'  => "agent_profile",
            +				'title' => esc_html__( 'Agent Profile', 'opalestate-pro' ),
            +				'id'    => 0,
            +			];
            +		}
            +
            +		return $menu;
            +	}
            +
            +	/**
            +	 * render_profile
            +	 */
            +	public function render_profile() {
            +
            +		$user_id = get_current_user_id();
            +		$post_id = get_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', true );
            +
            +		$post = get_post( $post_id );
            +
            +		if ( isset( $post->ID ) && $post->post_status != 'publish' ) {
            +			opalestate_add_notice( "warning", esc_html__( 'You account is under reviewing! it take some time to process' ) );
            +			add_action( "opalestate_profile_agency_form_before", "opalestate_print_notices" );
            +		}
            +
            +		$metaboxes = $this->render_front_form( [], $post_id );
            +
            +		return opalestate_load_template_path( 'user/agent/profile-agent', [ 'metaboxes' => $metaboxes, 'post_id' => $post_id ] );
            +	}
            +
            +	/**
            +	 * Process upload images for properties
            +	 */
            +	public function upload_image( $submitted_file, $parent_id = 0 ) {
            +		return opalesate_upload_image( $submitted_file, $parent_id );
            +	}
            +
            +	/**
            +	 * Remove dirty images of current user
            +	 */
            +	public function remove_dirty_images( $post_id, $user_id ) {
            +
            +		if ( isset( $_POST['remove_image_id'] ) && is_array( $_POST['remove_image_id'] ) && $_POST['remove_image_id'] ) {
            +			foreach ( $_POST['remove_image_id'] as $key => $value ) {
            +				$post = get_post( $value );
            +				if ( $post->post_author == $user_id ) {
            +					wp_delete_attachment( $value );
            +				}
            +			}
            +		}
            +	}
            +
            +	private function process_upload_files( $post_id ) {
            +
            +		//upload images for featured and gallery images
            +		if ( isset( $_FILES ) && ! empty( $_FILES ) ) {
            +
            +			/// 
            +			$fields = [
            +				$this->get_field_name( 'gallery' ),
            +				$this->get_field_name( 'avatar_id' ),
            +				$this->get_field_name( 'featured_image' ),
            +			];
            +
            +			foreach ( $_FILES as $key => $value ) {
            +				// allow processing in fixed collection
            +				if ( in_array( $key, $fields ) ) {
            +					$ufile = $_FILES[ $key ];
            +
            +					/// /////
            +					if ( isset( $ufile['name'] ) && is_array( $ufile['name'] ) ) {
            +						$output = [];
            +
            +						foreach ( $ufile['name'] as $f_key => $f_value ) {
            +							$loop_file = [
            +								'name'     => $ufile['name'][ $f_key ],
            +								'type'     => $ufile['type'][ $f_key ],
            +								'tmp_name' => $ufile['tmp_name'][ $f_key ],
            +								'error'    => $ufile['error'][ $f_key ],
            +								'size'     => $ufile['size'][ $f_key ],
            +							];
            +							$new_atm   = $this->upload_image( $loop_file, $post_id );
            +							if ( $new_atm ) {
            +								$_POST[ $key ]                                          = isset( $_POST[ $key ] ) ? sanitize_text_field( $_POST[ $key ] ) : [];
            +								$_POST[ $key ][ $new_atm['attachment_id'] ]             = $new_atm['url'];
            +								$this->new_attachmenet_ids[ $new_atm['attachment_id'] ] = $new_atm['attachment_id'];
            +							}
            +						}
            +
            +					} ///
            +					elseif ( isset( $ufile['name'] ) ) {
            +						$new_atm = $this->upload_image( $ufile, $post_id );
            +						if ( $new_atm ) {
            +							$_POST[ $key ] = $new_atm['attachment_id'];
            +
            +							if ( preg_match( "#id#", $key ) ) {
            +								$_key           = str_replace( "_id", "", $key );
            +								$_POST[ $_key ] = $new_atm['url'];
            +							}
            +							$this->new_attachmenet_ids[ $new_atm['attachment_id'] ] = $new_atm['attachment_id'];
            +						}
            +					}
            +				}
            +			}
            +		}
            +
            +
            +	}
            +
            +	public function on_save_front_data() {
            +
            +		if ( isset( $_POST[ 'nonce_CMB2php' . OPALESTATE_AGENT_PREFIX . 'front' ] ) ) {
            +
            +			$post_id = $this->update_data_agent_or_agency( OPALESTATE_AGENT_PREFIX );
            +
            +			if ( $post_id ) {
            +				OpalEstate_Agent::update_user_data( get_current_user_id() );
            +			}
            +
            +			return opalestate_output_msg_json( true,
            +				__( 'The data updated successful, please wait for redirecting', 'opalestate-pro' ),
            +				[
            +					'heading'  => esc_html__( 'Update Information', 'opalestate-pro' ),
            +					'redirect' => opalestate_get_user_management_page_uri( [ 'tab' => 'agent_profile' ] ),
            +				]
            +			);
            +
            +
            +			return opalestate_output_msg_json( fales,
            +				__( 'Currently, The data could not save!', 'opalestate-pro' ),
            +				[ 'heading' => esc_html__( 'Update Information', 'opalestate-pro' ) ]
            +			);
            +
            +			exit;
            +		}
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	private function get_field_name( $field ) {
            +		return OPALESTATE_AGENT_PREFIX . $field;
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	private function update_data_agent_or_agency( $prefix ) {
            +		global $current_user;
            +
            +		$post_id   = isset( $_POST['object_id'] ) && absint( $_POST['object_id'] ) ? $_POST['object_id'] : 0;
            +		$user_id   = get_current_user_id();
            +		$metaboxes = apply_filters( 'opalestate_before_render_profile_agent_form', [], $post_id );
            +		$metaboxes = apply_filters( 'cmb2_meta_boxes', $metaboxes );
            +
            +		if ( isset( $metaboxes[ $prefix . 'front' ] ) ) {
            +			if ( ! empty( $post_id ) ) {
            +				$old_post  = get_post( $post_id );
            +				$post_date = $old_post->post_date;
            +			} else {
            +				$post_date = '';
            +			}
            +			$post = get_post( $post_id );
            +
            +			$data = [
            +				'ID'           => $post->ID ? $post_id : null,
            +				'post_title'   => sanitize_text_field( $_POST[ $prefix . 'title' ] ),
            +				'post_author'  => $user_id,
            +				'post_type'    => 'opalestate_agent',
            +				'post_date'    => $post_date,
            +				'post_content' => wp_kses( $_POST[ $prefix . 'text' ], '

            ' ), + ]; + + + unset( $_POST[ $prefix . 'title' ] ); + unset( $_POST[ $prefix . 'text' ] ); + + + if ( $data['ID'] > 0 ) { + $post_id = wp_update_post( $data, true ); + } else { + $data['post_status'] = 'pending'; + $post_id = wp_insert_post( $data, true ); + } + + $post = get_post( $post_id ); + + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', $post_id ); + + /* + * Processing upload files + */ + $this->process_upload_files( $post_id, $_POST ); + + cmb2_get_metabox_form( $metaboxes[ $prefix . 'front' ], $post_id ); + $cmb = cmb2_get_metabox( $prefix . 'front', $post_id ); + $sanitized_values = $cmb->get_sanitized_values( $_POST ); + $cmb->save_fields( $post_id, 'post', $sanitized_values ); + /// update + // Create featured image + $featured_image = get_post_meta( $post_id, $prefix . 'featured_image', true ); + + if ( ! empty( $_POST[ $prefix . 'featured_image' ] ) && isset( $_POST[ $prefix . 'featured_image' ] ) ) { + + set_post_thumbnail( $post_id, $_POST[ $prefix . 'featured_image' ] ); + unset( $_POST[ $prefix . 'featured_image' ] ); + } else { + delete_post_thumbnail( $post_id ); + } + + // remove dirty images + $this->remove_dirty_images( $post_id, $user_id ); + // set ready of attachment for use. + if ( $this->new_attachmenet_ids ) { + foreach ( $this->new_attachmenet_ids as $_id ) { + delete_post_meta( $_id, '_pending_to_use_', 1 ); + } + } + + return $post_id; + } + + return false; + } + + public function register_shortcodes() { + + $this->shortcodes = [ + + 'change_agent_profile' => [ 'code' => 'change_agent_profile', 'label' => esc_html__( 'Agent Profile', 'opalestate-pro' ) ], + 'search_agents' => [ 'code' => 'search_agents', 'label' => esc_html__( 'Search Agents', 'opalestate-pro' ) ], + ]; + + foreach ( $this->shortcodes as $shortcode ) { + add_shortcode( 'opalestate_' . $shortcode['code'], [ $this, $shortcode['code'] ] ); + } + + } + + public function archives_query( $query ) { + + if ( $query->is_main_query() && is_post_type_archive( 'opalestate_agent' ) ) { + + $args = []; + + $min = opalestate_options( 'search_agent_min_price', 0 ); + $max = opalestate_options( 'search_agent_max_price', 10000000 ); + + + $search_min_price = isset( $_GET['min_price'] ) ? sanitize_text_field( $_GET['min_price'] ) : ''; + $search_max_price = isset( $_GET['max_price'] ) ? sanitize_text_field( $_GET['max_price'] ) : ''; + + $search_min_area = isset( $_GET['min_area'] ) ? sanitize_text_field( $_GET['min_area'] ) : ''; + $search_max_area = isset( $_GET['max_area'] ) ? sanitize_text_field( $_GET['max_area'] ) : ''; + $s = isset( $_GET['search_text'] ) ? sanitize_text_field( $_GET['search_text'] ) : null; + + + $paged = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' ); + $default = [ + 'post_type' => 'opalestate_agent', + 'posts_per_page' => apply_filters( 'opalestate_agent_per_page', 12 ), + 'paged' => $paged, + ]; + $args = array_merge( $default, $args ); + + $tax_query = []; + + + if ( isset( $_GET['location'] ) && $_GET['location'] != -1 ) { + $tax_query[] = + [ + 'taxonomy' => 'opalestate_location', + 'field' => 'slug', + 'terms' => sanitize_text_field( $_GET['location'] ), + ]; + } + + if ( isset( $_GET['types'] ) && $_GET['types'] != -1 ) { + $tax_query[] = + [ + 'taxonomy' => 'opalestate_types', + 'field' => 'slug', + 'terms' => sanitize_text_field( $_GET['types'] ), + ]; + } + + if ( $tax_query ) { + $args['tax_query'] = [ 'relation' => 'AND' ]; + $args['tax_query'] = array_merge( $args['tax_query'], $tax_query ); + } + + $args['meta_query'] = [ 'relation' => 'AND' ]; + + if ( $search_min_price != $min && is_numeric( $search_min_price ) ) { + array_push( $args['meta_query'], [ + 'key' => OPALESTATE_AGENT_PREFIX . 'target_min_price', + 'value' => $search_min_price, + 'compare' => '>=', + 'type' => 'NUMERIC', + ] ); + } + if ( is_numeric( $search_max_price ) && $search_max_price != $max ) { + array_push( $args['meta_query'], [ + 'key' => OPALESTATE_AGENT_PREFIX . 'target_max_price', + 'value' => $search_max_price, + 'compare' => '<=', + 'type' => 'NUMERIC', + ] ); + } + + + ///// search by address and geo location /// + if ( isset( $_GET['geo_long'] ) && isset( $_GET['geo_lat'] ) ) { + + $prefix = OPALESTATE_AGENT_PREFIX; + if ( $_GET['location_text'] && ( empty( $_GET['geo_long'] ) || empty( $_GET['geo_lat'] ) ) ) { + array_push( $args['meta_query'], [ + 'key' => $prefix . 'map_address', + 'value' => sanitize_text_field( trim( $_GET['location_text'] ) ), + 'compare' => 'LIKE', + 'operator' => 'OR', + ] ); + + } else { + $radius = isset( $_GET['geo_radius'] ) ? sanitize_text_field( $_GET['geo_radius'] ) : 5; + $post_ids = Opalestate_Query::filter_by_location( + sanitize_text_field( $_GET['geo_lat'] ), + sanitize_text_field( $_GET['geo_long'] ), $radius, $prefix ); + + + $args['post__in'] = $post_ids; + $query->set( 'post__in', $post_ids ); + } + } + + if ( isset( $args['tax_query'] ) && $args['tax_query'] ) { + $query->set( 'tax_query', $args['tax_query'] ); + } + if ( isset( $args['meta_query'] ) && $args['meta_query'] ) { + $query->set( 'meta_query', $args['meta_query'] ); + } + } + + return $query; + } + + + /** + * + */ + public function search_agents() { + return opalestate_load_template_path( 'shortcodes/search-agents' ); + } + + /** + * Auto update meta information to post from user data updated or created + */ + public function on_set_role( $user_id ) { + if ( $user_id ) { + + $args = [ + 'post_type' => 'opalestate_agent', + 'posts_per_page' => 10, + ]; + + + $args['meta_key'] = OPALESTATE_AGENT_PREFIX . 'user_id'; + $args['meta_value'] = $user_id; + $args['meta_compare'] = '='; + $args['post_status'] = [ 'publish', 'pending' ]; + + $post = get_posts( $args ); + + if ( empty( $post ) ) { + $agent_id = $this->create_agent( [], $user_id ); + update_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'user_id', $user_id ); + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', $agent_id ); + } + } + } + + public function create_agent( $args = [], $user_id ) { + + $data = get_user_by( 'id', $user_id ); + + $args = wp_parse_args( $args, [ + 'first_name' => $data->first_name, + 'last_name' => $data->last_name, + 'post_author' => $user_id, + 'avatar' => '', + 'job' => '', + 'email' => '', + 'phone' => '', + 'mobile' => '', + 'fax' => '', + 'web' => '', + 'address' => '', + 'twitter' => '', + 'facebook' => '', + 'google' => '', + 'linkedin' => '', + 'instagram' => '', + ] ); + + $agent_id = wp_insert_post( [ + 'post_title' => $args['first_name'] && $args['last_name'] ? $args['first_name'] . ' ' . $args['last_name'] : esc_html__( 'User ID', 'opalestate-pro' ) . ': ' . $user_id, + 'post_content' => '', + 'post_excerpt' => '', + 'post_type' => 'opalestate_agent', + 'post_status' => 'pending', + 'post_author' => $user_id, + ], true ); + + + do_action( 'opalesate_insert_user_agent', $agent_id ); + + return $agent_id; + } + + /** + * + */ + public function render_front_form( $metaboxes, $post_id = 0 ) { + $metabox = new Opalestate_Agent_MetaBox(); + + return $metabox->render_front_form( $metaboxes, $post_id ); + } +} + +Opalestate_Agent_Front::get_instance(); diff --git a/inc/agent/class-opalestate-agent-metabox.php b/inc/agent/class-opalestate-agent-metabox.php new file mode 100755 index 00000000..c8ce1b37 --- /dev/null +++ b/inc/agent/class-opalestate-agent-metabox.php @@ -0,0 +1,225 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Agent_MetaBox extends Opalestate_User_MetaBox { + + /** + * + */ + public function metaboxes_admin_fields( $prefix = '' ) { + if ( ! $prefix ) { + $prefix = OPALESTATE_AGENT_PREFIX; + } + + $fields = []; + + $fields = array_merge_recursive( $fields, + $this->get_base_fields( $prefix ), + $this->get_job_fields( $prefix ), + $this->get_address_fields( $prefix ) + ); + + return apply_filters( 'opalestate_postype_agent_metaboxes_fields', $fields ); + } + + public function metaboxes_target() { + + $prefix = OPALESTATE_AGENT_PREFIX; + $fields = [ + [ + 'id' => "{$prefix}user_id", + 'name' => esc_html__( 'Link to User', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Enter User ID to show information without using user info', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}target_min_price", + 'name' => esc_html__( 'Target Min Price', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Enter min price of property which is for sale/rent...', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}target_max_price", + 'name' => esc_html__( 'Target Max Price', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Enter max price of property which is for sale/rent...', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Types', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in location of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "type", + 'taxonomy' => 'opalestate_types', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + ], + ]; + + return $fields; + } + + /** + * + */ + public function metaboxes_front_fields( $prefix = '', $post_id = 0 ) { + if ( ! $prefix ) { + $prefix = OPALESTATE_AGENT_PREFIX; + } + $post = get_post( $post_id ); + + $fields = [ + [ + 'id' => $prefix . 'post_type', + 'type' => 'hidden', + 'default' => 'opalestate_agent', + ], + [ + 'name' => esc_html__( 'Title/Name', 'opalestate-pro' ), + 'id' => $prefix . 'title', + 'type' => 'text', + 'default' => ! empty( $post ) ? $post->post_title : '', + 'attributes' => [ + 'required' => 'required', + ], + ], + [ + 'name' => esc_html__( 'Information', 'opalestate-pro' ), + 'id' => $prefix . 'text', + 'type' => 'wysiwyg', + 'default' => ! empty( $post ) ? $post->post_content : '', + 'attributes' => [ + 'required' => 'required', + ], + ], + + [ + 'name' => esc_html__( 'Types', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in location of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "type", + 'taxonomy' => 'opalestate_types', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + + ], + [ + 'id' => "{$prefix}target_min_price", + 'name' => esc_html__( 'Target Min Price', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Enter min price of property which is for sale/rent...', 'opalestate-pro' ), + ], + + [ + 'id' => "{$prefix}target_max_price", + 'name' => esc_html__( 'Target Max Price', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Enter max price of property which is for sale/rent...', 'opalestate-pro' ), + 'after_row' => '', + ], + ]; + + + $fields = array_merge_recursive( $fields, + $this->get_base_front_fields( $prefix ), + $this->get_address_fields( $prefix ), + $this->get_social_fields( $prefix ) + ); + + return apply_filters( 'opalestate_postype_agent_metaboxes_fields', $fields ); + } + + + public function get_base_front_fields( $prefix ) { + return [ + [ + 'id' => "{$prefix}featured_image", + 'name' => esc_html__( 'Banner', 'opalestate-pro' ), + 'type' => 'uploader', + 'is_featured' => true, + 'limit' => 1, + 'single' => 1, + 'description' => esc_html__( 'Select one or more images to show as gallery', 'opalestate-pro' ), + 'before_row' => '


            ', + ], + [ + 'name' => esc_html__( 'Avatar Picture', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar', + 'type' => 'hidden', + 'single' => 1, + 'limit' => 1, + + ], + + [ + 'name' => esc_html__( 'Avatar Picture', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar_id', + 'type' => 'uploader', + 'single' => 1, + 'limit' => 1, + + ], + + [ + 'name' => esc_html__( 'Email', 'opalestate-pro' ), + 'id' => "{$prefix}email", + 'type' => 'text', + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Website', 'opalestate-pro' ), + 'id' => "{$prefix}web", + 'type' => 'text_url', + ], + [ + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'id' => "{$prefix}phone", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Mobile', 'opalestate-pro' ), + 'id' => "{$prefix}mobile", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Fax', 'opalestate-pro' ), + 'id' => "{$prefix}fax", + 'type' => 'text', + 'after_row' => '
            ', + ], + ]; + } + + /** + * + */ + public function render_front_form( $metaboxes, $post_id = 0 ) { + $prefix = OPALESTATE_AGENT_PREFIX; + $metaboxes[ $prefix . 'front' ] = [ + 'id' => $prefix . 'front', + 'title' => esc_html__( 'Agent Information', 'opalestate-pro' ), + 'object_types' => [ 'opalestate_agent' ], + 'context' => 'normal', + 'priority' => 'high', + 'show_names' => true, + 'fields' => $this->metaboxes_front_fields( $prefix, $post_id ), + ]; + + return $metaboxes; + } +} diff --git a/inc/agent/class-opalestate-agent-posttype.php b/inc/agent/class-opalestate-agent-posttype.php new file mode 100755 index 00000000..e1ca4cfb --- /dev/null +++ b/inc/agent/class-opalestate-agent-posttype.php @@ -0,0 +1,103 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_PostType_Agent { + + /** + * Opalestate_PostType_Agent constructor. + */ + public function __construct() { + add_action( 'init', [ __CLASS__, 'definition' ] ); + } + + /** + * Register Post type and taxonomies + */ + public static function definition() { + if ( ! is_blog_installed() || post_type_exists( 'opalestate_agent' ) ) { + return; + } + + $labels = [ + 'name' => esc_html__( 'Agents', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Property', 'opalestate-pro' ), + 'add_new' => esc_html__( 'Add New Agent', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Agent', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Agent', 'opalestate-pro' ), + 'new_item' => esc_html__( 'New Agent', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Agents', 'opalestate-pro' ), + 'view_item' => esc_html__( 'View Agent', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Agent', 'opalestate-pro' ), + 'not_found' => esc_html__( 'No Agents found', 'opalestate-pro' ), + 'not_found_in_trash' => esc_html__( 'No Agents found in Trash', 'opalestate-pro' ), + 'parent_item_colon' => '', + 'menu_name' => esc_html__( 'Agents', 'opalestate-pro' ), + ]; + + $labels = apply_filters( 'opalestate_postype_agent_labels', $labels ); + + register_post_type( 'opalestate_agent', + apply_filters( 'opalestate_agent_post_type_parameters', [ + 'labels' => $labels, + 'supports' => [ 'title', 'editor', 'thumbnail', 'comments', 'author', 'excerpt' ], + 'public' => true, + 'has_archive' => true, + 'menu_position' => 51, + 'categories' => [], + 'menu_icon' => 'dashicons-groups', + 'rewrite' => [ 'slug' => esc_html_x( 'agent', 'agent slug', 'opalestate-pro' ) ], + ] ) + ); + + static::register_taxonomies(); + } + + /** + * Register Agency Agency Taxonomy + */ + private static function register_taxonomies() { + /// Register Agent Levels + $labels = [ + 'name' => esc_html__( 'Agent Levels', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Level', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Level', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Levels', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Level', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Level:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Level', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Level', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Level', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Level Name', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Agent Levels', 'opalestate-pro' ), + ]; + /// + register_taxonomy( 'opalestate_agent_level', [ 'opalestate_agent' ], + [ + 'hierarchical' => true, + 'labels' => $labels, + 'show_ui' => true, + 'show_admin_column' => true, + 'query_var' => true, + 'show_in_nav_menus' => true, + 'rewrite' => [ + 'slug' => esc_html_x( 'agent-level', 'agent level slug', 'opalestate-pro' ), + ], + ] ); + } +} + +new Opalestate_PostType_Agent(); diff --git a/inc/agent/class-opalestate-agent-query.php b/inc/agent/class-opalestate-agent-query.php new file mode 100755 index 00000000..0258be50 --- /dev/null +++ b/inc/agent/class-opalestate-agent-query.php @@ -0,0 +1,20 @@ + + * @copyright Copyright (C) 2014 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +// Exit if accessed directly +if ( !defined( 'ABSPATH' ) ) exit; + +class Opalestate_Agent_Query extends OpalEstate_Abstract_Query { + +} \ No newline at end of file diff --git a/inc/agent/class-opalestate-agent.php b/inc/agent/class-opalestate-agent.php new file mode 100755 index 00000000..14c1bcbd --- /dev/null +++ b/inc/agent/class-opalestate-agent.php @@ -0,0 +1,277 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Agent + * + * @version 1.0 + */ +class OpalEstate_Agent { + + /** + * @var String $author_name + * + * @access protected + */ + protected $author_name; + + /** + * @var Boolean $is_featured + * + * @access protected + */ + protected $is_featured; + + /** + * Constructor + */ + public function __construct( $post_id = null ) { + + global $post; + + if ( $post ) { + $this->post = $post; + $this->post_id = $post_id ? $post_id : get_the_ID(); + $this->author = get_userdata( $post->post_author ); + $this->author_name = ! empty( $this->author ) ? sprintf( '%s %s', $this->author->first_name, $this->author->last_name ) : null; + $this->is_featured = $this->get_meta( 'featured' ); + $this->is_trusted = $this->get_meta( 'trusted' ); + } + } + + public function get_id() { + return $this->post_id; + } + + /** + * Get Collection Of soicals with theirs values + */ + public function get_socials() { + $socials = [ + 'facebook' => '', + 'twitter' => '', + 'pinterest' => '', + 'google' => '', + 'instagram' => '', + 'linkedIn' => '', + ]; + + $output = []; + + foreach ( $socials as $social => $k ) { + + $data = $this->get_meta( $social ); + if ( $data && $data != "#" && ! empty( $data ) ) { + $output[ $social ] = $data; + } + } + + return $output; + } + + /** + * Get url of user avatar by agent id + */ + public static function get_avatar_url( $userID ) { + return get_post_meta( $userID, OPALESTATE_AGENT_PREFIX . "avatar", true ); + } + + /** + * Render list of levels of agent + */ + public function render_level() { + $levels = wp_get_post_terms( $this->get_id(), 'opalestate_agent_level' ); + + if ( empty( $levels ) ) { + return; + } + + $output = ''; + foreach ( $levels as $key => $value ) { + $output .= '' . $value->name . ''; + } + $output .= ''; + + echo $output; + } + + /** + * get meta data value of key without prefix + */ + public function get_meta( $key ) { + return get_post_meta( $this->get_id(), OPALESTATE_AGENT_PREFIX . $key, true ); + } + + + /** + * return true if this agent is featured + */ + public function is_featured() { + return $this->is_featured; + } + + /** + * render block information by id + */ + public static function render_box_info( $post_id ) { + + } + + public static function get_link( $agent_id ) { + $agent = get_post( $agent_id ); + $url = self::get_avatar_url( $agent_id ); + + return [ + 'name' => $agent->post_title, + 'avatar' => $url, + 'link' => get_permalink( $agent->ID ), + ]; + + } + + public static function metaboxes_fields() { + $metabox = new Opalestate_Agent_MetaBox(); + $fields = $metabox->metaboxes_admin_fields(); + + return array_merge_recursive( $fields, $metabox->get_social_fields( OPALESTATE_AGENT_PREFIX ) ); + } + + public static function update_user_data( $user_id ) { + + $fields = self::metaboxes_fields(); + + $others = [ + 'avatar_id' => '', + 'opalestate_agt_map' => '', + 'map' => '', + ]; + foreach ( $fields as $key => $field ) { + $kpos = $field['id']; + $tmp = str_replace( OPALESTATE_AGENT_PREFIX, '', $field['id'] ); + if ( isset( $_POST[ $kpos ] ) && $tmp ) { + $data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ]; + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . $tmp, $data ); + } + } + + // update for others + foreach ( $others as $key => $value ) { + $kpos = OPALESTATE_AGENT_PREFIX . $key; + if ( isset( $_POST[ $kpos ] ) ) { + $data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ]; + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . $key, $data ); + } + } + } + + /** + * + */ + public function get_trusted() { + return $this->is_trusted; + } + + /** + * + */ + public static function update_data_from_user( $related_id ) { + + + $fields = self::metaboxes_fields(); + + $others = [ + 'avatar_id' => '', + 'map' => '', + ]; + foreach ( $fields as $key => $field ) { + + $tmp = str_replace( OPALESTATE_AGENT_PREFIX, "", $field['id'] ); + $kpos = OPALESTATE_USER_PROFILE_PREFIX . $tmp; + + if ( isset( $_POST[ $kpos ] ) && $tmp ) { + $data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ]; + update_post_meta( $related_id, OPALESTATE_AGENT_PREFIX . $tmp, $data ); + } + } + + // update for others + foreach ( $others as $key => $value ) { + $kpos = OPALESTATE_USER_PROFILE_PREFIX . $key; + if ( isset( $_POST[ $kpos ] ) ) { + $data = is_string( $_POST[ $kpos ] ) ? sanitize_text_field( $_POST[ $kpos ] ) : $_POST[ $kpos ]; + update_post_meta( $related_id, OPALESTATE_AGENT_PREFIX . $key, $data ); + } + } + } + + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_rating_counts() { + return $this->get_meta( 'rating_count' ) ? $this->get_meta( 'rating_count' ) : 0; + } + + /** + * Get average rating. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return float + */ + public function get_average_rating() { + return $this->get_meta( 'average_rating' ) ? $this->get_meta( 'average_rating' ) : 0; + } + + /** + * Get review count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_review_count() { + return $this->get_meta( 'review_count' ) ? $this->get_meta( 'review_count' ) : 0; + } + + /** + * + */ + public function get_rating_count_stats() { + return $this->get_meta( 'rating_count_stats' ) ? $this->get_meta( 'rating_count_stats' ) : [ + 5 => 0, + 4 => 0, + 3 => 0, + 2 => 0, + 1 => 0, + ]; + } + + /** + * + */ + public function get_rating_average_stats() { + return $this->get_meta( 'rating_average_stats' ); + } + + public function get_count_listing() { + return 4; + } +} + +?> diff --git a/inc/agent/functions.php b/inc/agent/functions.php new file mode 100755 index 00000000..e69de29b diff --git a/inc/ajax-functions.php b/inc/ajax-functions.php new file mode 100755 index 00000000..eabf0561 --- /dev/null +++ b/inc/ajax-functions.php @@ -0,0 +1,301 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +function opalestate_gallery_property() { + $post_id = intval( $_POST['property_id'] ); + $gallery = get_post_meta( $post_id, OPALESTATE_PROPERTY_PREFIX . 'gallery', 1 ); + + echo json_encode( [ 'gallery' => $gallery ] ); + die; +} + +add_action( 'wp_ajax_opalestate_gallery_property', 'opalestate_gallery_property' ); +add_action( 'wp_ajax_nopriv_opalestate_gallery_property', 'opalestate_gallery_property' ); +/** + * Searches for users via ajax and returns a list of results + * + * @return void + * @since 1.0 + * + */ +function opalestate_ajax_search_property_users() { + + $search_query = trim( $_GET['q'] ); + + $get_users_args = [ + 'number' => 9999, + 'search' => $search_query . '*', + ]; + + $get_users_args = apply_filters( 'opalestate_search_users_args', $get_users_args ); + + $found_users = apply_filters( 'opalestate_ajax_found_property_users', get_users( $get_users_args ), $search_query ); + + $users = []; + if ( ! empty( $found_users ) ) { + foreach ( $found_users as $user ) { + $users[] = [ + 'id' => $user->ID, + 'name' => $user->display_name, + 'avatar_url' => OpalEstate_User::get_author_picture( $user->ID ), + 'full_name' => $user->display_name, + 'description' => 'okokok', + ]; + } + } + + $output = [ + 'total_count' => count( $users ), + 'items' => $users, + 'incomplete_results' => false, + ]; + echo json_encode( $output ); + + die(); +} + +add_action( 'wp_ajax_opalestate_search_property_users', 'opalestate_ajax_search_property_users' ); + + +add_action( 'wp_ajax_opalestate_ajax_get_state_by_country', "opalestate_ajax_get_state_by_country" ); +function opalestate_ajax_get_state_by_country() { + if ( ! isset( $_POST['country'] ) ) { + die; + } + + $country = sanitize_text_field( $_POST['country'] ); + + $is_search = isset( $_POST['is_search'] ) && $_POST['is_search']; + + $terms = get_terms( [ + 'taxonomy' => 'opalestate_state', + 'orderby' => 'name', + 'order' => 'ASC', + 'hide_empty' => $is_search ? true : false, + 'meta_query' => [ + [ + 'key' => 'opalestate_state_location', + 'value' => $country, + ], + ], + ] ); + + $states = []; + $states[] = [ + 'id' => $is_search ? '-1' : '', + 'text' => esc_html__( 'Select State', 'opalestate-pro' ), + ]; + + if ( $terms ) { + foreach ( $terms as $term ) { + $states[] = [ + 'id' => $term->slug, + 'text' => $term->name, + ]; + } + } + + echo json_encode( $states ); + wp_die(); +} + +add_action( 'wp_ajax_opalestate_ajax_get_city_by_state', "opalestate_ajax_get_city_by_state" ); +function opalestate_ajax_get_city_by_state() { + if ( ! isset( $_POST['state'] ) ) { + die; + } + + $state = sanitize_text_field( $_POST['state'] ); + + $is_search = isset( $_POST['is_search'] ) && $_POST['is_search']; + + $terms = get_terms( [ + 'taxonomy' => 'opalestate_city', + 'orderby' => 'name', + 'order' => 'ASC', + 'hide_empty' => $is_search ? true : false, + 'meta_query' => [ + [ + 'key' => 'opalestate_city_state', + 'value' => $state, + ], + ], + ] ); + + $cities = []; + $cities[] = [ + 'id' => $is_search ? '-1' : '', + 'text' => esc_html__( 'Select City', 'opalestate-pro' ), + ]; + + if ( $terms ) { + foreach ( $terms as $term ) { + $cities[] = [ + 'id' => $term->slug, + 'text' => $term->name, + ]; + } + } + + echo json_encode( $cities ); + wp_die(); +} + +/* set feature property */ +add_action( 'wp_ajax_opalestate_set_feature_property', 'opalestate_set_feature_property' ); +add_action( 'wp_ajax_nopriv_opalestate_set_feature_property', 'opalestate_set_feature_property' ); +if ( ! function_exists( 'opalestate_set_feature_property' ) ) { + function opalestate_set_feature_property() { + + if ( ! isset( $_REQUEST['nonce'] ) && ! wp_verify_nonce( $_REQUEST['nonce'], 'nonce' ) ) { + return; + } + if ( ! isset( $_REQUEST['property_id'] ) ) { + return; + } + update_post_meta( absint( $_REQUEST['property_id'] ), OPALESTATE_PROPERTY_PREFIX . 'featured', 1 ); + + wp_redirect( admin_url( 'edit.php?post_type=opalestate_property' ) ); + exit(); + } +} +/* remove feature property */ +add_action( 'wp_ajax_opalestate_remove_feature_property', 'opalestate_remove_feature_property' ); +add_action( 'wp_ajax_nopriv_opalestate_remove_feature_property', 'opalestate_remove_feature_property' ); +if ( ! function_exists( 'opalestate_remove_feature_property' ) ) { + function opalestate_remove_feature_property() { + if ( ! isset( $_REQUEST['nonce'] ) && ! wp_verify_nonce( $_REQUEST['nonce'], 'nonce' ) ) { + return; + } + + if ( ! isset( $_REQUEST['property_id'] ) ) { + return; + } + + update_post_meta( absint( $_REQUEST['property_id'] ), OPALESTATE_PROPERTY_PREFIX . 'featured', '' ); + wp_redirect( admin_url( 'edit.php?post_type=opalestate_property' ) ); + exit(); + } +} + +/** + * Set Featured Item Following user + */ +add_action( 'wp_ajax_opalestate_toggle_featured_property', 'opalestate_toggle_featured_property' ); +add_action( 'wp_ajax_nopriv_opalestate_toggle_featured_property', 'opalestate_toggle_featured_property' ); + +function opalestate_toggle_featured_property() { + + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + + $property_id = intval( $_POST['property_id'] ); + $post = get_post( $property_id ); + + if ( $post->post_author == $user_id ) { + + $check = apply_filters( 'opalestate_set_feature_property_checked', false ); + if ( $check ) { + do_action( 'opalestate_toggle_featured_property_before', $user_id, $property_id ); + update_post_meta( $property_id, OPALESTATE_PROPERTY_PREFIX . 'featured', 1 ); + echo json_encode( [ 'status' => true, 'msg' => esc_html__( 'Could not set this as featured', 'opalestate-pro' ) ] ); + wp_die(); + } + } + + echo json_encode( [ 'status' => false, 'msg' => esc_html__( 'Could not set this as featured', 'opalestate-pro' ) ] ); + wp_reset_query(); + wp_die(); + +} + + +/** + * load more properties by agency + */ +add_action( 'wp_ajax_get_agency_property', 'opalestate_load_more_agency_property' ); +add_action( 'wp_ajax_nopriv_get_agency_property', 'opalestate_load_more_agency_property' ); + +function opalestate_load_more_agency_property() { + + + $post = [ + 'post_id' => 0, + 'paged' => 1, + 'user_id' => 13, + 'related' => '', + 'limit' => apply_filters( 'opalesate_agency_properties_limit', 5 ), + ]; + + $post = array_merge( $post, $_POST ); + extract( $post ); + + $user_id = get_post_meta( absint( $post_id ), OPALESTATE_AGENCY_PREFIX . 'user_id', true ); + $query = Opalestate_Query::get_agency_property( absint( $post_id ), absint( $user_id ), absint( $limit ), absint( $paged ) ); + + if ( $query->have_posts() ) : + while ( $query->have_posts() ) : $query->the_post(); ?> +
            + +
            + 1, + 'id' => 13, + 'limit' => apply_filters( 'opalesate_agent_properties_limit', 1 ), + ]; + + $post = array_merge( $post, $_POST ); + extract( $post ); + + set_query_var( 'paged', $post['paged'] ); + $query = Opalestate_Query::get_agent_property( null, absint( $post['id'] ), absint( $limit ) ); + + $paged = absint( $post['paged'] ); + if ( $query->have_posts() ) : ?> +
            +
            + have_posts() ) : $query->the_post(); ?> +
            + +
            + +
            +
            + max_num_pages > 1 ): ?> +
            max_num_pages ); ?>
            + + versions = array( + 'v1' => 'Opalestate_API', + ); + + + + add_action( 'init', array( $this, 'add_endpoint' ) ); + add_action( 'wp', array( $this, 'process_query' ), - 1 ); + add_filter( 'query_vars', array( $this, 'query_vars' ) ); + add_action( 'show_user_profile', array( $this, 'user_key_field' ) ); + add_action( 'edit_user_profile', array( $this, 'user_key_field' ) ); + add_action( 'personal_options_update', array( $this, 'update_key' ) ); + add_action( 'edit_user_profile_update', array( $this, 'update_key' ) ); + add_action( 'opalestate_process_api_key', array( $this, 'process_api_key' ) ); + + // Setup a backwards compatibility check for user API Keys + add_filter( 'get_user_metadata', array( $this, 'api_key_backwards_compat' ), 10, 4 ); + + // Determine if JSON_PRETTY_PRINT is available + $this->pretty_print = defined( 'JSON_PRETTY_PRINT' ) ? JSON_PRETTY_PRINT : null; + + // Allow API request logging to be turned off + $this->log_requests = apply_filters( 'opalestate_api_log_requests', $this->log_requests ); + + + } + + /** + * Registers a new rewrite endpoint for accessing the API + * + * @access public + * + * @param array $rewrite_rules WordPress Rewrite Rules + * + * @since 1.1 + */ + public function add_endpoint( $rewrite_rules ) { + add_rewrite_endpoint( 'opalestate-api', EP_ALL ); + } + + /** + * Registers query vars for API access + * + * @access public + * @since 1.1 + * + * @param array $vars Query vars + * + * @return string[] $vars New query vars + */ + public function query_vars( $vars ) { + + $vars[] = 'token'; + $vars[] = 'key'; + $vars[] = 'query'; + $vars[] = 'type'; + $vars[] = 'property'; + $vars[] = 'number'; + $vars[] = 'date'; + $vars[] = 'startdate'; + $vars[] = 'enddate'; + $vars[] = 'donor'; + $vars[] = 'propertyat'; + $vars[] = 'id'; + $vars[] = 'purchasekey'; + $vars[] = 'email'; + + return $vars; + } + + /** + * Retrieve the API versions + * + * @access public + * @since 1.1 + * @return array + */ + public function get_versions() { + return $this->versions; + } + + /** + * Retrieve the API version that was queried + * + * @access public + * @since 1.1 + * @return string + */ + public function get_queried_version() { + return $this->queried_version; + } + + /** + * Retrieves the default version of the API to use + * + * @access public + * @since 1.1 + * @return string + */ + public function get_default_version() { + + $version = get_option( 'opalestate_default_api_version' ); + + if ( defined( 'OPALESTATE_API_VERSION' ) ) { + $version = OPALESTATE_API_VERSION; + } elseif ( ! $version ) { + $version = 'v1'; + } + + return $version; + } + + /** + * Sets the version of the API that was queried. + * + * Falls back to the default version if no version is specified + * + * @access private + * @since 1.1 + */ + private function set_queried_version() { + + global $wp_query; + + $version = $wp_query->query_vars['opalestate-api']; + + if ( strpos( $version, '/' ) ) { + + $version = explode( '/', $version ); + $version = strtolower( $version[0] ); + + $wp_query->query_vars['opalestate-api'] = str_replace( $version . '/', '', $wp_query->query_vars['opalestate-api'] ); + + if ( array_key_exists( $version, $this->versions ) ) { + + $this->queried_version = $version; + + } else { + + $this->is_valid_request = false; + $this->invalid_version(); + } + + } else { + + $this->queried_version = $this->get_default_version(); + + } + + } + + /** + * Validate the API request + * + * Checks for the user's public key and token against the secret key + * + * @access private + * @global object $wp_query WordPress Query + * @uses Opalestate_API::get_user() + * @uses Opalestate_API::invalid_key() + * @uses Opalestate_API::invalid_auth() + * @since 1.1 + * @return void + */ + private function validate_request() { + global $wp_query; + + $this->override = false; + + // Make sure we have both user and api key + if ( ! empty( $wp_query->query_vars['opalestate-api'] ) && ( $wp_query->query_vars['opalestate-api'] != 'properties' || ! empty( $wp_query->query_vars['token'] ) ) ) { + + if ( empty( $wp_query->query_vars['token'] ) || empty( $wp_query->query_vars['key'] ) ) { + $this->missing_auth(); + } + + // Retrieve the user by public API key and ensure they exist + if ( ! ( $user = $this->get_user( $wp_query->query_vars['key'] ) ) ) { + + $this->invalid_key(); + + } else { + + $token = urldecode( $wp_query->query_vars['token'] ); + $secret = $this->get_user_secret_key( $user ); + $public = urldecode( $wp_query->query_vars['key'] ); + + if ( hash_equals( md5( $secret . $public ), $token ) ) { + $this->is_valid_request = true; + } else { + $this->invalid_auth(); + } + } + } elseif ( ! empty( $wp_query->query_vars['opalestate-api'] ) && $wp_query->query_vars['opalestate-api'] == 'properties' ) { + $this->is_valid_request = true; + $wp_query->set( 'key', 'public' ); + } + } + + /** + * Retrieve the user ID based on the public key provided + * + * @access public + * @since 1.1 + * @global WPDB $wpdb Used to query the database using the WordPress + * Database API + * + * @param string $key Public Key + * + * @return bool if user ID is found, false otherwise + */ + public function get_user( $key = '' ) { + global $wpdb, $wp_query; + + if ( empty( $key ) ) { + $key = urldecode( $wp_query->query_vars['key'] ); + } + + if ( empty( $key ) ) { + return false; + } + + $user = get_transient( md5( 'opalestate_api_user_' . $key ) ); + + if ( false === $user ) { + $user = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s LIMIT 1", $key ) ); + set_transient( md5( 'opalestate_api_user_' . $key ), $user, DAY_IN_SECONDS ); + } + + if ( $user != null ) { + $this->user_id = $user; + + return $user; + } + + return false; + } + + public function get_user_public_key( $user_id = 0 ) { + global $wpdb; + + if ( empty( $user_id ) ) { + return ''; + } + + $cache_key = md5( 'opalestate_api_user_public_key' . $user_id ); + $user_public_key = get_transient( $cache_key ); + + if ( empty( $user_public_key ) ) { + $user_public_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'opalestate_user_public_key' AND user_id = %d", $user_id ) ); + set_transient( $cache_key, $user_public_key, HOUR_IN_SECONDS ); + } + + return $user_public_key; + } + + public function get_user_secret_key( $user_id = 0 ) { + global $wpdb; + + if ( empty( $user_id ) ) { + return ''; + } + + $cache_key = md5( 'opalestate_api_user_secret_key' . $user_id ); + $user_secret_key = get_transient( $cache_key ); + + if ( empty( $user_secret_key ) ) { + $user_secret_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'opalestate_user_secret_key' AND user_id = %d", $user_id ) ); + set_transient( $cache_key, $user_secret_key, HOUR_IN_SECONDS ); + } + + return $user_secret_key; + } + + /** + * Displays a missing authentication error if all the parameters aren't + * provided + * + * @access private + * @uses Opalestate_API::output() + * @since 1.1 + */ + private function missing_auth() { + $error = array(); + $error['error'] = esc_html__( 'You must specify both a token and API key!', 'opalestate-pro' ); + + $this->data = $error; + $this->output( 401 ); + } + + /** + * Displays an authentication failed error if the user failed to provide valid + * credentials + * + * @access private + * @since 1.1 + * @uses Opalestate_API::output() + * @return void + */ + private function invalid_auth() { + $error = array(); + $error['error'] = esc_html__( 'Your request could not be authenticated!', 'opalestate-pro' ); + + $this->data = $error; + $this->output( 403 ); + } + + /** + * Displays an invalid API key error if the API key provided couldn't be + * validated + * + * @access private + * @since 1.1 + * @uses Opalestate_API::output() + * @return void + */ + private function invalid_key() { + $error = array(); + $error['error'] = esc_html__( 'Invalid API key!', 'opalestate-pro' ); + + $this->data = $error; + $this->output( 403 ); + } + + /** + * Displays an invalid version error if the version number passed isn't valid + * + * @access private + * @since 1.1 + * @uses Opalestate_API::output() + * @return void + */ + private function invalid_version() { + $error = array(); + $error['error'] = esc_html__( 'Invalid API version!', 'opalestate-pro' ); + + $this->data = $error; + $this->output( 404 ); + } + + /** + * Listens for the API and then processes the API requests + * + * @access public + * @global $wp_query + * @since 1.1 + * @return void + */ + public function process_query() { + + global $wp_query; + + // Start logging how long the request takes for logging + $before = microtime( true ); + + // Check for opalestate-api var. Get out if not present + if ( empty( $wp_query->query_vars['opalestate-api'] ) ) { + return; + } + + // Determine which version was queried + $this->set_queried_version(); + + // Determine the kind of query + $this->set_query_mode(); + + // Check for a valid user and set errors if necessary + $this->validate_request(); + + // Only proceed if no errors have been noted + if ( ! $this->is_valid_request ) { + return; + } + + if ( ! defined( 'OPALESTATE_DOING_API' ) ) { + define( 'OPALESTATE_DOING_API', true ); + } + + $data = array(); + $this->routes = new $this->versions[$this->get_queried_version()]; + $this->routes->validate_request(); + + switch ( $this->endpoint ) : + + + case 'properties' : + + $property = isset( $wp_query->query_vars['property'] ) ? $wp_query->query_vars['property'] : null; + + $data = $this->routes->get_properties( $property ); + + break; + case 'featured' : + + $property = isset( $wp_query->query_vars['property'] ) ? $wp_query->query_vars['property'] : null; + + $data = $this->routes->get_featured_properties( $property ); + + break; + + case 'agents' : + + $agent = isset( $wp_query->query_vars['agent'] ) ? $wp_query->query_vars['agent'] : null; + + $data = $this->routes->get_agents( $agent ); + + break; + + + endswitch; + + // Allow extensions to setup their own return data + $this->data = apply_filters( 'opalestate_api_output_data', $data, $this->endpoint, $this ); + + $after = microtime( true ); + $request_time = ( $after - $before ); + $this->data['request_speed'] = $request_time; + + // Log this API request, if enabled. We log it here because we have access to errors. + $this->log_request( $this->data ); + + // Send out data to the output function + $this->output(); + } + + /** + * Returns the API endpoint requested + * + * @access public + * @since 1.1 + * @return string $query Query mode + */ + public function get_query_mode() { + + return $this->endpoint; + } + + /** + * Determines the kind of query requested and also ensure it is a valid query + * + * @access public + * @since 1.1 + * @global $wp_query + */ + public function set_query_mode() { + + global $wp_query; + + // Whitelist our query options + $accepted = apply_filters( 'opalestate_api_valid_query_modes', array( + 'agents', + 'properties', + 'featured' + ) ); + + $query = isset( $wp_query->query_vars['opalestate-api'] ) ? $wp_query->query_vars['opalestate-api'] : null; + $query = str_replace( $this->queried_version . '/', '', $query ); + + $error = array(); + + // Make sure our query is valid + if ( ! in_array( $query, $accepted ) ) { + $error['error'] = esc_html__( 'Invalid query!', 'opalestate-pro' ); + + $this->data = $error; + // 400 is Bad Request + $this->output( 400 ); + } + + $this->endpoint = $query; + } + + /** + * Get page number + * + * @access public + * @since 1.1 + * @global $wp_query + * @return int $wp_query->query_vars['page'] if page number returned (default: 1) + */ + public function get_paged() { + global $wp_query; + + return isset( $wp_query->query_vars['page'] ) ? $wp_query->query_vars['page'] : 1; + } + + + /** + * Number of results to display per page + * + * @access public + * @since 1.1 + * @global $wp_query + * @return int $per_page Results to display per page (default: 10) + */ + public function per_page() { + global $wp_query; + + $per_page = isset( $wp_query->query_vars['number'] ) ? $wp_query->query_vars['number'] : 10; + + return apply_filters( 'opalestate_api_results_per_page', $per_page ); + } + + + /** + * + * + */ + public function get_agents( $agent = null ) { + + $agents = array(); + $error = array(); + + if ( $agent == null ) { + $agents['agents'] = array(); + + $property_list = get_posts( array( + 'post_type' => 'opalestate_agent', + 'posts_per_page' => $this->per_page(), + 'suppress_filters' => true, + 'paged' => $this->get_paged() + ) ); + + if ( $property_list ) { + $i = 0; + foreach ( $property_list as $agent_info ) { + $agents['agents'][ $i ] = $this->get_agent_data( $agent_info ); + $i ++; + } + } + } else { + if ( get_post_type( $agent ) == 'opalestate_property' ) { + $agent_info = get_post( $agent ); + + $agents['agents'][0] = $this->get_agent_data( $agent_info ); + + } else { + $error['error'] = sprintf( + /* translators: %s: property */ + esc_html__( 'Form %s not found!', 'opalestate-pro' ), + $agent + ); + + return $error; + } + } + + return $agents; + } + + /** + * + * + */ + public function get_agent_data( $agent_info ){ + $ouput = array(); + + $ouput['info']['id'] = $agent_info->ID; + $ouput['info']['slug'] = $agent_info->post_name; + $ouput['info']['title'] = $agent_info->post_title; + $ouput['info']['create_date'] = $agent_info->post_date; + $ouput['info']['modified_date'] = $agent_info->post_modified; + $ouput['info']['status'] = $agent_info->post_status; + $ouput['info']['link'] = html_entity_decode( $agent_info->guid ); + $ouput['info']['content'] = $agent_info->post_content; + $ouput['info']['thumbnail'] = wp_get_attachment_url( get_post_thumbnail_id( $agent_info->ID ) ); + + + + $agent = new OpalEstate_Agent( $agent_info->ID ); + + $ouput['info']['featured'] = (int)$agent->is_featured(); + $ouput['info']['email'] = get_post_meta( $agent_info->ID, OPALESTATE_AGENT_PREFIX . 'email', true ); + $ouput['info']['address'] = get_post_meta( $agent_info->ID, OPALESTATE_AGENT_PREFIX . 'address', true ); + + $terms = wp_get_post_terms( $agent_info->ID, 'opalestate_agent_location' ); + $ouput['info']['location'] = $terms && !is_wp_error($terms) ? $terms : array(); + + $ouput['socials'] = $agent->get_socials(); + + $ouput['levels'] = wp_get_post_terms( $agent_info->ID, 'opalestate_agent_level' ); + + + return apply_filters( 'opalestate_api_agents', $ouput ); + } + + /** + * Process Get Products API Request + * + * @access public + * @since 1.1 + * + * @param int $property Opalestate Form ID + * + * @return array $customers Multidimensional array of the properties + */ + public function get_featured_properties( $property = null ) { + + $properties = array(); + $error = array(); + + if ( $property == null ) { + $properties['properties'] = array(); + + $property_list = get_posts( array( + 'post_type' => 'opalestate_property', + 'posts_per_page' => $this->per_page(), + 'suppress_filters' => true, + 'paged' => $this->get_paged(), + 'meta_key' => OPALESTATE_PROPERTY_PREFIX . 'featured', + 'meta_value' => 1, + 'meta_compare' => '=' + ) ); + + if ( $property_list ) { + $i = 0; + foreach ( $property_list as $property_info ) { + $properties['properties'][ $i ] = $this->get_property_data( $property_info ); + $i ++; + } + } + } else { + if ( get_post_type( $property ) == 'opalestate_property' ) { + $property_info = get_post( $property ); + + $properties['properties'][0] = $this->get_property_data( $property_info ); + + } else { + $error['error'] = sprintf( + /* translators: %s: property */ + esc_html__( 'Form %s not found!', 'opalestate-pro' ), + $property + ); + + return $error; + } + } + + return $properties; + } + + /** + * Process Get Products API Request + * + * @access public + * @since 1.1 + * + * @param int $property Opalestate Form ID + * + * @return array $customers Multidimensional array of the properties + */ + public function get_properties( $property = null ) { + + $properties = array(); + $error = array(); + + if ( $property == null ) { + $properties['properties'] = array(); + + $property_list = get_posts( array( + 'post_type' => 'opalestate_property', + 'posts_per_page' => $this->per_page(), + 'suppress_filters' => true, + 'paged' => $this->get_paged() + ) ); + + if ( $property_list ) { + $i = 0; + foreach ( $property_list as $property_info ) { + $properties['properties'][ $i ] = $this->get_property_data( $property_info ); + $i ++; + } + } + } else { + if ( get_post_type( $property ) == 'opalestate_property' ) { + $property_info = get_post( $property ); + + $properties['properties'][0] = $this->get_property_data( $property_info ); + + } else { + $error['error'] = sprintf( + /* translators: %s: property */ + esc_html__( 'Form %s not found!', 'opalestate-pro' ), + $property + ); + + return $error; + } + } + + return $properties; + } + + /** + * Opalestaten a opalestate_property post object, generate the data for the API output + * + * @since 1.1 + * + * @param object $property_info The Download Post Object + * + * @return array Array of post data to return back in the API + */ + private function get_property_data( $property_info ) { + + $property = array(); + + $property['info']['id'] = $property_info->ID; + $property['info']['slug'] = $property_info->post_name; + $property['info']['title'] = $property_info->post_title; + $property['info']['create_date'] = $property_info->post_date; + $property['info']['modified_date'] = $property_info->post_modified; + $property['info']['status'] = $property_info->post_status; + $property['info']['link'] = html_entity_decode( $property_info->guid ); + $property['info']['content'] = $property_info->post_content; + $property['info']['thumbnail'] = wp_get_attachment_url( get_post_thumbnail_id( $property_info->ID ) ); + + $data = opalesetate_property( $property_info->ID ); + $gallery = $data->get_gallery(); + $property['info']['gallery'] = isset($gallery[0]) && !empty($gallery[0]) ? $gallery[0]: array(); + $property['info']['price'] = opalestate_price_format( $data->get_price() ); + $property['info']['map'] = $data->get_map(); + $property['info']['address'] = $data->get_address(); + $property['meta'] = $data->get_meta_shortinfo(); + + $property['status'] = $data->get_status(); + $property['locations'] = $data->get_locations(); + $property['amenities'] = $data->get_amenities(); + $property['types'] = $data->get_types_tax(); + + + if ( user_can( $this->user_id, 'view_opalestate_sensitive_data' ) || $this->override ) { + + //Sensitive data here + do_action( 'opalestate_api_sensitive_data' ); + + } + + return apply_filters( 'opalestate_api_properties_property', $property ); + + } + + + + + /** + * Retrieve the output propertyat + * + * Determines whether results should be displayed in XML or JSON + * + * @since 1.1 + * @access public + * + * @return mixed|void + */ + public function get_output_propertyat() { + global $wp_query; + + $propertyat = isset( $wp_query->query_vars['propertyat'] ) ? $wp_query->query_vars['propertyat'] : 'json'; + + return apply_filters( 'opalestate_api_output_propertyat', $propertyat ); + } + + + /** + * Log each API request, if enabled + * + * @access private + * @since 1.1 + * + * @global Opalestate_Logging $opalestate_logs + * @global WP_Query $wp_query + * + * @param array $data + * + * @return void + */ + private function log_request( $data = array() ) { + if ( ! $this->log_requests ) { + return; + } + + /** + * @var Opalestate_Logging $opalestate_logs + */ + global $opalestate_logs; + + /** + * @var WP_Query $wp_query + */ + global $wp_query; + + $query = array( + 'opalestate-api' => $wp_query->query_vars['opalestate-api'], + 'key' => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null, + 'token' => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null, + 'query' => isset( $wp_query->query_vars['query'] ) ? $wp_query->query_vars['query'] : null, + 'type' => isset( $wp_query->query_vars['type'] ) ? $wp_query->query_vars['type'] : null, + 'property' => isset( $wp_query->query_vars['property'] ) ? $wp_query->query_vars['property'] : null, + 'customer' => isset( $wp_query->query_vars['customer'] ) ? $wp_query->query_vars['customer'] : null, + 'date' => isset( $wp_query->query_vars['date'] ) ? $wp_query->query_vars['date'] : null, + 'startdate' => isset( $wp_query->query_vars['startdate'] ) ? $wp_query->query_vars['startdate'] : null, + 'enddate' => isset( $wp_query->query_vars['enddate'] ) ? $wp_query->query_vars['enddate'] : null, + 'id' => isset( $wp_query->query_vars['id'] ) ? $wp_query->query_vars['id'] : null, + 'purchasekey' => isset( $wp_query->query_vars['purchasekey'] ) ? $wp_query->query_vars['purchasekey'] : null, + 'email' => isset( $wp_query->query_vars['email'] ) ? $wp_query->query_vars['email'] : null, + ); + + $log_data = array( + 'log_type' => 'api_request', + 'post_excerpt' => http_build_query( $query ), + 'post_content' => ! empty( $data['error'] ) ? $data['error'] : '', + ); + + $log_meta = array( + 'request_ip' => opalestate_get_ip(), + 'user' => $this->user_id, + 'key' => isset( $wp_query->query_vars['key'] ) ? $wp_query->query_vars['key'] : null, + 'token' => isset( $wp_query->query_vars['token'] ) ? $wp_query->query_vars['token'] : null, + 'time' => $data['request_speed'], + 'version' => $this->get_queried_version() + ); + } + + + /** + * Retrieve the output data + * + * @access public + * @since 1.1 + * @return array + */ + public function get_output() { + return $this->data; + } + + /** + * Output Query in either JSON/XML. The query data is outputted as JSON + * by default + * + * @since 1.1 + * @global WP_Query $wp_query + * + * @param int $status_code + */ + public function output( $status_code = 200 ) { + /** + * @var WP_Query $wp_query + */ + global $wp_query; + + $propertyat = $this->get_output_propertyat(); + + status_header( $status_code ); + + do_action( 'opalestate_api_output_before', $this->data, $this, $propertyat ); + + switch ( $propertyat ) : + + case 'xml' : + + require_once OPALESTATE_PLUGIN_DIR . 'inc/libraries/array2xml.php'; + $xml = Array2XML::createXML( 'opalestate-pro', $this->data ); + echo $xml->saveXML(); + + break; + + case 'json' : + + header( 'Content-Type: application/json' ); + if ( ! empty( $this->pretty_print ) ) { + echo json_encode( $this->data, $this->pretty_print ); + } else { + echo json_encode( $this->data ); + } + + break; + + + default : + + // Allow other propertyats to be added via extensions + do_action( 'opalestate_api_output_' . $propertyat, $this->data, $this ); + + break; + + endswitch; + + do_action( 'opalestate_api_output_after', $this->data, $this, $propertyat ); + + die(); + } + + /** + * Modify User Profile + * + * Modifies the output of profile.php to add key generation/revocation + * + * @access public + * @since 1.1 + * + * @param object $user Current user info + * + * @return void + */ + function user_key_field( $user ) { + + if ( ( opalestate_get_option( 'api_allow_user_keys', false ) || current_user_can( 'manage_opalestate_settings' ) ) && current_user_can( 'edit_user', $user->ID ) ) { + $user = get_userdata( $user->ID ); + ?> +
            + + + + + + + +
            + + + get_user_public_key( $user->ID ); + $secret_key = $this->get_user_secret_key( $user->ID ); + ?> + opalestate_user_public_key ) ) { ?> + + + +   + +
            +   + +
            +   + +
            + + + +
            + 403 ) ); + + } + + if ( empty( $args['user_id'] ) ) { + wp_die( esc_html__( 'User ID Required.', 'opalestate-pro' ), esc_html__( 'Error', 'opalestate-pro' ), array( 'response' => 401 ) ); + } + + if ( is_numeric( $args['user_id'] ) ) { + $user_id = isset( $args['user_id'] ) ? absint( $args['user_id'] ) : get_current_user_id(); + } else { + $userdata = get_user_by( 'login', $args['user_id'] ); + $user_id = $userdata->ID; + } + $process = isset( $args['opalestate_api_process'] ) ? strtolower( $args['opalestate_api_process'] ) : false; + + if ( $user_id == get_current_user_id() && ! opalestate_get_option( 'allow_user_api_keys' ) && ! current_user_can( 'manage_opalestate_settings' ) ) { + wp_die( + sprintf( + /* translators: %s: process */ + esc_html__( 'You do not have permission to %s API keys for this user.', 'opalestate-pro' ), + $process + ), + esc_html__( 'Error', 'opalestate-pro' ), + array( 'response' => 403 ) + ); + } elseif ( ! current_user_can( 'manage_opalestate_settings' ) ) { + wp_die( + sprintf( + /* translators: %s: process */ + esc_html__( 'You do not have permission to %s API keys for this user.', 'opalestate-pro' ), + $process + ), + esc_html__( 'Error', 'opalestate-pro' ), + array( 'response' => 403 ) + ); + } + + switch ( $process ) { + case 'generate': + if ( $this->generate_api_key( $user_id ) ) { + delete_transient( 'opalestate_total_api_keys' ); + wp_redirect( add_query_arg( 'opalestate-message', 'api-key-generated', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); + exit(); + } else { + wp_redirect( add_query_arg( 'opalestate-message', 'api-key-failed', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); + exit(); + } + break; + case 'regenerate': + $this->generate_api_key( $user_id, true ); + delete_transient( 'opalestate_total_api_keys' ); + wp_redirect( add_query_arg( 'opalestate-message', 'api-key-regenerated', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); + exit(); + break; + case 'revoke': + $this->revoke_api_key( $user_id ); + delete_transient( 'opalestate_total_api_keys' ); + wp_redirect( add_query_arg( 'opalestate-message', 'api-key-revoked', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api' ) ); + exit(); + break; + default; + break; + } + } + + /** + * Generate new API keys for a user + * + * @access public + * @since 1.1 + * + * @param int $user_id User ID the key is being generated for + * @param boolean $regenerate Regenerate the key for the user + * + * @return boolean True if (re)generated succesfully, false otherwise. + */ + public function generate_api_key( $user_id = 0, $regenerate = false ) { + + if ( empty( $user_id ) ) { + return false; + } + + $user = get_userdata( $user_id ); + + if ( ! $user ) { + return false; + } + + $public_key = $this->get_user_public_key( $user_id ); + $secret_key = $this->get_user_secret_key( $user_id ); + + if ( empty( $public_key ) || $regenerate == true ) { + $new_public_key = $this->generate_public_key( $user->user_email ); + $new_secret_key = $this->generate_private_key( $user->ID ); + } else { + return false; + } + + if ( $regenerate == true ) { + $this->revoke_api_key( $user->ID ); + } + + update_user_meta( $user_id, $new_public_key, 'opalestate_user_public_key' ); + update_user_meta( $user_id, $new_secret_key, 'opalestate_user_secret_key' ); + + return true; + } + + /** + * Revoke a users API keys + * + * @access public + * @since 1.1 + * + * @param int $user_id User ID of user to revoke key for + * + * @return string + */ + public function revoke_api_key( $user_id = 0 ) { + + if ( empty( $user_id ) ) { + return false; + } + + $user = get_userdata( $user_id ); + + if ( ! $user ) { + return false; + } + + $public_key = $this->get_user_public_key( $user_id ); + $secret_key = $this->get_user_secret_key( $user_id ); + if ( ! empty( $public_key ) ) { + delete_transient( md5( 'opalestate_api_user_' . $public_key ) ); + delete_transient( md5( 'opalestate_api_user_public_key' . $user_id ) ); + delete_transient( md5( 'opalestate_api_user_secret_key' . $user_id ) ); + delete_user_meta( $user_id, $public_key ); + delete_user_meta( $user_id, $secret_key ); + } else { + return false; + } + + return true; + } + + public function get_version() { + return self::VERSION; + } + + + /** + * Generate and Save API key + * + * Generates the key requested by user_key_field and stores it in the database + * + * @access public + * @since 1.1 + * + * @param int $user_id + * + * @return void + */ + public function update_key( $user_id ) { + if ( current_user_can( 'edit_user', $user_id ) && isset( $_POST['opalestate_set_api_key'] ) ) { + + $user = get_userdata( $user_id ); + + $public_key = $this->get_user_public_key( $user_id ); + $secret_key = $this->get_user_secret_key( $user_id ); + + if ( empty( $public_key ) ) { + $new_public_key = $this->generate_public_key( $user->user_email ); + $new_secret_key = $this->generate_private_key( $user->ID ); + + update_user_meta( $user_id, $new_public_key, 'opalestate_user_public_key' ); + update_user_meta( $user_id, $new_secret_key, 'opalestate_user_secret_key' ); + } else { + $this->revoke_api_key( $user_id ); + } + } + } + + /** + * Generate the public key for a user + * + * @access private + * @since 1.1 + * + * @param string $user_email + * + * @return string + */ + private function generate_public_key( $user_email = '' ) { + $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; + $public = hash( 'md5', $user_email . $auth_key . date( 'U' ) ); + + return $public; + } + + /** + * Generate the secret key for a user + * + * @access private + * @since 1.1 + * + * @param int $user_id + * + * @return string + */ + private function generate_private_key( $user_id = 0 ) { + $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; + $secret = hash( 'md5', $user_id . $auth_key . date( 'U' ) ); + + return $secret; + } + + /** + * Retrieve the user's token + * + * @access private + * @since 1.1 + * + * @param int $user_id + * + * @return string + */ + public function get_token( $user_id = 0 ) { + return hash( 'md5', $this->get_user_secret_key( $user_id ) . $this->get_user_public_key( $user_id ) ); + } + + /** + * API Key Backwards Compatibility + * + * A Backwards Compatibility call for the change of meta_key/value for users API Keys + * + * @since 1.3.6 + * + * @param string $check Whether to check the cache or not + * @param int $object_id The User ID being passed + * @param string $meta_key The user meta key + * @param bool $single If it should return a single value or array + * + * @return string The API key/secret for the user supplied + */ + public function api_key_backwards_compat( $check, $object_id, $meta_key, $single ) { + + if ( $meta_key !== 'opalestate_user_public_key' && $meta_key !== 'opalestate_user_secret_key' ) { + return $check; + } + + $return = $check; + + switch ( $meta_key ) { + case 'opalestate_user_public_key': + $return = Opalestate()->api->get_user_public_key( $object_id ); + break; + case 'opalestate_user_secret_key': + $return = Opalestate()->api->get_user_secret_key( $object_id ); + break; + } + + if ( ! $single ) { + $return = array( $return ); + } + + return $return; + + } + +} diff --git a/inc/class-no-captcha-recaptcha.php b/inc/class-no-captcha-recaptcha.php new file mode 100755 index 00000000..d48ff647 --- /dev/null +++ b/inc/class-no-captcha-recaptcha.php @@ -0,0 +1,160 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Nocaptcha_Recaptcha + * + * @version 1.0 + */ +class OpalEstate_Nocaptcha_Recaptcha { + /** + * OpalEstate_Nocaptcha_Recaptcha constructor. + */ + public function __construct() { + if ( is_admin() ) { + + add_filter( 'opalestate_settings_3rd_party_subtabs_nav', [ $this, 'admin_tab_setting' ] ); + + add_filter( 'opalestate_settings_3rd_party_subtabs_google_captcha_page_fields', [ $this, 'admin_content_setting' ] ); + } + + if ( opalestate_options( 'show_captcha' ) == 'on' ) { + define( 'WPOPAL_CAPTCHA_LOAED', true ); + $this->theme = opalestate_options( 'captcha_theme', 'light' ); + add_action( 'wp_head', [ $this, 'add_custom_styles' ] ); + + add_action( 'opalestate_message_form_after', [ __CLASS__, 'show_captcha' ] ); + add_action( 'opalestate_process_send_email_before', [ __CLASS__, 'ajax_verify_captcha' ] ); + } + } + + /** + * + */ + public function add_custom_styles() { + $lang = null; + echo '' . "\r\n"; + } + + /** + * + */ + public static function show_captcha() { + + if ( isset( $_GET['captcha'] ) && $_GET['captcha'] == 'failed' ) { + + } + echo '
            '; + } + + /** + * + */ + public static function ajax_verify_captcha() { + $response = isset( $_POST['g-recaptcha-response'] ) ? esc_attr( $_POST['g-recaptcha-response'] ) : ''; + + $remote_ip = $_SERVER["REMOTE_ADDR"]; + + // make a GET request to the Google reCAPTCHA Server + $request = wp_remote_get( + 'https://www.google.com/recaptcha/api/siteverify?secret=' . opalestate_options( 'secret_key' ) . '&response=' . $response . '&remoteip=' . $remote_ip + ); + + // get the request response body + $response_body = wp_remote_retrieve_body( $request ); + + $result = json_decode( $response_body, true ); + + if ( isset( $result['hostname'] ) && ! empty( $result['hostname'] ) && empty( $result['success'] ) ) { + $result['success'] = 1; + } + if ( ! $result['success'] ) { + $return = [ 'status' => false, 'msg' => esc_html__( 'The captcha is not verified, please try again!', 'opalestate-pro' ) ]; + echo json_encode( $return ); + die(); + } + } + + /** + * + */ + public function admin_content_setting( $fields ) { + $fields = apply_filters( 'opalestate_settings_google_captcha', [ + + [ + 'name' => esc_html__( 'Show Captcha In Form', 'opalestate-pro' ), + 'desc' => __( 'Enable google captch in contact , register form. After Set yes, you change setting in Google Captcha Tab. Register here: https://www.google.com/recaptcha/admin Version 2', + 'opalestate-pro' ), + 'id' => 'show_captcha', + 'type' => 'switch', + 'options' => [ + 'off' => esc_html__( 'No', 'opalestate-pro' ), + 'on' => esc_html__( 'Yes', 'opalestate-pro' ), + ], + 'default' => 'on', + ], + + [ + 'name' => esc_html__( 'Google Captcha page Settings', 'opalestate-pro' ), + 'desc' => '
            ', + 'id' => 'opalestate_title_google_captcha_settings', + 'type' => 'title', + ], + + [ + 'name' => esc_html__( 'Site Key', 'opalestate-pro' ), + 'desc' => esc_html__( 'Used for displaying the CAPTCHA. Grab it %s', 'opalestate-pro' ), + 'id' => 'site_key', + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Secret key', 'opalestate-pro' ), + 'desc' => esc_html__( 'Used for communication between your site and Google. Grab it.', 'opalestate-pro' ), + 'id' => 'secret_key', + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Theme', 'opalestate-pro' ), + 'desc' => esc_html__( 'Display captcha box with color style.', 'opalestate-pro' ), + 'id' => 'captcha_theme', + 'type' => 'select', + 'options' => [ + 'light' => esc_html__( 'Light', 'opalestate-pro' ), + 'dark' => esc_html__( 'Dark', 'opalestate-pro' ), + ], + ], + + ] ); + + return $fields; + } + + /** + * + */ + public function admin_tab_setting( $tabs ) { + $tabs['google_captcha_page'] = esc_html__( 'Google Captcha', 'opalestate-pro' ); + + return $tabs; + } +} + +new OpalEstate_Nocaptcha_Recaptcha(); diff --git a/inc/class-opalestate-email.php b/inc/class-opalestate-email.php new file mode 100755 index 00000000..266235bd --- /dev/null +++ b/inc/class-opalestate-email.php @@ -0,0 +1,458 @@ + + * @copyright Copyright (C) 2014 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +// Exit if accessed directly +if ( !defined( 'ABSPATH' ) ) exit; + +/** + * @class OpalMembership_Checkout + * + * @version 1.0 + */ +class Opalestate_Emails { + + + /** + * init action to automatic send email when user edit or submit a new submission and init setting form in plugin setting of admin + */ + public static function init() { + + self::load(); + + add_action( 'opalestate_processed_new_submission' , array( __CLASS__ , 'new_submission_email'), 10, 2 ); + //add_action( 'opalestate_processed_edit_submission' , array( __CLASS__ , 'new_submission_email'), 10, 2 ); + if( is_admin() ){ + add_filter( 'opalestate_settings_tabs', array( __CLASS__, 'setting_email_tab'), 1 ); + add_filter( 'opalestate_registered_emails_settings', array( __CLASS__, 'setting_email_fields'), 10, 1 ); + } + + $enable_approve_property_email = opalestate_get_option( 'enable_approve_property_email' ); + + if ( $enable_approve_property_email == 'on' ) { + add_action( 'transition_post_status', array( __CLASS__, 'send_email_when_publish_property') , 10, 3 ); + add_action( 'opalestate_processed_approve_publish_property', array( __CLASS__, 'approve_publish_property_email') , 10, 1 ); + } + + /** + * Send email when User contact via Enquiry Form and Contact Form + */ + add_action( 'opalestate_send_email_notifycation', array(__CLASS__,'send_notifycation') ); + add_action( 'opalestate_send_email_submitted', array(__CLASS__,'new_submission_email') ); + add_action( 'opalestate_send_email_request_reviewing', array( __CLASS__, 'send_email_request_reviewing') ); + } + + /** + * + */ + public static function load() { + + require_once OPALESTATE_PLUGIN_DIR . 'inc/email/class-opalestate-abs-email-template.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/email/class-opalestate-email-notifycation.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/email/class-opalestate-request-viewing.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/email/class-opalestate-new-submitted.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/email/class-opalesate-approve.php'; + } + + /** + * Send Email Notifycation with two types: Enquiry or Contact + */ + public static function send_notifycation ( $content ) { + + $mail = new OpalEstate_Send_Email_Notification() ; + $mail->set_args ( $content ); + + $return = self::send_mail_now( $mail ); + + if( isset($content['data']) ){ + $return['data'] = $content['data']; + } + echo json_encode( $return ); die(); + } + + + + /** + * send email if agent submit a new property + */ + public static function new_submission_email( $user_id, $post_id ){ + + $mail = new OpalEstate_Send_Email_New_Submitted() ; + + $mail->set_pros( $post_id, $user_id ); + + $return = self::send_mail_now( $mail ); + + + echo json_encode( $return ); die(); + + } + + /** + * Send email to requet viewing a property + */ + public static function send_email_request_reviewing( $content ){ + + $mail = new OpalEstate_Send_Email_Request_Reviewing(); + $mail->set_args( $content ); + + $return = self::send_mail_now( $mail ); + + + echo json_encode( $return ); die(); + + } + + /** + * + */ + public static function send_mail_now( $mail ){ + + $from_name = $mail->from_name(); + $from_email = $mail->from_email(); + $headers = sprintf( "From: %s <%s>\r\n Content-type: text/html", $from_name, $from_email ); + + $subject = $mail->get_subject(); + $message = $mail->get_body(); + + if( $mail->to_email() ) { + + if( $mail->get_cc() ){ + $status = @wp_mail( $mail->get_cc(), $subject, $message, $headers ); + } + + $status = @wp_mail( $mail->to_email(), $subject, $message, $headers ); + $return = array( 'status' => true, 'msg' => esc_html__( 'Message has been successfully sent.', 'opalestate-pro' ) ); + + } else { + $return = array( 'status' => true, 'msg' => esc_html__( 'Message has been successfully sent.', 'opalestate-pro' ) ); + } + + return $return; + } + + /** + * + */ + public static function send_email_when_publish_property( $new_status, $old_status, $post ) { + + if( is_object( $post ) ){ + if ( $post->post_type == 'opalestate_property' ) { + if ( $new_status != $old_status ) { + if ($new_status == 'publish' ) { + if ($old_status == 'draft' || $old_status == 'pending') { + // Send email + $post_id = $post->ID; + do_action( "opalestate_processed_approve_publish_property", $post_id ); + } + } + } + } + } + + } + + /** + * add new tab Email in opalestate -> setting + */ + public static function setting_email_tab( $tabs ){ + + $tabs['emails'] = esc_html__( 'Email', 'opalestate-pro' ); + return $tabs; + } + + public static function newproperty_email_body(){ + + } + + public static function approve_email_body(){ + + } + + /** + * render setting email fields with default values + */ + public static function setting_email_fields( $fields ){ + + $contact_list_tags = '
            +

            Use the following tags to automatically add property information to the emails. Tags labeled with an asterisk (*) can be used in the email subject as well.

            + +
            + {receive_name} Name of the agent who made the property +
            + +
            + {property_link} Property of the user who made the property +
            + +
            + {name} Name of the user who contact via email form +
            + +
            + {email} Email of the user who contact via email form +
            + +
            + {property_link} * Link of the property +
            + +
            + {message} * Message content of who sent via form +
            + +
            '; + + $list_tags = '
            +

            Use the following tags to automatically add property information to the emails. Tags labeled with an asterisk (*) can be used in the email subject as well.

            + +
            + {property_name} Email of the user who made the property +
            + +
            + {property_link} Email of the user who made the property +
            + +
            + {user_email} Email of the user who made the property +
            + +
            + {submitted_date} Email of the user who made the property +
            + +
            + {user_name} * Name of the user who made the property +
            + +
            + {date} * Date and time of the property +
            + +
            + {site_name} The name of this website +
            +
            + {site_link} A link to this website +
            +
            + {current_time} Current date and time +
            '; + + $list_tags = apply_filters( 'opalestate_email_tags', $list_tags ); + + + $fields = array( + 'id' => 'options_page', + 'title' => esc_html__( 'Email Settings', 'opalestate-pro' ), + 'show_on' => array( 'key' => 'options-page', 'value' => array( 'opalestate_settings' ), ), + 'fields' => apply_filters( 'opalestate_settings_emails', array( + array( + 'name' => esc_html__( 'Email Settings', 'opalestate-pro' ), + 'desc' => '
            ', + 'id' => 'opalestate_title_email_settings_1', + 'type' => 'title' + ), + array( + 'id' => 'from_name', + 'name' => esc_html__( 'From Name', 'opalestate-pro' ), + 'desc' => esc_html__( 'The name donation receipts are said to come from. This should probably be your site or shop name.', 'opalestate-pro' ), + 'default' => get_bloginfo( 'name' ), + 'type' => 'text' + ), + array( + 'id' => 'from_email', + 'name' => esc_html__( 'From Email', 'opalestate-pro' ), + 'desc' => esc_html__( 'Email to send donation receipts from. This will act as the "from" and "reply-to" address.', 'opalestate-pro' ), + 'default' => get_bloginfo( 'admin_email' ), + 'type' => 'text' + ), + + + + array( + 'name' => esc_html__( 'Email Submission Templates (Template Tags)', 'opalestate-pro' ), + 'desc' => $list_tags.'

            ', + 'id' => 'opalestate_title_email_settings_2', + 'type' => 'title' + ), + + + + array( + 'name' => esc_html__( 'Notification For New Property Submission', 'opalestate-pro' ), + 'desc' => '
            ', + 'id' => 'opalestate_title_email_settings_3', + 'type' => 'title' + ), + + + array( + 'id' => 'newproperty_email_subject', + 'name' => esc_html__( 'Email Subject', 'opalestate-pro' ), + 'type' => 'text', + 'desc' => esc_html__( 'The email subject for admin notifications.', 'opalestate-pro' ), + 'attributes' => array( + 'placeholder' => 'Your package is expired', + 'rows' => 3, + ), + 'default' => esc_html__( 'New Property Listing Submitted: {property_name}', 'opalestate-pro' ) + + ), + array( + 'id' => 'newproperty_email_body', + 'name' => esc_html__( 'Email Body', 'opalestate-pro' ), + 'type' => 'wysiwyg', + 'desc' => esc_html__( 'Enter the email an admin should receive when an initial payment request is made.', 'opalestate-pro' ), + 'default' => OpalEstate_Send_Email_New_Submitted::get_default_template(), + ), + //------------------------------------------ + array( + 'name' => esc_html__( 'Approve property for publish', 'opalestate-pro' ), + 'desc' => '
            ', + 'id' => 'opalestate_title_email_settings_4', + 'type' => 'title' + ), + + array( + 'name' => esc_html__( 'Enable approve property email', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable approve property email.', 'opalestate-pro' ), + 'id' => 'enable_approve_property_email', + 'type' => 'switch', + 'options' => array( + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ), + 'default' => 'off', + ), + + array( + 'id' => 'approve_email_subject', + 'name' => esc_html__( 'Email Subject', 'opalestate-pro' ), + 'type' => 'text', + 'desc' => esc_html__( 'The email subject a user should receive when they make an initial property request.', 'opalestate-pro' ), + 'attributes' => array( + 'placeholder' => 'Your property at I Love WordPress is pending',get_bloginfo( 'name' ), + 'rows' => 3, + ), + 'default' => esc_html__( 'New Property Listing Submitted: {property_name}', 'opalestate-pro' ) + ), + + array( + 'id' => 'approve_email_body', + 'name' => esc_html__( 'Email Body', 'opalestate-pro' ), + 'type' => 'wysiwyg', + 'desc' => esc_html__( 'Enter the email a user should receive when they make an initial payment request.', 'opalestate-pro' ), + 'default' => OpalEstate_Send_Email_Approve::get_default_template(), + ), + + /// email contact template //// + array( + 'name' => esc_html__( 'Email Contact Templates (Template Tags)', 'opalestate-pro' ), + 'desc' => $contact_list_tags.'

            ', + 'id' => 'opalestate_title_email_settings_6', + 'type' => 'title' + ), + + array( + 'id' => 'contact_email_subject', + 'name' => esc_html__( 'Email Subject', 'opalestate-pro' ), + 'type' => 'text', + 'desc' => esc_html__( 'The email subject a user should receive when they make an initial property request.', 'opalestate-pro' ), + 'attributes' => array( + 'placeholder' => 'Your property at I Love WordPress is pending',get_bloginfo( 'name' ), + 'rows' => 3, + ), + 'default' => esc_html__('You got a message', 'opalestate-pro') + ), + + array( + 'id' => 'contact_email_body', + 'name' => esc_html__( 'Email Body', 'opalestate-pro' ), + 'type' => 'wysiwyg', + 'desc' => trim(preg_replace('/\t+/', '', "Hi {receive_name},
            + You have got message from {name} with email {email}. Here is detail: +
            +
            + {message} +
            +  
            +
            + This message was sent by {site_link} on {current_time}.")) + ) + ) + ) + ); + + return $fields; + } + + /** + * get data of newrequest email + * + * @var $args array: property_id , $body + * @return text: message + */ + public static function replace_shortcode( $args, $body ) { + + $tags = array( + 'user_name' => "", + 'user_mail' => "", + 'submitted_date' => "", + 'property_name' => "", + 'site_name' => '', + 'site_link' => '', + 'property_link' => '', + ); + $tags = array_merge( $tags, $args ); + + extract( $tags ); + + $tags = array( "{user_mail}", + "{user_name}", + "{submitted_date}", + "{site_name}", + "{site_link}", + "{current_time}", + '{property_name}', + '{property_link}'); + + $values = array( $user_mail, + $user_name , + $submitted_date , + get_bloginfo( 'name' ) , + get_home_url(), + date("F j, Y, g:i a"), + $property_name, + $property_link + ); + + $message = str_replace($tags, $values, $body); + + return $message; + } + + public static function approve_publish_property_email( $post_id ) { + + $mail = new OpalEstate_Send_Email_Approve(); + $mail->set_pros( $post_id ); + + $return = self::send_mail_now( $mail ); + + echo json_encode( $return ); die(); + } + +} + +Opalestate_Emails::init(); \ No newline at end of file diff --git a/inc/class-opalestate-enqueue.php b/inc/class-opalestate-enqueue.php new file mode 100755 index 00000000..5020a829 --- /dev/null +++ b/inc/class-opalestate-enqueue.php @@ -0,0 +1,216 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Enqueue + * + * @version 1.0 + */ +class OpalEstate_Enqueue { + + /** + * Constructor + */ + public function __construct() { + + add_action( 'wp_enqueue_scripts', [ $this, 'load_scripts' ] ); + add_action( 'wp_head', [ $this, 'add_custom_styles' ] ); + } + + /** + * Load javascript and css + */ + public function load_scripts() { + $api = opalestate_get_map_api_uri(); + + wp_enqueue_script( 'opalestate-google-maps', $api, null, '0.0.1', false ); + + wp_enqueue_script( 'infobox', OPALESTATE_PLUGIN_URL . 'assets/js/infobox.js', [ 'jquery' ], OPALESTATE_VERSION, false ); + wp_enqueue_script( 'markerclusterer', OPALESTATE_PLUGIN_URL . 'assets/js/markerclusterer.js', [ 'jquery' ], '1.3', false ); + + wp_enqueue_script( 'opalestate-scripts', OPALESTATE_PLUGIN_URL . 'assets/js/opalestate.js', [ 'jquery' ], OPALESTATE_VERSION, true ); + wp_enqueue_script( 'opalestate-country-select', OPALESTATE_PLUGIN_URL . 'assets/js/country-select.js', [ 'jquery' ], OPALESTATE_VERSION, true ); + wp_enqueue_script( 'noUiSlider', OPALESTATE_PLUGIN_URL . 'assets/js/nouislider.min.js', [ 'jquery' ], '1.0.0', true ); + wp_enqueue_script( 'fitvids', OPALESTATE_PLUGIN_URL . 'assets/js/jquery.fitvids.js', [ 'jquery' ], '1.0.0', true ); + + // load google map for searchable + wp_enqueue_script( 'opalestate-gmap', OPALESTATE_PLUGIN_URL . 'assets/js/frontend/googlemaps.js', [ 'jquery' ], '1.3', false ); + wp_enqueue_script( 'opalestate-messages', OPALESTATE_PLUGIN_URL . 'assets/js/frontend/property.js', [ 'jquery' ], '1.3', false ); + + + wp_enqueue_style( 'opalestate-style', OPALESTATE_PLUGIN_URL . '/assets/opalestate.css' ); + + wp_enqueue_style( 'font-awesome', OPALESTATE_PLUGIN_URL . 'assets/3rd/fontawesome/css/all.min.css', null, '1.3', false ); + + // load tooltips css3 + wp_enqueue_style( 'hint', OPALESTATE_PLUGIN_URL . 'assets/hint.min.css', null, '1.3', false ); + // load tooltips css3 + wp_enqueue_style( 'select2', OPALESTATE_PLUGIN_URL . 'assets/3rd/select2/css/select2.min.css', null, '1.3', false ); + wp_enqueue_script( 'select2', OPALESTATE_PLUGIN_URL . 'assets/3rd/select2/js/select2.min.js', null, '1.3', false ); + + wp_register_script( 'chart-js', OPALESTATE_PLUGIN_URL . 'assets/js/chart.min.js', null, '2.8.0', true ); + wp_register_style( 'tooltipster', OPALESTATE_PLUGIN_URL . 'assets/3rd/tooltipster/css/tooltipster.bundle.min.css', [], false ); + wp_register_script( 'tooltipster', OPALESTATE_PLUGIN_URL . 'assets/3rd/tooltipster/js/tooltipster.bundle.min.js', [ 'jquery' ], false, true ); + + if ( is_single_property() ) { + wp_enqueue_script( 'chart-js' ); + } + + if ( is_single_property() || is_single_agent() || is_single_agency() ) { + wp_enqueue_style( 'tooltipster' ); + wp_enqueue_script( 'tooltipster' ); + } + + // load global variables + wp_localize_script( 'opalestate-scripts', 'opalesateJS', + [ + 'ajaxurl' => admin_url( 'admin-ajax.php' ), + 'siteurl' => get_template_directory_uri(), + 'mapiconurl' => OPALESTATE_PLUGIN_URL . 'assets/map/', + 'rtl' => is_rtl() ? 'true' : 'false', + 'confirmed' => esc_html__( 'Are you sure to remove?', 'opalestate-pro' ), + 'error_upload_size' => esc_html__( 'This file is has large volume size, please try to upload other.', 'opalestate-pro' ), + 'size_image' => opalestate_options( 'upload_image_max_size', 0.5 ) * 1000000, + 'mfile_image' => opalestate_options( 'upload_image_max_files', 10 ), + 'size_other' => opalestate_options( 'upload_other_max_size', 0.8 ) * 1000000, + 'mfile_other' => opalestate_options( 'upload_other_max_files', 10 ), + ] ); + + /// + $this->register_enqueue(); + } + + /** + * Register and enqueue javascript, css library + */ + public function register_enqueue() { + wp_register_script( + 'jquery-modernizr', + OPALESTATE_PLUGIN_URL . '/assets/3rd/magnific-popup/jquery.magnific-popup.min.js', + [ + 'jquery', + ], + '4.4.3', + true + ); + wp_enqueue_script( 'jquery-magnific-popup' ); + wp_register_script( 'jquery-sticky-kit', trailingslashit( OPALESTATE_PLUGIN_URL ) . 'assets/3rd/sticky/jquery.sticky-kit.min.js', [], null, true ); + wp_enqueue_script( 'jquery-sticky-kit' ); + wp_enqueue_script( 'opalestate-elementor', OPALESTATE_PLUGIN_URL . 'assets/js/frontend/elementor.js', [], null, true ); + wp_enqueue_script( 'jquery-ui-datepicker' ); + wp_enqueue_style( 'jquery-ui-datepicker-style', OPALESTATE_PLUGIN_URL . '/assets/3rd/datepicker.css' ); + /// + wp_register_script( 'jquery-toast', + OPALESTATE_PLUGIN_URL . 'assets/3rd/toast/jquery.toast.js', [], null, true ); + + wp_enqueue_script( 'jquery-toast' ); + + wp_register_script( + 'jquery-swiper', + OPALESTATE_PLUGIN_URL . '/assets/3rd/swiper/js/swiper.min.js', + [ + 'jquery', + ], + '4.4.3', + true + ); + + wp_enqueue_script( 'jquery-swiper' ); + } + + /** + * Add custom styles. + */ + public function add_custom_styles() { + $custom = ''; + $status_color = $this->add_custom_property_status_color(); + if ( $status_color ) { + $custom .= $status_color; + } + + $label_color = $this->add_custom_property_label_color(); + if ( $label_color ) { + $custom .= $label_color; + } + + if ( $custom ) { + echo ''; + } + } + + /** + * Add custom property status color. + * + * @return string + */ + public function add_custom_property_status_color() { + $statuses = Opalestate_Taxonomy_Status::get_list(); + $custom = ''; + + if ( $statuses ) { + foreach ( $statuses as $status ) { + $bg = get_term_meta( $status->term_id, 'opalestate_status_lb_bg', true ); + $color = get_term_meta( $status->term_id, 'opalestate_status_lb_color', true ); + if ( $bg || $color ) { + $custom .= '.property-status-' . trim( $status->slug ) . ' { '; + if ( $bg ) { + $custom .= 'background-color:' . $bg . ' !important;'; + } + if ( $color ) { + $custom .= 'color:' . $color . '!important'; + } + $custom .= ' } '; + } + } + } + + return $custom; + } + + /** + * Add custom property status color. + * + * @return string + */ + public function add_custom_property_label_color() { + $labels = Opalestate_Taxonomy_Label::get_list(); + $custom = ''; + + if ( $labels ) { + foreach ( $labels as $label ) { + $bg = get_term_meta( $label->term_id, 'opalestate_label_lb_bg', true ); + $color = get_term_meta( $label->term_id, 'opalestate_label_lb_color', true ); + if ( $bg || $color ) { + $custom .= '.property-label-' . trim( $label->slug ) . ' { '; + if ( $bg ) { + $custom .= 'background-color:' . $bg . ' !important;'; + } + if ( $color ) { + $custom .= 'color:' . $color . '!important'; + } + $custom .= ' } '; + } + } + } + + return $custom; + } + +} + +new OpalEstate_Enqueue(); diff --git a/inc/class-opalestate-html.php b/inc/class-opalestate-html.php new file mode 100755 index 00000000..5762c372 --- /dev/null +++ b/inc/class-opalestate-html.php @@ -0,0 +1,395 @@ + 'user_id', + 'value' => isset( $args['default'] ) ? $args['default'] : null, + 'placeholder' => esc_html__( 'Enter username', 'opalestate-pro' ), + 'label' => null, + 'desc' => null, + 'class' => '', + 'disabled' => false, + 'autocomplete' => 'off', + 'data' => false, + ]; + + $args = wp_parse_args( $args, $defaults ); + + $args['class'] = 'opalestate-ajax-user-search ' . $args['class']; + + $output = ''; + $output .= $this->text_field( $args ); + $output .= ''; + $output .= ''; + + return $output; + } + + /** + * Text Field + * + * Renders an HTML Text field. + * + * @param array $args Arguments for the text field. + * + * @return string The text field. + * @since 1.0 + * @access public + * + */ + public function text_field( $field_args, $args = [] ) { + + + $defaults = [ + 'id' => '', + 'value' => isset( $field_args['default'] ) ? $field_args['default'] : null, + 'name' => '', + 'description' => null, + 'placeholder' => '', + 'class' => 'regular-text form-control', + 'disabled' => false, + 'autocomplete' => 'off', + 'data' => false, + 'default' => '', + 'required' => false, + ]; + + $args = wp_parse_args( $field_args, $defaults ); + + $disabled = ''; + if ( $args['disabled'] ) { + $disabled = ' disabled="disabled"'; + } + + $data = ''; + if ( ! empty( $args['data'] ) ) { + foreach ( $args['data'] as $key => $value ) { + $data .= 'data-' . $key . '="' . $value . '" '; + } + } + + if ( $args['required'] ) { + $data .= ' required="required" '; + } + + $output = ''; + + $output .= ''; + + + $output .= ''; + + if ( ! empty( $args['description'] ) ) { + $output .= '' . esc_html( $args['description'] ) . ''; + } + + $output .= ''; + + return $output; + } + + /** + * Date Picker + * + * Renders a date picker field. + * + * @param array $args Arguments for the date picker. + * + * @return string The date picker. + * @since 1.5 + * @access public + * + */ + public function date_field( $args = [] ) { + + if ( empty( $args['class'] ) ) { + $args['class'] = 'opalestate-datepicker form-control'; + } elseif ( ! strpos( $args['class'], 'opalestate-datepicker' ) ) { + $args['class'] .= ' opalestate-datepicker form-control'; + } + + return $this->text_field( $args ); + } + + /** + * Textarea + * + * Renders an HTML textarea. + * + * @param array $args Arguments for the textarea. + * + * @return string The textarea. + * @since 1.0 + * @access public + * + */ + public function textarea_field( $args = [] ) { + $defaults = [ + 'name' => '', + 'value' => isset( $args['default'] ) ? $args['default'] : null, + 'label' => null, + 'description' => null, + 'class' => 'large-text', + 'disabled' => false, + ]; + + $args = wp_parse_args( $args, $defaults ); + + $disabled = ''; + if ( $args['disabled'] ) { + $disabled = ' disabled="disabled"'; + } + + $output = ''; + + $output .= ''; + + $data = ''; + if ( $args['required'] ) { + $data .= ' required="required" '; + } + + $output .= ''; + + if ( ! empty( $args['description'] ) ) { + $output .= '' . esc_html( $args['description'] ) . ''; + } + + $output .= ''; + + return $output; + } + + /** + * Dropdown + * + * Renders an HTML Dropdown. + * + * @param array $args Arguments for the dropdown. + * + * @return string The dropdown. + * @since 1.0 + * @access public + * + */ + public function select_field( $field_args = [] ) { + $defaults = [ + 'options' => [], + 'name' => null, + 'class' => 'form-control', + 'id' => '', + 'autocomplete' => 'off', + 'selected' => 0, + 'chosen' => false, + 'placeholder' => null, + 'multiple' => false, + 'select_atts' => false, + 'show_option_all' => esc_html__( 'All', 'opalestate-pro' ), + 'show_option_none' => esc_html__( 'None', 'opalestate-pro' ), + 'data' => [], + 'readonly' => false, + 'disabled' => false, + 'required' => '', + ]; + + $args = wp_parse_args( $field_args, $defaults ); + + $data_elements = ''; + foreach ( $args['data'] as $key => $value ) { + $data_elements .= ' data-' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"'; + } + + $multiple = ''; + if ( $args['multiple'] ) { + $multiple = 'MULTIPLE'; + } + + if ( $args['chosen'] ) { + $args['class'] .= ' opalestate-select-chosen'; + } + + $placeholder = ''; + if ( $args['placeholder'] ) { + $placeholder = $args['placeholder']; + } + + $output = ''; + + $data = ''; + if ( $args['required'] ) { + $data .= ' required="required" '; + } + + $output .= sprintf( + ''; + + return $output; + } + + public function hidden_field( $args ) { + $defaults = [ + 'id' => '', + 'value' => isset( $args['default'] ) ? $args['default'] : null, + 'name' => '', + 'description' => null, + 'placeholder' => '', + 'class' => 'regular-text form-control', + 'disabled' => false, + 'autocomplete' => 'off', + 'data' => false, + 'default' => '', + 'required' => false, + ]; + $args = wp_parse_args( $args, $defaults ); + + $output = ''; + + return $output; + } + + public function render_field( $field ) { + switch ( $field['type'] ) { + case 'date': + + return $this->date_field( $field ); + + break; + + case 'text': + + return $this->text_field( $field ); + + break; + case 'hidden': + + return $this->hidden_field( $field ); + + break; + + case 'textarea': + + return $this->textarea_field( $field ); + + break; + case 'user': + + return $this->ajax_user_search( $field ); + + break; + + case 'select': + return $this->select_field( $field ); + break; + default: + # code... + break; + } + } + + public function render_form( $fields ) { + static $id_counter = 0; + if ( function_exists( 'wp_unique_id' ) ) { + $form_id = wp_unique_id( 'opalestate-form-' ); + } else { + $form_id = 'opalestate-form-' . (string) ++$id_counter; + } + + $output = ''; + $this->form_id = $form_id; + foreach ( $fields as $field ) { + $wrap = ''; + if ( isset( $field['before_row'] ) ) { + $wrap .= $field['before_row']; + } + $wrap .= '
            '; + $wrap .= $this->render_field( $field ); + $wrap .= '
            '; + + if ( isset( $field['after_row'] ) ) { + $wrap .= $field['after_row']; + } + + $output .= $wrap; + } + + return $output; + } +} diff --git a/inc/class-opalestate-install.php b/inc/class-opalestate-install.php new file mode 100755 index 00000000..6109c52f --- /dev/null +++ b/inc/class-opalestate-install.php @@ -0,0 +1,252 @@ +add_roles(); + $roles->add_caps(); + } + + /** + * Default options. + * + * Sets up the default options used on the settings page. + */ + private static function create_options() { + global $opalestate_options; + + // Add Upgraded From Option + $current_version = get_option( 'opalestate_version' ); + if ( $current_version ) { + update_option( 'opalestate_version_upgraded_from', $current_version ); + } + + // Setup some default options + $options = []; + + //Fresh Install? Setup Test Mode, Base Country (US), Test Gateway, Currency + if ( empty( $current_version ) ) { + $options['test_mode'] = 1; + $options['currency'] = 'USD'; + $options['currency_position'] = 'before'; + $options['measurement_unit'] = 'sq ft'; + $options['google_map_api_keys'] = 'AIzaSyCfMVNIa7khIqYHCw6VBn8ShUWWm4tjbG8'; + $options['admin_approve'] = 'on'; + $options['require_input_price'] = 'on'; + $options['from_name'] = get_bloginfo( 'name' ); + $options['from_email'] = get_bloginfo( 'admin_email' ); + $options['message_log'] = 1; + + $options[ OPALESTATE_PROPERTY_PREFIX . 'bedrooms_opt' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'parking_opt' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'bathrooms_opt' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'areasize_opt' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'price_opt' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'bedrooms_opt_v' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'parking_opt_v' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'bathrooms_opt_v' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'areasize_opt_v' ] = 1; + $options[ OPALESTATE_PROPERTY_PREFIX . 'price_opt_v' ] = 1; + + $options['enable_single_amenities'] = 'on'; + $options['enable_single_facilities'] = 'on'; + $options['enable_single_attachments'] = 'on'; + $options['enable_single_video'] = 'on'; + $options['enable_single_map'] = 'on'; + $options['enable_single_nearby'] = 'on'; + $options['enable_single_walkscores'] = 'on'; + $options['enable_single_apartments'] = 'on'; + $options['enable_single_floor_plans'] = 'on'; + $options['enable_single_views_statistics'] = 'on'; + $options['single_views_statistics_limit'] = 8; + + $options['enable_property_reviews'] = 'on'; + $options['enable_agency_reviews'] = 'on'; + $options['enable_agent_reviews'] = 'on'; + + $options['enable_submission_tab_media'] = 'on'; + $options['enable_submission_tab_location'] = 'on'; + $options['enable_submission_tab_amenities'] = 'on'; + $options['enable_submission_tab_facilities'] = 'on'; + $options['enable_submission_tab_apartments'] = 'on'; + $options['enable_submission_tab_floor_plans'] = 'on'; + + } + + // Checks if the Success Page option exists AND that the page exists + if ( ! get_post( opalestate_get_option( 'user_management_page' ) ) ) { + // Purchase Confirmation (Success) Page + $profile_page = wp_insert_post( + [ + 'post_title' => esc_html__( 'User Dashboard Page', 'opalestate-pro' ), + 'post_content' => esc_html__( '', 'opalestate-pro' ), + 'post_status' => 'publish', + 'post_author' => 1, + 'post_type' => 'page', + 'comment_status' => 'closed', + 'page_template' => 'user-management.php', + ] + ); + + // Store our page IDs + $options['user_management_page'] = $profile_page; + } + + // Checks if the Success Page option exists AND that the page exists + if ( ! get_post( opalestate_get_option( 'user_myaccount_page' ) ) ) { + $saved_link_page = wp_insert_post( + [ + 'post_title' => esc_html__( 'My Account', 'opalestate-pro' ), + 'post_content' => esc_html__( '[opalestate_myaccount]', 'opalestate-pro' ), + 'post_status' => 'publish', + 'post_author' => 1, + 'post_type' => 'page', + 'comment_status' => 'closed', + ] + ); + + // Store our page IDs + $options['user_myaccount_page'] = $saved_link_page; + } + + // Checks if the Success Page option exists AND that the page exists + if ( ! get_post( opalestate_get_option( 'submission_page' ) ) ) { + // Purchase Confirmation (Success) Page + $submission_page = wp_insert_post( + [ + 'post_title' => esc_html__( 'Property Submission Page', 'opalestate-pro' ), + 'post_content' => esc_html__( '[opalestate_submission]', 'opalestate-pro' ), + 'post_status' => 'publish', + 'post_author' => 1, + 'post_type' => 'page', + 'comment_status' => 'closed', + ] + ); + + // Store our page IDs + $options['submission_page'] = $submission_page; + } + + // Checks if the Success Page option exists AND that the page exists + if ( ! get_post( opalestate_get_option( 'search_map_properties_page' ) ) ) { + // Purchase Confirmation (Success) Page + $search_map_properties_page = wp_insert_post( + [ + 'post_title' => esc_html__( 'Search Map Properties Page', 'opalestate-pro' ), + 'post_content' => esc_html__( '[opalestate_search_map_properties]', 'opalestate-pro' ), + 'post_status' => 'publish', + 'post_author' => 1, + 'post_type' => 'page', + 'comment_status' => 'closed', + 'page_template' => 'fullwidth-page.php', + ] + ); + + // Store our page IDs + $options['search_map_properties_page'] = $search_map_properties_page; + } + + // Populate some default values + update_option( 'opalestate_settings', array_merge( $opalestate_options, $options ) ); + + // Add a temporary option to note that Give pages have been created + set_transient( '_opalestate_installed', $options, 30 ); + } + + /** + * Update Opalestate version to current. + */ + private static function update_opalestate_version() { + update_option( 'opalestate_version', OPALESTATE_VERSION ); + } +} + +/** + * Install user roles on sub-sites of a network + * + * Roles do not get created when Give is network activation so we need to create them during admin_init + * + * @return void + * @since 1.0 + */ +function opalestate_install_roles_on_network() { + global $wp_roles; + + if ( ! is_object( $wp_roles ) ) { + return; + } + + if ( ! array_key_exists( 'opalestate_manager', $wp_roles->roles ) ) { + $roles = new Opalestate_Roles; + $roles->add_roles(); + $roles->add_caps(); + } else { + // remove_role( 'opalestate_manager' ); + // remove_role( 'opalestate_manager' ); + // $roles = new Opalestate_Roles; + // $roles->remove_caps(); + } +} + +add_action( 'admin_init', 'opalestate_install_roles_on_network' ); diff --git a/inc/class-opalestate-roles.php b/inc/class-opalestate-roles.php new file mode 100755 index 00000000..f755ec07 --- /dev/null +++ b/inc/class-opalestate-roles.php @@ -0,0 +1,273 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * Opalestate_Roles Class + * + * This class handles the role creation and assignment of capabilities for those roles. + * + * These roles let us have Opalestate Accountants, Opalestate Workers, etc, each of whom can do + * certain things within the plugin + * + * @since 1.0.0 + */ +class Opalestate_Roles { + + /** + * Get things going + * + * @since 1.0.0 + */ + public function __construct() { + + add_filter( 'opalestate_map_meta_cap', array( $this, 'meta_caps' ), 10, 4 ); + } + + /** + * Add new shop roles with default WP caps + * + * @access public + * @since 1.0.0 + * @return void + */ + public function add_roles() { + add_role( 'opalestate_manager', esc_html__( 'Opal Estate Manager', 'opalestate-pro' ), array( + 'read' => true, + 'edit_posts' => true, + 'delete_posts' => true, + 'unfiltered_html' => true, + 'upload_files' => true, + 'export' => true, + 'import' => true, + 'delete_others_pages' => true, + 'delete_others_posts' => true, + 'delete_pages' => true, + 'delete_private_pages' => true, + 'delete_private_posts' => true, + 'delete_published_pages' => true, + 'delete_published_posts' => true, + 'edit_others_pages' => true, + 'edit_others_posts' => true, + 'edit_pages' => true, + 'edit_private_pages' => true, + 'edit_private_posts' => true, + 'edit_published_pages' => true, + 'edit_published_posts' => true, + 'manage_categories' => true, + 'manage_links' => true, + 'moderate_comments' => true, + 'publish_pages' => true, + 'publish_posts' => true, + 'read_private_pages' => true, + 'read_private_posts' => true + ) ); + + add_role( 'opalestate_agent', esc_html__( 'Opal Estate Agent', 'opalestate-pro' ), array( + 'read' => true, + 'edit_posts' => false, + 'upload_files' => true, + 'delete_posts' => false, + 'publish_posts' => false, + 'upload_files' =>true, + 'edit_attachments' =>true, + 'delete_attachments' =>true, + 'delete_post' => true, + ) ); + + add_role( 'opalestate_agency', esc_html__( 'Opal Estate Agency', 'opalestate-pro' ), array( + 'read' => true, + 'edit_posts' => false, + 'upload_files' => true, + 'delete_posts' => false, + 'publish_posts' => false, + ) ); + + } + + /** + * Add new shop-specific capabilities + * + * @access public + * @since 1.0.0 + * @global WP_Roles $wp_roles + * @return void + */ + public function add_caps() { + global $wp_roles; + + if ( class_exists('WP_Roles') ) { + if ( ! isset( $wp_roles ) ) { + $wp_roles = new WP_Roles(); + } + } + + if ( is_object( $wp_roles ) ) { + $wp_roles->add_cap( 'opalestate_manager', 'view_opalestate_reports' ); + $wp_roles->add_cap( 'opalestate_manager', 'view_opalestate_sensitive_data' ); + $wp_roles->add_cap( 'opalestate_manager', 'export_opalestate_reports' ); + $wp_roles->add_cap( 'opalestate_manager', 'manage_opalestate_settings' ); + + $wp_roles->add_cap( 'administrator', 'view_opalestate_reports' ); + $wp_roles->add_cap( 'administrator', 'view_opalestate_sensitive_data' ); + $wp_roles->add_cap( 'administrator', 'export_opalestate_reports' ); + $wp_roles->add_cap( 'administrator', 'manage_opalestate_settings' ); + + // Add the main post type capabilities + $capabilities = $this->get_core_caps(); + foreach ( $capabilities as $cap_group ) { + foreach ( $cap_group as $cap ) { + $wp_roles->add_cap( 'opalestate_manager', $cap ); + $wp_roles->add_cap( 'administrator', $cap ); + $wp_roles->add_cap( 'opalestate_agent', $cap ); + } + } + + $wp_roles->add_cap( 'opalestate_accountant', 'edit_opalestate_properties' ); + $wp_roles->add_cap( 'opalestate_accountant', 'read_private_forms' ); + $wp_roles->add_cap( 'opalestate_accountant', 'view_opalestate_reports' ); + $wp_roles->add_cap( 'opalestate_accountant', 'export_opalestate_reports' ); + $wp_roles->add_cap( 'opalestate_accountant', 'edit_opalestate_payments' ); + + } + } + + /** + * Gets the core post type capabilities + * + * @access public + * @since 1.0.0 + * @return array $capabilities Core post type capabilities + */ + public function get_core_caps() { + $capabilities = array(); + + $capability_types = array( 'opalestate_properties', 'opalestate_agents' ); + + foreach ( $capability_types as $capability_type ) { + $capabilities[ $capability_type ] = array( + // Post type + "edit_{$capability_type}", + "read_{$capability_type}", + "delete_{$capability_type}", + "edit_{$capability_type}s", + "edit_others_{$capability_type}s", + "publish_{$capability_type}s", + "read_private_{$capability_type}s", + "delete_{$capability_type}s", + "delete_private_{$capability_type}s", + "delete_published_{$capability_type}s", + "delete_others_{$capability_type}s", + "edit_private_{$capability_type}s", + "edit_published_{$capability_type}s", + + // Terms + "manage_{$capability_type}_terms", + "edit_{$capability_type}_terms", + "delete_{$capability_type}_terms", + "assign_{$capability_type}_terms", + + // Custom + "view_{$capability_type}_stats" + ); + } + + return $capabilities; + } + + /** + * Map meta caps to primitive caps + * + * @access public + * @since 2.0 + * @return array $caps + */ + public function meta_caps( $caps, $cap, $user_id, $args ) { + + switch( $cap ) { + + case 'view_opalestate_properties_stats' : + + if( empty( $args[0] ) ) { + break; + } + + $form = get_post( $args[0] ); + if ( empty( $form ) ) { + break; + } + + if( user_can( $user_id, 'view_opalestate_reports' ) || $user_id == $form->post_author ) { + $caps = array(); + } + + break; + } + + return $caps; + + } + + /** + * Remove core post type capabilities (called on uninstall) + * + * @access public + * @since 1.0 + * @return void + */ + public function remove_caps() { + + global $wp_roles; + + if ( class_exists( 'WP_Roles' ) ) { + if ( ! isset( $wp_roles ) ) { + $wp_roles = new WP_Roles(); + } + } + + if ( is_object( $wp_roles ) ) { + /** Opalestate Manager Capabilities */ + $wp_roles->remove_cap( 'opalestate_manager', 'view_opalestate_reports' ); + $wp_roles->remove_cap( 'opalestate_manager', 'view_opalestate_sensitive_data' ); + $wp_roles->remove_cap( 'opalestate_manager', 'export_opalestate_reports' ); + $wp_roles->remove_cap( 'opalestate_manager', 'manage_opalestate_settings' ); + + /** Site Administrator Capabilities */ + $wp_roles->remove_cap( 'administrator', 'view_opalestate_reports' ); + $wp_roles->remove_cap( 'administrator', 'view_opalestate_sensitive_data' ); + $wp_roles->remove_cap( 'administrator', 'export_opalestate_reports' ); + $wp_roles->remove_cap( 'administrator', 'manage_opalestate_settings' ); + + /** Remove the Main Post Type Capabilities */ + $capabilities = $this->get_core_caps(); + + foreach ( $capabilities as $cap_group ) { + foreach ( $cap_group as $cap ) { + $wp_roles->remove_cap( 'opalestate_manager', $cap ); + $wp_roles->remove_cap( 'administrator', $cap ); + $wp_roles->remove_cap( 'opalestate_agent', $cap ); + } + } + + /** Shop Accountant Capabilities */ + $wp_roles->remove_cap( 'opalestate_accountant', 'edit_opalestate_properties' ); + $wp_roles->remove_cap( 'opalestate_accountant', 'read_private_forms' ); + $wp_roles->remove_cap( 'opalestate_accountant', 'view_opalestate_reports' ); + $wp_roles->remove_cap( 'opalestate_accountant', 'export_opalestate_reports' ); + } + } +} \ No newline at end of file diff --git a/inc/class-template-loader.php b/inc/class-template-loader.php new file mode 100755 index 00000000..56d82487 --- /dev/null +++ b/inc/class-template-loader.php @@ -0,0 +1,142 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Template_Loader { + + /** + * Initialize template loader + * + * @access public + * @return void + */ + public static function init() { + add_filter( 'template_include', [ __CLASS__, 'templates' ] ); + } + + /** + * Default templates + * + * @access public + * @param $template + * @return string + * @throws Exception + */ + public static function templates( $template ) { + $post_type = get_post_type(); + $custom_post_types = [ 'opalestate_property', 'opalestate_agent', 'opalestate_agency' ]; + + if ( in_array( $post_type, $custom_post_types ) ) { + + + if ( is_tax( 'opalestate_agency' ) ) { + return self::locate( 'single-opalestate_agency' ); + } + + if ( is_archive() ) { + return self::locate( 'archive-' . $post_type ); + } + + if ( is_single() ) { + return self::locate( 'single-' . $post_type ); + } + } + + if ( is_post_type_archive( 'opalestate_agency' ) ) { + return self::locate( 'archive-opalestate_agency' ); + } + + if ( is_post_type_archive( 'opalestate_agent' ) ) { + return self::locate( 'archive-opalestate_agent' ); + } + + return $template; + } + + /** + * Gets template path + * + * @access public + * @param $name + * @param $plugin_dir + * @return string + * @throws Exception + */ + public static function locate( $name, $plugin_dir = OPALESTATE_PLUGIN_DIR, $warning = true ) { + $template = ''; + + // Current theme base dir + if ( ! empty( $name ) ) { + $template = locate_template( "{$name}.php" ); + } + + // Child theme + if ( ! $template && ! empty( $name ) && file_exists( get_stylesheet_directory() . "/opalestate/{$name}.php" ) ) { + $template = get_stylesheet_directory() . "/opalestate/{$name}.php"; + } + + // Original theme + if ( ! $template && ! empty( $name ) && file_exists( get_template_directory() . "/opalestate/{$name}.php" ) ) { + $template = get_template_directory() . "/opalestate/{$name}.php"; + } + + // Plugin + if ( ! $template && ! empty( $name ) && file_exists( $plugin_dir . "/templates/{$name}.php" ) ) { + $template = $plugin_dir . "/templates/{$name}.php"; + } + + // Nothing found + if ( empty( $template ) && $warning ) { + throw new Exception( "Template /templates/{$name}.php in plugin dir {$plugin_dir} not found." ); + } + + return $template; + } + + + /** + * Loads template content + * + * @param string $name + * @param array $args + * @param string $plugin_dir + * @return string + * @throws Exception + */ + public static function get_template_part( $name, $args = [], $slug = null ) { + if ( is_array( $args ) && count( $args ) > 0 ) { + extract( $args, EXTR_SKIP ); + } + + if ( $slug ) { + $path = self::locate( $name . '-' . $slug, OPALESTATE_PLUGIN_DIR, false ); + if ( empty( $path ) ) { + $path = self::locate( $name, OPALESTATE_PLUGIN_DIR ); + } + } else { + $path = self::locate( $name, OPALESTATE_PLUGIN_DIR ); + } + + ob_start(); + include $path; + $result = ob_get_contents(); + ob_end_clean(); + + return $result; + } +} + +Opalestate_Template_Loader::init(); diff --git a/inc/classes/class-opalestate-abs-query.php b/inc/classes/class-opalestate-abs-query.php new file mode 100755 index 00000000..7b006347 --- /dev/null +++ b/inc/classes/class-opalestate-abs-query.php @@ -0,0 +1,141 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Agent + * + * @version 1.0 + */ +class OpalEstate_Abstract_Query{ + + /** + * Preserve args + * + * @since $id + * @access public + * + * @var string + */ + public $group; + + /** + * Preserve args + * + * @since $id + * @access public + * + * @var array + */ + public $_args = array(); + + /** + * The args to pass to the give_get_payments() query + * + * @since $id + * @access public + * + * @var array + */ + public $args = array(); + + /** + * The collection found based on the criteria set + * + * @since $id + * @access public + * + * @var array + */ + public $collection = array(); + + public function set_filters() { + } + + public function unset_filters() { + } + + + public function get_list(){ + + } + + public function status() { + } + + public function page() { + } + + /** + * Posts Per Page + * + * @since 1.0 + * @access public + * + * @return void + */ + public function per_page() { + } + + /** + * Order by + * + * @since 1.0 + * @access public + * + * @return void + */ + public function orderby() { + } + + public function get_by_user() { + + } + + public function search () { + + } + + /** + * Set a query variable. + * + * @since 1.0 + * @access public + * + * @param $query_var + * @param $value + */ + public function __set( $query_var, $value ) { + if ( in_array( $query_var, array( 'meta_query', 'tax_query' ) ) ) { + $this->args[ $query_var ][] = $value; + } else { + $this->args[ $query_var ] = $value; + } + } + + /** + * Unset a query variable. + * + * @since 1.0 + * @access public + * + * @param $query_var + */ + public function __unset( $query_var ) { + unset( $this->args[ $query_var ] ); + } +} \ No newline at end of file diff --git a/inc/classes/class-opalestate-cache.php b/inc/classes/class-opalestate-cache.php new file mode 100755 index 00000000..786ee4f4 --- /dev/null +++ b/inc/classes/class-opalestate-cache.php @@ -0,0 +1,686 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +class Opalestate_Cache { + + /** + * Instance. + * + * @since 1.8.7 + * @access private + * @var Opalestate_Cache + */ + static private $instance; + + /** + * Flag to check if caching enabled or not. + * + * @since 2.0 + * @access private + * @var + */ + private $is_cache; + + /** + * Singleton pattern. + * + * @since 1.8.7 + * @access private + * Opalestate_Cache constructor. + */ + private function __construct() { + } + + + /** + * Get instance. + * + * @since 1.8.7 + * @access public + * @return static + */ + public static function get_instance() { + if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Opalestate_Cache ) ) { + self::$instance = new Opalestate_Cache(); + } + + return self::$instance; + } + + /** + * Setup hooks. + * + * @since 1.8.7 + * @access public + */ + public function setup() { + // Currently enable cache only for backend. + self::$instance->is_cache = ( defined( 'GIVE_CACHE' ) ? GIVE_CACHE : opalestate_is_setting_enabled( opalestate_get_option( 'cache', 'enabled' ) ) ) && is_admin(); + + // weekly delete all expired cache. + Give_Cron::add_weekly_event( array( $this, 'delete_all_expired' ) ); + + add_action( 'save_post_opalestate_forms', array( $this, 'delete_form_related_cache' ) ); + add_action( 'save_post_opalestate_payment', array( $this, 'delete_payment_related_cache' ) ); + add_action( 'opalestate_deleted_opalestate-donors_cache', array( $this, 'delete_donor_related_cache' ), 10, 3 ); + add_action( 'opalestate_deleted_opalestate-donations_cache', array( $this, 'delete_donations_related_cache' ), 10, 3 ); + + add_action( 'opalestate_save_settings_opalestate_settings', array( __CLASS__, 'flush_cache' ) ); + + add_action( 'wp', array( __CLASS__, 'prevent_caching' ) ); + add_action( 'admin_notices', array( $this, '__notices' ) ); + } + + /** + * Prevent caching on certain pages + * + * @since 2.0.5 + * @access public + * @credit WooCommerce + */ + public static function prevent_caching() { + if ( ! is_blog_installed() ) { + return; + } + + $page_ids = array_filter( array( + opalestate_get_option( 'success_page' ), + opalestate_get_option( 'failure_page' ), + opalestate_get_option( 'history_page' ), + ) ); + + if ( + is_page( $page_ids ) + || is_singular( 'opalestate_forms' ) + ) { + self::set_nocache_constants(); + nocache_headers(); + } + } + + /** + * Set constants to prevent caching by some plugins. + * + * @since 2.0.5 + * @access public + * @credit WooCommerce + * + * @param mixed $return Value to return. Previously hooked into a filter. + * + * @return mixed + */ + public static function set_nocache_constants( $return = true ) { + + return $return; + } + + /** + * Notices function. + * + * @since 2.0.5 + * @access public + * @credit WooCommerce + */ + public function __notices() { + if ( ! function_exists( 'w3tc_pgcache_flush' ) || ! function_exists( 'w3_instance' ) ) { + return; + } + + $config = w3_instance( 'W3_Config' ); + $enabled = $config->get_integer( 'dbcache.enabled' ); + $settings = array_map( 'trim', $config->get_array( 'dbcache.reject.sql' ) ); + + if ( $enabled && ! in_array( 'opalestate-pro', $settings, true ) ) { + ?> +
            +

            database caching to work with Give you must add %1$s to the "Ignored query stems" option in W3 Total Cache settings.', 'opalestate-pro' ), 'opalestate', esc_url( admin_url( 'admin.php?page=w3tc_dbcache#dbcache_reject_sql' ) ) ) ); ?>

            +
            + $data, + 'expiration' => ! is_null( $expiration ) + ? ( $expiration + current_time( 'timestamp', 1 ) ) + : null, + ); + + $result = update_option( $cache_key, $option_value, false ); + + return $result; + } + + /** + * Delete cache. + * + * Note: only for internal use + * + * @since 1.8.7 + * + * @param string|array $cache_keys + * + * @return bool|WP_Error + */ + public static function delete( $cache_keys ) { + $result = true; + $invalid_keys = array(); + + if ( ! empty( $cache_keys ) ) { + $cache_keys = is_array( $cache_keys ) ? $cache_keys : array( $cache_keys ); + + foreach ( $cache_keys as $cache_key ) { + if ( ! self::is_valid_cache_key( $cache_key ) ) { + $invalid_keys[] = $cache_key; + $result = false; + } + + delete_option( $cache_key ); + } + } + + if ( ! $result ) { + $result = new WP_Error( + 'opalestate_invalid_cache_key', + __( 'Cache key format should be opalestate_cache_*', 'opalestate-pro' ), + $invalid_keys + ); + } + + return $result; + } + + /** + * Delete all logging cache. + * + * Note: only for internal use + * + * @since 1.8.7 + * @access public + * @global wpdb $wpdb + * + * @param bool $force If set to true then all cached values will be delete instead of only expired + * + * @return bool + */ + public static function delete_all_expired( $force = false ) { + global $wpdb; + $options = $wpdb->get_results( + $wpdb->prepare( + "SELECT option_name, option_value + FROM {$wpdb->options} + Where option_name + LIKE '%%%s%%'", + 'opalestate_cache' + ), + ARRAY_A + ); + + // Bailout. + if ( empty( $options ) ) { + return false; + } + + $current_time = current_time( 'timestamp', 1 ); + + // Delete log cache. + foreach ( $options as $option ) { + $option['option_value'] = maybe_unserialize( $option['option_value'] ); + + if ( + ( + ! self::is_valid_cache_key( $option['option_name'] ) + || ! is_array( $option['option_value'] ) // Backward compatibility (<1.8.7). + || ! array_key_exists( 'expiration', $option['option_value'] ) // Backward compatibility (<1.8.7). + || empty( $option['option_value']['expiration'] ) + || ( $current_time < $option['option_value']['expiration'] ) + ) + && ! $force + ) { + continue; + } + + self::delete( $option['option_name'] ); + } + } + + + /** + * Get list of options like. + * + * Note: only for internal use + * + * @since 1.8.7 + * @access public + * + * @param string $option_name + * @param bool $fields + * + * @return array + */ + public static function get_options_like( $option_name, $fields = false ) { + global $wpdb; + + $field_names = $fields ? 'option_name, option_value' : 'option_name'; + + if ( $fields ) { + $options = $wpdb->get_results( + $wpdb->prepare( + "SELECT {$field_names } + FROM {$wpdb->options} + Where option_name + LIKE '%%%s%%'", + "opalestate_cache_{$option_name}" + ), + ARRAY_A + ); + } else { + $options = $wpdb->get_col( + $wpdb->prepare( + "SELECT * + FROM {$wpdb->options} + Where option_name + LIKE '%%%s%%'", + "opalestate_cache_{$option_name}" + ), + 1 + ); + } + + if ( ! empty( $options ) && $fields ) { + foreach ( $options as $index => $option ) { + $option['option_value'] = maybe_unserialize( $option['option_value'] ); + $options[ $index ] = $option; + } + } + + return $options; + } + + /** + * Check cache key validity. + * + * @since 1.8.7 + * @access public + * + * @param $cache_key + * + * @return bool + */ + public static function is_valid_cache_key( $cache_key ) { + $is_valid = ( false !== strpos( $cache_key, 'opalestate_cache_' ) ); + + + /** + * Filter the flag which tell about cache key valid or not + * + * @since 2.0 + */ + return apply_filters( 'opalestate_is_valid_cache_key', $is_valid, $cache_key ); + } + + + /** + * Get cache from group + * + * @since 2.0 + * @access public + * + * @param int $id + * @param string $group + * + * @return mixed + */ + public static function get_group( $id, $group = '' ) { + $cached_data = null; + + // Bailout. + if ( self::$instance->is_cache && ! empty( $id ) ) { + $group = self::$instance->filter_group_name( $group ); + + $cached_data = wp_cache_get( $id, $group ); + $cached_data = false !== $cached_data ? $cached_data : null; + } + + return $cached_data; + } + + /** + * Cache small chunks inside group + * + * @since 2.0 + * @access public + * + * @param int $id + * @param mixed $data + * @param string $group + * @param int $expire + * + * @return bool + */ + public static function set_group( $id, $data, $group = '', $expire = 0 ) { + $status = false; + + // Bailout. + if ( ! self::$instance->is_cache || empty( $id ) ) { + return $status; + } + + $group = self::$instance->filter_group_name( $group ); + + $status = wp_cache_set( $id, $data, $group, $expire ); + + return $status; + } + + /** + * Cache small db query chunks inside group + * + * @since 2.0 + * @access public + * + * @param int $id + * @param mixed $data + * + * @return bool + */ + public static function set_db_query( $id, $data ) { + $status = false; + + // Bailout. + if ( ! self::$instance->is_cache || empty( $id ) ) { + return $status; + } + + return self::set_group( $id, $data, 'opalestate-db-queries', 0 ); + } + + /** + * Get cache from group + * + * @since 2.0 + * @access public + * + * @param string $id + * + * @return mixed + */ + public static function get_db_query( $id ) { + return self::get_group( $id, 'opalestate-db-queries' ); + } + + /** + * Delete group cache + * + * @since 2.0 + * @access public + * + * @param int|array $ids + * @param string $group + * @param int $expire + * + * @return bool + */ + public static function delete_group( $ids, $group = '', $expire = 0 ) { + $status = false; + + // Bailout. + if ( ! self::$instance->is_cache || empty( $ids ) ) { + return $status; + } + + $group_prefix = $group; + $group = self::$instance->filter_group_name( $group ); + + // Delete single or multiple cache items from cache. + if ( ! is_array( $ids ) ) { + $status = wp_cache_delete( $ids, $group ); + self::$instance->get_incrementer( true ); + + /** + * Fire action when cache deleted for specific id. + * + * @since 2.0 + * + * @param string $ids + * @param string $group + * @param int $expire + */ + do_action( "opalestate_deleted_{$group_prefix}_cache", $ids, $group, $expire, $status ); + + } else { + foreach ( $ids as $id ) { + $status = wp_cache_delete( $id, $group ); + self::$instance->get_incrementer( true ); + + /** + * Fire action when cache deleted for specific id . + * + * @since 2.0 + * + * @param string $ids + * @param string $group + * @param int $expire + */ + do_action( "opalestate_deleted_{$group_prefix}_cache", $id, $group, $expire, $status ); + } + } + + return $status; + } + + + /** + * Get unique incrementer. + * + * @see https://core.trac.wordpress.org/ticket/4476 + * @see https://www.tollmanz.com/invalidation-schemes/ + * + * @since 2.0 + * @access public + * + * @param bool $refresh + * @param string $incrementer_key + * + * @return string + */ + public function get_incrementer( $refresh = false, $incrementer_key = 'opalestate-cache-incrementer-db-queries' ) { + $incrementer_value = wp_cache_get( $incrementer_key ); + + if ( false === $incrementer_value || true === $refresh ) { + $incrementer_value = (string) microtime( true ); + wp_cache_set( $incrementer_key, $incrementer_value ); + } + + return $incrementer_value; + } + + + /** + * Flush cache on cache setting enable/disable + * Note: only for internal use + * + * @since 2.0 + * @access public + * + * @param bool $force Delete cache forcefully. + * + * @return bool + */ + public static function flush_cache( $force = false ) { + + return false; + } + + + /** + * Filter the group name + * + * @since 2.0 + * @access private + * + * @param $group + * + * @return mixed + */ + private function filter_group_name( $group ) { + /** + * Filter the group name + * + * @since 2.1.0 + */ + $filtered_group = apply_filters( 'opalestate_cache_filter_group_name', '', $group ); + + if ( empty( $filtered_group ) ) { + + switch ( $group ) { + case 'opalestate-db-queries': + $incrementer = self::$instance->get_incrementer(); + break; + + default: + $incrementer = self::$instance->get_incrementer( false, 'opalestate-cache-incrementer' ); + + } + + $current_blog_id = get_current_blog_id(); + $filtered_group = "{$group}_{$current_blog_id}_{$incrementer}"; + } + + return $filtered_group; + } + + + /** + * Disable cache. + * + * @since 2.0 + * @access public + */ + public static function disable() { + self::get_instance()->is_cache = false; + } + + /** + * Enable cache. + * + * @since 2.0 + * @access public + */ + public static function enable() { + self::get_instance()->is_cache = true; + } +} + +// Initialize +Opalestate_Cache::get_instance()->setup(); diff --git a/inc/classes/class-opalestate-geolocation.php b/inc/classes/class-opalestate-geolocation.php new file mode 100755 index 00000000..c33a3b4c --- /dev/null +++ b/inc/classes/class-opalestate-geolocation.php @@ -0,0 +1,111 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +class OpalEstate_GeoLocation { + + /* + * function to geocode address, it will return false if unable to geocode address + */ + public static function get_points_in_miles( $latitude, $longitude, $miles ) { + + $equator = 69.172; + + $maxlat = $latitude + $miles / $EQUATOR_LAT_MILE; + $minlat = $latitude - ($maxlat - $latitude); + $maxlong = $longitude + $miles / (cos($minlat * M_PI / 180) * $equator); + $minlong = $longitude - ($maxlong - $longitude); + + return array( + 'minlat' => $minlat, + 'maxlat' => $maxlat, + 'minlong' => $minlong, + 'maxlong' => $maxlong + ); + } + + /* + * function to geocode address, it will return false if unable to geocode address + */ + public static function calculate( $lat1, $long1, $lat2, $long2 ) { + + $EARTH_RADIUS_MILES = 3963; + $dist = 0; + + //convert degrees to radians + $lat1 = $lat1 * M_PI / 180; + $long1 = $long1 * M_PI / 180; + $lat2 = $lat2 * M_PI / 180; + $long2 = $long2 * M_PI / 180; + + if ($lat1 != $lat2 || $long1 != $long2) { + + $dist = sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($long2 - $long1); + $dist = $EARTH_RADIUS_MILES * (-1 * atan($dist / sqrt(1 - $dist * $dist)) + M_PI / 2); + } + return $dist; + } + + /* + * function to geocode address, it will return false if unable to geocode address + */ + public static function geocode( $address ){ + + // url encode the address + $address = urlencode($address); + + // google map geocode api url + $url = opalestate_get_map_search_api_uri( $address ); + + // get the json response + // $resp_json = file get contents($url); + $resp_json = wp_remote_get($url); + + // decode the json + $resp = json_decode($resp_json, true); + + + // response status will be 'OK', if able to geocode given address + if($resp['status']=='OK'){ + + // get the important data + $lati = isset($resp['results'][0]['geometry']['location']['lat']) ? $resp['results'][0]['geometry']['location']['lat'] : ""; + $longi = isset($resp['results'][0]['geometry']['location']['lng']) ? $resp['results'][0]['geometry']['location']['lng'] : ""; + $formatted_address = isset($resp['results'][0]['formatted_address']) ? $resp['results'][0]['formatted_address'] : ""; + + // verify if data is complete + if($lati && $longi && $formatted_address){ + // put the data in the array + $data_arr = array(); + array_push( + $data_arr, + $lati, + $longi, + $formatted_address + ); + + return $data_arr; + + }else{ + return false; + } + } + + else{ + return false; + } + } +} diff --git a/inc/classes/class-opalestate-metabox-user.php b/inc/classes/class-opalestate-metabox-user.php new file mode 100755 index 00000000..86e71463 --- /dev/null +++ b/inc/classes/class-opalestate-metabox-user.php @@ -0,0 +1,290 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_User_MetaBox { + + public function get_front_base_field( $prefix ) { + $management = [ + [ + 'name' => esc_html__( 'Avatar Picture', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar', + 'type' => 'hidden', + 'single' => 1, + 'limit' => 1, + ], + + [ + 'name' => esc_html__( 'Avatar Picture', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar_id', + 'type' => 'uploader', + 'single' => 1, + 'limit' => 1, + + ], + + [ + 'id' => 'first_name', + 'name' => esc_html__( 'First Name', 'opalestate-pro' ), + 'type' => 'text', + 'attributes' => [ + 'required' => 'required', + ], + ], + [ + 'id' => 'last_name', + 'name' => esc_html__( 'Last Name', 'opalestate-pro' ), + 'type' => 'text', + 'attributes' => [ + 'required' => 'required', + ], + ], + [ + 'id' => 'description', + 'name' => esc_html__( 'Biographical Info', 'opalestate-pro' ), + 'type' => 'textarea', + 'description' => esc_html__( 'Share a little biographical information to fill out your profile. This may be shown publicly.', 'opalestate-pro' ), + 'after_row' => '
            ', + ], + ]; + + + return $management; + } + + public function get_avatar_fields( $prefix ) { + return [ + [ + 'name' => esc_html__( 'Avatar Pictures', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar', + 'type' => is_admin() ? 'file' : 'opal_upload', + 'avatar' => true, + + ], + ]; + } + + public function get_address_fields( $prefix ) { + return [ + [ + 'name' => esc_html__( 'Location', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in location of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "location", + 'taxonomy' => 'opalestate_location', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + 'before_row' => '
            ', + + ], + [ + 'name' => esc_html__( 'State / Province', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in state of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "state", + 'taxonomy' => 'opalestate_state', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + ], + [ + 'name' => esc_html__( 'City / Town', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in city of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "city", + 'taxonomy' => 'opalestate_city', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Address', 'opalestate-pro' ), + 'id' => "{$prefix}address", + 'type' => 'text', + 'attributes' => [ + 'required' => 'required', + ], + ], + [ + 'id' => "{$prefix}map", + 'name' => esc_html__( 'Map Location', 'opalestate-pro' ), + 'type' => 'opal_map', + 'sanitization_cb' => 'opal_map_sanitise', + 'split_values' => true, + 'attributes' => [ + 'required' => 'required', + ], + ], + ]; + } + + public function get_job_fields( $prefix ) { + return [ + [ + 'name' => esc_html__( 'Job', 'opalestate-pro' ), + 'id' => "{$prefix}job", + 'type' => 'text', + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Company', 'opalestate-pro' ), + 'id' => "{$prefix}company", + 'type' => 'text', + 'after_row' => '
            ', + ], + ]; + } + + public function get_office_fields( $prefix ) { + return $this->get_base_fields( $prefix ); + } + + public function get_base_front_fields( $prefix ) { + return [ + [ + 'name' => esc_html__( 'Email', 'opalestate-pro' ), + 'id' => "{$prefix}email", + 'type' => 'text', + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Website', 'opalestate-pro' ), + 'id' => "{$prefix}web", + 'type' => 'text_url', + ], + [ + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'id' => "{$prefix}phone", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Mobile', 'opalestate-pro' ), + 'id' => "{$prefix}mobile", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Fax', 'opalestate-pro' ), + 'id' => "{$prefix}fax", + 'type' => 'text', + 'after_row' => '
            ', + ], + ]; + } + + public function get_base_fields( $prefix ) { + return [ + [ + 'id' => "{$prefix}featured", + 'name' => esc_html__( 'Is Featured', 'opalestate-pro' ), + 'type' => 'switch', + 'description' => esc_html__( 'Set member as featured', 'opalestate-pro' ), + 'options' => [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + ], + ], + + [ + 'id' => "{$prefix}trusted", + 'name' => esc_html__( 'Trusted', 'opalestate-pro' ), + 'type' => 'switch', + 'description' => esc_html__( 'Set this member as Trusted Member', 'opalestate-pro' ), + 'options' => [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + ], + ], + + [ + 'name' => esc_html__( 'Avatar Pictures', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in user detail and profile box information', 'opalestate-pro' ), + 'id' => $prefix . 'avatar', + 'type' => is_admin() ? 'file' : 'uploader', + 'single' => true, + 'avatar' => true, + ], + + [ + 'name' => esc_html__( 'Email', 'opalestate-pro' ), + 'id' => "{$prefix}email", + 'type' => 'text', + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Website', 'opalestate-pro' ), + 'id' => "{$prefix}web", + 'type' => 'text_url', + ], + [ + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'id' => "{$prefix}phone", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Mobile', 'opalestate-pro' ), + 'id' => "{$prefix}mobile", + 'type' => 'text', + ], + + [ + 'name' => esc_html__( 'Fax', 'opalestate-pro' ), + 'id' => "{$prefix}fax", + 'type' => 'text', + 'after_row' => '
            ', + ], + ]; + } + + public function get_social_fields( $prefix ) { + return [ + [ + 'name' => esc_html__( 'Twitter', 'opalestate-pro' ), + 'id' => "{$prefix}twitter", + 'type' => 'text_url', + 'before_row' => '
            ', + ], + + [ + 'name' => esc_html__( 'Facebook', 'opalestate-pro' ), + 'id' => "{$prefix}facebook", + 'type' => 'text_url', + ], + + [ + 'name' => esc_html__( 'Google', 'opalestate-pro' ), + 'id' => "{$prefix}google", + 'type' => 'text_url', + ], + + [ + 'name' => esc_html__( 'LinkedIn', 'opalestate-pro' ), + 'id' => "{$prefix}linkedin", + 'type' => 'text_url', + ], + + [ + 'name' => esc_html__( 'Pinterest', 'opalestate-pro' ), + 'id' => "{$prefix}pinterest", + 'type' => 'text_url', + ], + [ + 'name' => esc_html__( 'Instagram', 'opalestate-pro' ), + 'id' => "{$prefix}instagram", + 'type' => 'text_url', + 'after_row' => '
            ', + ], + ]; + } +} diff --git a/inc/classes/class-opalestate-multilingual.php b/inc/classes/class-opalestate-multilingual.php new file mode 100755 index 00000000..2c788b56 --- /dev/null +++ b/inc/classes/class-opalestate-multilingual.php @@ -0,0 +1,157 @@ +check(); + } + } + + /** + * Get the current language. + * + * @return string|null + */ + public function get_current_language() { + return $this->current_language ?: null; + } + + /** + * Get the main language. + * + * @return string|null + */ + public function get_default_language() { + return $this->default_language ?: null; + } + + /** + * Get the original post. + * + * @param int $post_id The post ID. + * @return int + */ + public function get_original_post( $post_id ) { + return $this->get_original_object( $post_id, 'post' ); + } + + /** + * Get the original object ID (post, taxonomy, etc...). + * + * @param int $id The object id. + * @param string $type Optional, post type or taxonomy name of the object, defaults to 'post'. + * @return int|null + */ + public function get_original_object( $id, $type = 'post' ) { + return icl_object_id( $id, $type, true, $this->get_default_language() ); + } + + /** + * Perform check the language. + * + * @access private + */ + public function check() { + switch ( true ) { + case ( static::is_wpml() ): + global $sitepress; + $this->current_language = $sitepress->get_current_language(); + $this->default_language = $sitepress->get_default_language(); + break; + + case ( static::is_polylang() ): + $this->default_language = pll_default_language( 'slug' ); + $this->current_language = pll_current_language( 'slug' ); + break; + } + } + + /** + * Sets the specified language. + * + * @param string|null $language The language name. + * @return void + */ + public function set_language( $language = null ) { + if ( static::is_polylang() ) { + $this->set_polylang_language( $language ); + } elseif ( static::is_wpml() ) { + global $sitepress; + $sitepress->switch_lang( $language, ! headers_sent() ); + } + } + + /** + * Sets the specified language on PLL. + * + * @sse \PLL_Choose_Lang::set_language() + * + * @param string|null $language The language name. + * @return void + */ + public function set_polylang_language( $language = null ) { + if ( ! static::is_polylang() ) { + return; + } + + /* @var \Polylang $polylang */ + $polylang = PLL(); + + // In frontend, if no language given, get the preferred language + // according to the browser preferences. + if ( empty( $language ) && ( ! is_admin() && ! defined( 'DOING_CRON' ) ) ) { + $curlang = $polylang->choose_lang->get_preferred_language(); + } else { + $curlang = $polylang->model->get_language( trim( $language ) ); + } + + if ( $curlang instanceof \PLL_Language ) { + $polylang->curlang = $curlang; + $GLOBALS['text_direction'] = $curlang->is_rtl ? 'rtl' : 'ltr'; // @codingStandardsIgnoreLine + } + } + + /** + * Determine if we're using WPML. + * + * Since PolyLang has a compatibility layer for WPML, we'll have to consider that too. + * + * @return bool + */ + public static function is_wpml() { + return ( defined( 'ICL_SITEPRESS_VERSION' ) && ! static::is_polylang() ); + } + + /** + * Determine if we're using PolyLang. + * + * @return bool + */ + public static function is_polylang() { + return class_exists( 'Polylang' ) && function_exists( 'pll_current_language' ); + } +} diff --git a/inc/classes/class-opalestate-session.php b/inc/classes/class-opalestate-session.php new file mode 100755 index 00000000..60a91c1b --- /dev/null +++ b/inc/classes/class-opalestate-session.php @@ -0,0 +1,299 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * Give_Session Class + * + * @since 1.0 + */ +class Opalestate_Session { + + /** + * Holds our session data + * + * @var array + * @access private + * @since 1.0 + */ + private $session; + + /** + * Whether to use PHP $_SESSION or WP_Session + * + * @var bool + * @access private + * @since 1.0 + */ + private $use_php_sessions = false; + + /** + * Expiration Time + * + * @var int + * @access private + * @since 1.0 + */ + private $exp_option = false; + + /** + * Session index prefix + * + * @var string + * @access private + * @since 1.0 + */ + private $prefix = ''; + + /** + * Get things started + * + * Defines our WP_Session constants, includes the necessary libraries and + * retrieves the WP Session instance + * + * @since 1.0 + */ + public function __construct() { + + $this->use_php_sessions = $this->use_php_sessions(); + $this->exp_option = 604800; //opalestate_get_option( 'session_lifetime' ); + + if ( $this->use_php_sessions ) { + + if ( is_multisite() ) { + $this->prefix = '_' . get_current_blog_id(); + } + + // Use PHP SESSION (must be enabled via the OPALMEMBERSHIP_USE_PHP_SESSIONS constant) + add_action( 'init', array( $this, 'maybe_start_session' ), - 2 ); + + } else { + + // Use WP_Session (default) + if ( ! defined( 'WP_SESSION_COOKIE' ) ) { + define( 'WP_SESSION_COOKIE', 'opalestate_wp_session' ); + } + + if ( ! class_exists( 'Recursive_ArrayAccess' ) ) { + // require_once OPALESTATE_PLUGIN_DIR . 'inc/libraries/class-recursive-arrayaccess.php'; + } + + if ( ! class_exists( 'WP_Session' ) ) { + require_once OPALESTATE_PLUGIN_DIR . 'inc/libraries/wp_session/class-wp-session.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/libraries/wp-session.php'; + } + + add_filter( 'wp_session_expiration_variant', array( $this, 'set_expiration_variant_time' ), 99999 ); + add_filter( 'wp_session_expiration', array( $this, 'set_expiration_time' ), 99999 ); + + } + + if ( empty( $this->session ) && ! $this->use_php_sessions ) { + add_action( 'plugins_loaded', array( $this, 'init' ), - 1 ); + } else { + add_action( 'init', array( $this, 'init' ), - 1 ); + } + + } + + /** + * Setup the WP_Session instance + * + * @access public + * @since 1.0 + * @return array $this->session + */ + public function init() { + + if ( $this->use_php_sessions ) { + $this->session = isset( $_SESSION[ 'opalestate-pro' . $this->prefix ] ) && is_array( $_SESSION[ 'opalestate-pro' . $this->prefix ] ) ? $_SESSION[ 'opalestate-pro' . $this->prefix ] : array(); + } else { + $this->session = WP_Session::get_instance(); + } + + return $this->session; + } + + /** + * Retrieve session ID + * + * @access public + * @since 1.0 + * @return string Session ID + */ + public function get_id() { + return $this->session->session_id; + } + + /** + * Retrieve a session variable + * + * @access public + * @since 1.0 + * + * @param string $key Session key + * + * @return string Session variable + */ + public function get( $key = '', $default = false ) { + $key = sanitize_key( $key ); + + return isset( $this->session[ $key ] ) ? maybe_unserialize( $this->session[ $key ] ) : $default; + } + + /** + * Set a session variable + * + * @since 1.0 + * + * @param $key $_SESSION key + * @param $value $_SESSION variable + * + * @return mixed Session variable + */ + public function set( $key, $value ) { + + $key = sanitize_key( $key ); + + if ( is_array( $value ) ) { + $this->session[ $key ] = serialize( $value ); + } else { + $this->session[ $key ] = $value; + } + + if ( $this->use_php_sessions ) { + $_SESSION[ 'opalestate-pro' . $this->prefix ] = $this->session; + } + + return $this->session[ $key ]; + } + + /** + * Set Cookie Variant Time + * + * @description Force the cookie expiration variant time to custom expiration option, less and hour; defaults to 23 hours (set_expiration_variant_time used in WP_Session) + * + * @access public + * @since 1.0 + * + * @return int + */ + public function set_expiration_variant_time() { + return ( ! empty( $this->exp_option ) ? ( intval( $this->exp_option ) - 3600 ) : 30 * 60 * 23 ); + } + + /** + * Set the Cookie Expiration + * + * @description Force the cookie expiration time if set, default to 24 hours + * + * @access public + * @since 1.0 + * + * @return int + */ + public function set_expiration_time() { + return ( ! empty( $this->exp_option ) ? intval( $this->exp_option ) : 30 * 60 * 24 ); + } + + /** + * Starts a new session if one hasn't started yet. + * + * @return null + * Checks to see if the server supports PHP sessions + * or if the OPALMEMBERSHIP_USE_PHP_SESSIONS constant is defined + * + * @access public + * @since 1.0 + * @return bool $ret True if we are using PHP sessions, false otherwise + */ + public function use_php_sessions() { + + $ret = false; + + // If the database variable is already set, no need to run autodetection + $opalestate_use_php_sessions = (bool) get_option( 'opalestate_use_php_sessions' ); + + if ( ! $opalestate_use_php_sessions ) { + + // Attempt to detect if the server supports PHP sessions + if ( function_exists( 'session_start' ) && ! ini_get( 'safe_mode' ) ) { + + $this->set( 'opalestate_use_php_sessions', 1 ); + + if ( $this->get( 'opalestate_use_php_sessions' ) ) { + + $ret = true; + + // Set the database option + update_option( 'opalestate_use_php_sessions', true ); + + } + + } + + } else { + $ret = $opalestate_use_php_sessions; + } + + // Enable or disable PHP Sessions based on the OPALMEMBERSHIP_USE_PHP_SESSIONS constant + if ( defined( 'OPALMEMBERSHIP_USE_PHP_SESSIONS' ) && OPALMEMBERSHIP_USE_PHP_SESSIONS ) { + $ret = true; + } else if ( defined( 'OPALMEMBERSHIP_USE_PHP_SESSIONS' ) && ! OPALMEMBERSHIP_USE_PHP_SESSIONS ) { + $ret = false; + } + + return (bool) apply_filters( 'opalestate_use_php_sessions', $ret ); + } + + /** + * Maybe Start Session + * + * @description Starts a new session if one hasn't started yet. + * @see http://php.net/manual/en/function.session-set-cookie-params.php + */ + public function maybe_start_session() { + +// session_destroy(); //Uncomment for testing ONLY + + if ( ! session_id() && ! headers_sent() ) { + $lifetime = current_time( 'timestamp' ) + $this->set_expiration_time(); + session_start(); + setcookie( session_name(), session_id(), $lifetime ); // + setcookie( session_name() . '_expiration', $lifetime, $lifetime ); + } + } + + /** + * Get Session Expiration + * + * @description Looks at the session cookies and returns the expiration date for this session if applicable + * + */ + public function get_session_expiration() { + + $expiration = false; + + if ( session_id() && isset( $_COOKIE[ session_name() . '_expiration' ] ) ) { + $expiration = date( 'D, d M Y h:i:s', intval( $_COOKIE[ session_name() . '_expiration' ] ) ); + } + + return $expiration; + } + +} + diff --git a/inc/classes/class-opalestate-walkscore.php b/inc/classes/class-opalestate-walkscore.php new file mode 100755 index 00000000..494caf9b --- /dev/null +++ b/inc/classes/class-opalestate-walkscore.php @@ -0,0 +1,185 @@ + + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * An implementation of the Walk Score API in PHP. + * + * @see http://www.walkscore.com/ + */ +class Opalestate_WalkScore { + + /** + * Constructs a WalkScore object + * + * @param string $wsapikey + * Walk Score API key obtainable at http://www.walkscore.com/request-api-key.php + */ + function __construct($wsapikey) { + // a Walk Score API key is required + if (!isset($wsapikey)) { + throw new Exception("Walk Score API key required"); + } + $this->wsapikey = $wsapikey; + } + + /** + * Makes the API call using curl + * + * @param string $url + * The URL to send the request to + * @param array $options + * The options to send as the query appended to the URL + */ + private function make_api_call($url, $options) { + $options['wsapikey'] = $this->wsapikey; + $options['format'] = 'json'; + $query = http_build_query($options); + $response_url = $url . '?' . $query; + + $response = wp_remote_get($response_url); + $response = wp_remote_retrieve_body( $response ); + $response = json_decode($response); + + return $response; + } + + /** + * Implement the Walk Score Public Transit API + * + * @param string $call + * Which call to make to the Public Transit API + * - score: Returns the Transit Score for a given location. + * - stop search: Returns information about stops near a given location. + * - network search: Returns connected stops and routes near a given location. + * - stop detail: Returns details for a single stop. + * - route detail: eturns details for a single route. + * - supported cities: Returns a list of cities for which scores are available. + * @param array $options + * Options to send to the Public Transit API. Keys and values are dependent + * on the call made. + * @return + * An object containing the results of the call. + * @see http://www.walkscore.com/services/public-transit-api.php + */ + public function PublicTransit($call, $options = array()) { + + $api_url = 'http://transit.walkscore.com/transit/'; + $calls = array( + 'score' => 'score/', + 'stop search' => 'search/stops/', + 'network search' => 'search/network/', + 'stop detail' => 'stop/ID/', + 'route detail' => 'route/ID/', + 'supported cities' => 'supported/cities/', + ); + + + $api_url .= $calls[$call]; + return $this->make_api_call($api_url, $options); + } + + /** + * Implementation of the Walk Score API + * + * @param array $options + * An array of options. The array keys to pass are: + * - mode: string, one of 'walk', 'bike', 'drive', or 'transit'. + * - origin: string containing a comma-separated lat,lng. + * - destination: string containing a comma-separated lat,lng. + * @todo Multiple destinations. + * @ see http://www.walkscore.com/professional/travel-time-api.php + */ + public function TravelTime($options = array()) { + if (!is_array($options)) { + throw new Exception("Input parameter must be an array."); + } + $modes = array('walk', 'bike', 'drive', 'transit'); + if (!in_array($options['mode'], $modes)) { + throw new Exception("Mode parameter must be one of 'walk', 'bike', 'drive', or 'transit'."); + } + $response = $this->make_api_call('http://www.walkscore.com/api/v1/traveltime/json', $options); + return $response->response; + } + + /** + * Implementation of the Walk Score API + * + * @param array $options + * An array of options. The array keys to pass are: + * - address: string containing the street address of the location + * - lat: string or number containing the latitude of the location + * - lon: string or number containing the longitude of the location + * @return + * An object containing the results of the call. An added property + * called status_description gives a human-readable description of + * the numeric status code returned in the object + * @see http://www.walkscore.com/services/api.php + */ + public function WalkScore($options = array()) { + if (!is_array($options)) { + throw new Exception("Input parameter must be an array."); + } + + $response = $this->make_api_call('http://api.walkscore.com/score', $options); + + // stuff the status code description in the response object + // so you don't have to look it up on the Walk Score website + $status_descriptions = array( + 1 => 'Walk Score successfully returned.', + 2 => 'Score is being calculated and is not currently available.', + 30 => 'Invalid latitude/longitude.', + 40 => 'Your WSAPIKEY is invalid.', + 41 => 'Your daily API quota has been exceeded.', + 42 => 'Your IP address has been blocked.', + ); + + $response->status_description = $status_descriptions[$response->status]; + + return $response; + } + + /** + * Implementation of the Walk Shed API + * + * @param array $options + * An array of options. The array keys to pass are: + * - lat: string or number containing the latitude of the location + * - lon: string or number containing the longitude of the location + * @return + * An object containing the results of the call. An added property + * called status_description gives a human-readable description of + * the numeric status code returned in the object + * @see http://www.walkscore.com/services/api.php + */ + public function WalkShed($options = array()) { + + if (!is_array($options)) { + throw new Exception("Input parameter must be an array."); + } + + $response = $this->make_api_call('http://api.walkscore.com/walk_shed', $options); + + // stuff the status code description in the response object + // so you don't have to look it up on the Walk Score website + $status_descriptions = array( + 1 => 'Walk shed successfully returned.', + 2 => 'Walk shed unavailable.', + 30 => 'Invalid latitude/longitude.', + 31 => 'Walk Score API internal error.', + 40 => 'Your WSAPIKEY is invalid.', + 41 => 'Your daily API quota has been exceeded.', + ); + $response->status_description = $status_descriptions[$response->status]; + + return $response; + } +} diff --git a/inc/classes/class-opalestate-yelp.php b/inc/classes/class-opalestate-yelp.php new file mode 100755 index 00000000..0cc3d7f7 --- /dev/null +++ b/inc/classes/class-opalestate-yelp.php @@ -0,0 +1,250 @@ + + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Yelp { + // API constants, you shouldn't have to change these. + const API_HOST = "https://api.yelp.com"; + const SEARCH_PATH = "/v3/businesses/search"; + const BUSINESS_PATH = "/v3/businesses/"; // Business ID will come after slash. + const TOKEN_PATH = "/oauth2/token"; + const GRANT_TYPE = "client_credentials"; + + public static function get_client_id() { + return opalestate_get_option( 'yelp_app_id', '' ); + } + + public static function get_app_secret() { + return opalestate_get_option( 'yelp_app_secret', '' ); + } + + public static function get_app_key() { + return opalestate_get_option( 'yelp_app_key', '' ); + } + + public static function get_categories() { + return opalestate_get_option( 'yelp_categories', [] ); + } + + public static function get_category_results_limit() { + return opalestate_get_option( 'yelp_number_results', 3 ); + } + + /** + * Given a bearer token, send a GET request to the API. + * + * @return OAuth bearer token, obtained using client_id and client_secret. + */ + public function obtain_bearer_token() { + $yelp_client_id = static::get_client_id(); + $yelp_client_secret = static::get_app_secret(); + $yelp_app_key = static::get_app_key(); + + return $yelp_app_key; + } + + + /** + * Makes a request to the Yelp API and returns the response + * + * @param $bearer_token API bearer token from obtain_bearer_token + * @param $host The domain host of the API + * @param $path The path of the API after the domain. + * @param $url_params Array of query-string parameters. + * @return The JSON response from the request + */ + public function request( $bearer_token, $host, $path, $url_params = [] ) { + // Send Yelp API Call + try { + $url = $host . $path . "?" . http_build_query( $url_params ); + $args = [ + 'timeout' => 30, + 'redirection' => 10, + 'httpversion' => CURL_HTTP_VERSION_1_1, + 'user-agent' => '', + 'headers' => [ + 'authorization' => 'Bearer ' . $bearer_token, + ], + 'sslverify' => false, + ]; + + $response = wp_remote_get( $url, $args ); + $response = wp_remote_retrieve_body( $response ); + } catch ( Exception $e ) { + + } + + return $response; + } + + /** + * Query the Search API by a search term and location + * + * @param $bearer_token API bearer token from obtain_bearer_token + * @param $term The search term passed to the API + * @param $location The search location passed to the API + * @return The JSON response from the request + */ + public function search( $bearer_token, $term, $latitude, $longitude ) { + $url_params = []; + + $url_params['term'] = $term; + $url_params['latitude'] = $latitude; + $url_params['longitude'] = $longitude; + $url_params['limit'] = static::get_category_results_limit(); + + return $this->request( $bearer_token, static::API_HOST, static::SEARCH_PATH, $url_params ); + } + + /** + * Query the Business API by business_id + * + * @param $bearer_token API bearer token from obtain_bearer_token + * @param $business_id The ID of the business to query + * @return The JSON response from the request + */ + public function get_business( $bearer_token, $business_id ) { + $business_path = $GLOBALS['BUSINESS_PATH'] . urlencode( $business_id ); + + return $this->request( $bearer_token, $GLOBALS['API_HOST'], $business_path ); + } + + public function query_api( $term, $latitude, $longitude ) { + $bearer_token = $this->obtain_bearer_token(); + + $response = json_decode( $this->search( $bearer_token, $term, $latitude, $longitude ) ); + + return $response; + } + + public function get_results( $term, $latitude, $longitude ) { + if ( ! static::get_categories() ) { + return false; + } + + $results = $this->query_api( $term, $latitude, $longitude ); + if ( isset( $results->error ) && $results->error ) { + return false; + } + + return $results; + } + + public static function get_all_categories() { + return apply_filters( 'opalestate_yelp_all_categories', + [ + 'active' => [ + 'category' => esc_html__( 'Active Life', 'opalestate-pro' ), + 'category_sign' => 'fa fa-bicycle', + ], + 'arts' => [ + 'category' => esc_html__( 'Arts & Entertainment', 'opalestate-pro' ), + 'category_sign' => 'fa fa-music', + ], + 'auto' => [ + 'category' => esc_html__( 'Automotive', 'opalestate-pro' ), + 'category_sign' => 'fa fa-car', + ], + 'beautysvc' => [ + 'category' => esc_html__( 'Beauty & Spas', 'opalestate-pro' ), + 'category_sign' => 'fa fa-female', + ], + 'education' => [ + 'category' => esc_html__( 'Education', 'opalestate-pro' ), + 'category_sign' => 'fa fa-graduation-cap', + ], + 'eventservices' => [ + 'category' => esc_html__( 'Event Planning & Services', 'opalestate-pro' ), + 'category_sign' => 'fa fa-birthday-cake', + ], + 'financialservices' => [ + 'category' => esc_html__( 'Financial Services', 'opalestate-pro' ), + 'category_sign' => 'fa fa-money', + ], + 'food' => [ + 'category' => esc_html__( 'Food', 'opalestate-pro' ), + 'category_sign' => 'fa fa fa-cutlery', + ], + 'health' => [ + 'category' => esc_html__( 'Health & Medical', 'opalestate-pro' ), + 'category_sign' => 'fa fa-medkit', + ], + 'homeservices' => [ + 'category' => esc_html__( 'Home Services ', 'opalestate-pro' ), + 'category_sign' => 'fa fa-wrench', + ], + 'hotelstravel' => [ + 'category' => esc_html__( 'Hotels & Travel', 'opalestate-pro' ), + 'category_sign' => 'fa fa-bed', + ], + 'localflavor' => [ + 'category' => esc_html__( 'Local Flavor', 'opalestate-pro' ), + 'category_sign' => 'fa fa-coffee', + ], + 'localservices' => [ + 'category' => esc_html__( 'Local Services', 'opalestate-pro' ), + 'category_sign' => 'fa fa-dot-circle-o', + ], + 'massmedia' => [ + 'category' => esc_html__( 'Mass Media', 'opalestate-pro' ), + 'category_sign' => 'fa fa-television', + ], + 'nightlife' => [ + 'category' => esc_html__( 'Nightlife', 'opalestate-pro' ), + 'category_sign' => 'fa fa-glass', + ], + 'pets' => [ + 'category' => esc_html__( 'Pets', 'opalestate-pro' ), + 'category_sign' => 'fa fa-paw', + ], + 'professional' => [ + 'category' => esc_html__( 'Professional Services', 'opalestate-pro' ), + 'category_sign' => 'fa fa-suitcase', + ], + 'publicservicesgovt' => [ + 'category' => esc_html__( 'Public Services & Government', 'opalestate-pro' ), + 'category_sign' => 'fa fa-university', + ], + 'realestate' => [ + 'category' => esc_html__( 'Real Estate', 'opalestate-pro' ), + 'category_sign' => 'fa fa-building-o', + ], + 'religiousorgs' => [ + 'category' => esc_html__( 'Religious Organizations', 'opalestate-pro' ), + 'category_sign' => 'fa fa-cloud', + ], + 'restaurants' => [ + 'category' => esc_html__( 'Restaurants', 'opalestate-pro' ), + 'category_sign' => 'fa fa-cutlery', + ], + 'shopping' => [ + 'category' => esc_html__( 'Shopping', 'opalestate-pro' ), + 'category_sign' => 'fa fa-shopping-bag', + ], + 'transport' => [ + 'category' => esc_html__( 'Transportation', 'opalestate-pro' ), + 'category_sign' => 'fa fa-bus', + ], + ] + ); + } + + public static function get_all_categories_options() { + $categories = static::get_all_categories(); + + $options = []; + foreach ( $categories as $key => $term ) { + $options[ $key ] = $term['category']; + } + + return $options; + } +} diff --git a/inc/cli/export.php b/inc/cli/export.php new file mode 100755 index 00000000..24eaaf3b --- /dev/null +++ b/inc/cli/export.php @@ -0,0 +1,646 @@ +path = OPALESTATE_PLUGIN_DIR; + + // $this->cfg = json_decode( file get contents( $this->path.'project.json' ) ); + $this->cfg = json_decode( wp_remote_get( $this->path.'project.json' ) ); + + $this->server = $this->cfg->server; + $this->oldurl = $this->cfg->oldurl; + $this->theme = $this->cfg->theme; + $this->name = $this->cfg->name; + $this->subpath = $this->cfg->subpath; + } + + /** + * Write data in file + */ + private function output_file_content( $file_path, $output ) { + $fp = fopen( $file_path, 'w+' ); + fwrite( $fp, $output ); + fclose( $fp ); + } + + /** + * Get more options + */ + public function get_more_options(){ + $data = array( + 'header' => 'header-1', + 'footer' => 'footer-1', + 'page' => 'home-1' + ); + + if( isset($this->cfg->active) && $this->cfg->active ) { + $data = (array) $this->cfg->active; + } + + return array( + 'active' => $data, + 'oldurl' => $this->oldurl, + 'server' => $this->server, + "samples" => array( + 'post' => array(), + 'product' => array() + ) + ); + } + + /** + * Export theme options in customizer + */ + public function options(){ + return array(); + $thememods = get_option( 'theme_mods_' . $this->theme ); + $file = $this->path.'/sample/thememods.json'; + $ids = array(); + foreach( $thememods as $key => $mod ){ + + + if( is_string($mod) ){ + // $thememods[$key] = $this->_replace_uri( $mod, $this->oldurl, "SITE_URL_HERE"); + if( preg_match( "#jpg|png|gif|svg#", $mod) && $mod ){ + $ids[$key] = $this->find_image_id_byguid( $mod ); + } + } + if( isset($thememods['wpopal_customize_css']) ){ + unset( $thememods['wpopal_customize_css'] ); + } + + if( isset($thememods['osf_theme_custom_style']) ){ + unset( $thememods['osf_theme_custom_style'] ); + } + + if( isset($thememods['sidebars_widgets']) ){ + unset( $thememods['sidebars_widgets'] ); + } + + /// + if( $key == 'custom_logo' && $mod ){ + $ids[$key] = $mod; + } + + } + + + $attachments = array(); + + if( $ids ){ + foreach( $ids as $id ) { + $post = get_post( $id ); + if( $post ) { + $attachments[$post->ID] = array( + 'id' => $post->ID, + 'guid' => wp_get_attachment_url( $post->ID ), + 'post_parent' => $post->post_parent, + 'post_name' => $post->post_name, + 'post_date' => $post->post_date ); + } + } + } + + $options = array( + 'woocommerce_single_image_width' => '', + 'woocommerce_thumbnail_image_width' => '', + 'woocommerce_thumbnail_cropping' => '', + 'woocommerce_thumbnail_cropping_custom_height' => '', + 'woocommerce_thumbnail_cropping_custom_width' => '', + "woocommerce_shop_page_id" => '', + "woocommerce_cart_page_id" => '', + 'woocommerce_checkout_page_id' => '', + 'woocommerce_myaccount_page_id' => '', + 'woocommerce_terms_page_id' => '', + 'yith_wcwl_wishlist_page_id' => '' + + ); + + foreach( $options as $key => $value ){ + $value = get_option( $key ); + if( empty($value) ) { + unset( $options[$key] ); + continue; + } + $options[$key] = $value; + } + + $options['page_for_posts'] = 'Blog'; + if( function_exists( 'wp_get_custom_css_post' ) ) { + $options['wp_css'] = wp_get_custom_css(); + } + $data = array( 'thememods' => $thememods, 'attachments' => $attachments, "options" => $options ); + + + + // $this->output_file_content( $file, wp_json_encode($data ,JSON_PRETTY_PRINT ) ); + + return $data; + } + + /** + * Replace URI in xml + */ + public function _replace_uri( $str, $oldurl, $server ){ + $str = str_replace( str_replace("/","\/", $oldurl ), str_replace("/","\/", $server ), $str ); + $str = str_replace( $oldurl, $server, $str ); + $str = str_replace( str_replace("/","\\\\\\/", $oldurl ), str_replace("/","\\\\\\/", $server ), $str ); + return $str; + } + + /** + * Export config samples + */ + public function config_samples( $dev=0 ){ + + + $data['samples'] = array(); + + + $file = $this->path.$this->cfg->folder_source.'/samples.json'; + + + $niches = $this->cfg->niches; + + $single = $this->cfg->single; + + $key = 0; + $data['samples'][] = array( + "name" => isset($single->name)?$single->name:"Sample", + "key" => "niche-".$key, + "url" => isset($single->url)?$single->url:"", + "demo" => isset($single->demo)?$single->demo:"", + "preview" => $this->cfg->server_source.'/screenshot.png', + "sample" => $this->cfg->server_source.'/data.zip' + ); + + $this->output_file_content( $file, wp_json_encode($data ) ); + /// + //$file = $this->path.'/wp-content/themes/'.$this->cfg->theme.'/project.json'; + //$data = $this->cfg->themeinfo; + //$this->output_file_content( $file, json_encode($data , JSON_PRETTY_PRINT ) ); + } + + /** + * Export all pages + */ + public function pages(){ + + return array(); + $excludes = array(); + + global $wpdb; + + $post_type = 'page'; + /// items + + $where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s and {$wpdb->posts}.post_content LIKE '%opalestate_%'", $post_type ); + + + // grab a snapshot of post IDs, just in case it changes during the export + $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE $where" ); + + $data = $this->export_json_ids( $post_ids, $excludes, $isattachement ); + + echo '
            ' . print_r( $data ,1 );die;
            +
            +			//$file = $this->path.'sample/pages.json'; 
            +			// $this->output_file_content( $file, wp_json_encode($data ) );
            +			return $data; 
            +
            +		}
            +
            +		/**
            +		 * Export all pages 
            +		 */
            +		public function data_posttypes(){
            +
            +			$excludes = array();
            +
            +			$data = $this->export_posttype( array(  
            +				'opalestate_agent', 
            +				'opalestate_agency', 
            +				'opalestate_agent_ft', 
            +				'opalestate_agency_ft', 
            +				'opalestate_rating_ft', 
            +				'opalestate_property'
            +			), $excludes );
            +
            +		//	$file = ABSPATH.'src/json/elementor.json'; 
            +		//	$this->output_file_content( $file, wp_json_encode($data ) );
            +
            +			return $data; 
            +
            +		}
            +
            +		/**
            +		 * get all attachments by post ids
            +		 */
            +		protected function get_attachment( $post_ids ) {
            +	        $attachments = array();
            +	        foreach ( $post_ids as $post_id) { 
            +	             
            +	            $value = get_post_meta($post_id, '_thumbnail_id', true);
            +	            if ( $value ) {
            +	                $attachments = array_merge( $attachments, array($value) );
            +	            }
            +	           
            +
            +	            $attachArgs  = array(
            +	                'post_parent'  => $post_id,
            +	                'post_type'    => 'attachment',
            +	                'numberposts'  => -1,
            +	                'post__not_in' => $attachments, //To skip duplicates
            +	            );
            +	            $attachList  = get_children($attachArgs, ARRAY_A);
            +	            $attachments = array_merge($attachments, array_keys($attachList));
            +	       	}
            +
            +			$ids = $this->get_images_posts( $post_ids );
            +			if( $ids ){
            +				$attachments = array_merge( $ids, $attachments );
            +			}
            +
            +	        return $attachments;
            +	    }
            +
            +	    /**
            +	     * Export data posts by post type with attachments
            +	     */
            +	    protected function export_posttype( $post_type, $excludes=array(), $isattachement=true ) {
            +
            +			global $wpdb;
            +	
            +			/// items 
            +			
            +			if( is_array($post_type) ){
            +				$tmp   = "'".implode( "','", $post_type )."'";
            +				$where = "{$wpdb->posts}.post_type IN( ".$tmp ." )";
            +			} else {
            +				$where = $wpdb->prepare( "{$wpdb->posts}.post_type = %s", $post_type );
            +			}
            +
            +			// grab a snapshot of post IDs, just in case it changes during the export
            +			$post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE $where" );
            +
            +			return $this->export_json_ids( $post_ids, $excludes, $isattachement  );
            +
            +		}
            +
            +		public function aa(){
            +			global $wpdb;
            +			$postmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE  post_id = %d",  240) );
            +			
            +					$exls = array(
            +						'_edit_last',
            +						'_edit_lock',
            +						'_elementor_version',
            +						'_menu_item_type',
            +						'_menu_item_menu_item_parent',
            +						'_menu_item_object_id',
            +						'_menu_item_object',
            +						'_menu_item_target',
            +						'_menu_item_classes',
            +						'_menu_item_xfn',
            +						'_menu_item_url',
            +						'_elementor_css'
            +					);
            +
            +					$tmp = array();
            +					foreach( $postmeta as $key => $meta ){
            +						unset( $postmeta[$key]->post_id );
            +						unset( $postmeta[$key]->meta_id );
            +						foreach( $exls as $exl ){
            +							if( $meta->meta_key == $exl ){
            +								unset( $postmeta[$key] );
            +							}
            +						}
            +					}	
            +					foreach( $postmeta as $key => $meta ){
            +						$tmp[$meta->meta_key] = $meta->meta_value;
            +					}
            +		}
            +
            +		/**
            +		 * export json data by ids
            +		 */
            +		protected function export_json_ids( $post_ids , $excludes,  $isattachement ){
            +			global $wpdb;
            +
            +			$output = array();
            +
            +			$export = array();
            +
            +			if( $isattachement ){
            +				$ids = $this->get_attachment( $post_ids ); 
            +
            +
            +		 		if( $ids ){
            +
            +					$where = 'WHERE ID IN (' . join( ',', $ids ) . ')';
            +					$posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
            +
            +					$export['attachments'] = array();
            +					foreach( $posts as $post ) {
            +						$export['attachments'][$post->ID] = array(
            +							'id'	=> $post->ID,
            +						 'guid'=>  wp_get_attachment_url( $post->ID ), 
            +						 'post_parent' => $post->post_parent,
            +						  'post_name' => $post->post_name, 
            +						  'post_date' => $post->post_date  );
            +					}	
            +				}	
            +			}
            +				
            +			while ( $next_posts = array_splice( $post_ids, 0, 20 ) ) {
            +				
            +				$where = 'ID IN (' . join( ',', $next_posts ) . ')';
            +				$posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} WHERE post_status='publish' and  $where" );
            +
            +				// Begin Loop.
            +				foreach ( $posts as $post ) {
            +
            +					if( in_array($post->ID , $excludes) ){
            +						continue; 
            +					}
            +
            +					setup_postdata( $post );
            +					$data = array();
            +					if ( get_post_meta( $post->ID, '_elementor_edit_mode', true ) === 'builder' ) {
            +						$post->post_content = "";
            +					}
            +
            +					$post->guid =  $this->_replace_uri( $post->guid, $this->oldurl, "SITE_URL_HERE" );
            +
            +					$excludes = array(
            +						'guid', 
            +						'to_ping', 
            +						'pinged',
            +						'post_content_filtered',
            +						'post_mime_type',
            +						'comment_count',
            +						'filter',
            +						'post_modified',
            +						'post_modified_gmt'
            +					);
            +
            +					foreach( $excludes as $exl ){
            +						if( isset($post->$exl) ){
            +							unset( $post->$exl );
            +						}
            +					}
            +
            +					$data['post'] =  $post;
            +					// meta data
            +					$postmeta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->postmeta WHERE  post_id = %d", $post->ID ) );
            +
            +					$exls = array(
            +						'_edit_last',
            +						'_edit_lock',
            +						'_elementor_version',
            +						'_menu_item_type',
            +						'_menu_item_menu_item_parent',
            +						'_menu_item_object_id',
            +						'_menu_item_object',
            +						'_menu_item_target',
            +						'_menu_item_classes',
            +						'_menu_item_xfn',
            +						'_menu_item_url',
            +						'_elementor_css'
            +					);
            +
            +					$tmp = array();
            +					foreach( $postmeta as $key => $meta ){
            +						unset( $postmeta[$key]->post_id );
            +						unset( $postmeta[$key]->meta_id );
            +						foreach( $exls as $exl ){
            +							if( $meta->meta_key == $exl ){
            +								unset( $postmeta[$key] );
            +							}
            +						}
            +					}	
            +					foreach( $postmeta as $key => $meta ){
            +						$tmp[$meta->meta_key] = $meta->meta_value;
            +					}
            +
            +					$data['postmeta'] = $tmp; 
            +
            +					
            +
            +					if ( $post->post_type == 'attachment' ){
            +						$data['attachment_url'] = wp_get_attachment_url( $post->ID );
            +					}
            +
            +					
            +					$data['thumbnail_id'] = get_post_meta( $post->ID, '_thumbnail_id', true );
            +
            +                    // taxonomy
            +                    $taxonomies = get_object_taxonomies( $post->post_type );
            +
            +                    if ( !empty( $taxonomies ) ) {
            +
            +                        $data['taxonomy'] = array();
            +                        $terms = wp_get_object_terms( $post->ID, $taxonomies );
            +
            +                        foreach ( (array) $terms as $term ) {
            +
            +                            if( $term->taxonomy == 'nav_menu' ){
            +                                continue;
            +                            }
            +
            +                            $t = array(
            +                                $term->taxonomy => array (
            +                                    $term->slug	 => $term->name
            +                                )
            +                            );
            +                            $data['taxonomy'][] = $t;
            +                        }
            +                    }
            +
            +                    $output [] = $data;
            +				}
            +			}
            +	
            +			$export['posts'] = $output;
            +			return $export; 	
            +		}
            +
            +		/**
            +		 * find attachment post id by guid
            +		 */
            +		private function find_image_id_byguid( $image_url ) {
            +			global $wpdb;
            +			$attachment = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE guid LIKE '%".$image_url."%';" );
            +
            +			return isset($attachment[0])?$attachment[0]:0;
            +		}
            +
            +		/**
            +		 * find all images:svg,git,png,jpg  in data setting of elementor
            +		 */
            + 		private function get_images_posts( $ids ){
            + 			$mids = array();
            + 			$images = array();
            +			foreach( $ids as $id ){
            +				if ( get_post_meta( $id, '_elementor_edit_mode', true ) === 'builder' ) {
            +					$data = json_decode( get_post_meta( $id, '_elementor_data', true ), ARRAY_A );
            +					if( $data ){
            +						$string = "start".print_r( $data , true )."end";
            +						$pattern = '~(http.*\.)(jpe?g|png|svg|gif|[tg]iff?|svg)~i';
            +						$m = preg_match_all($pattern,$string,$matches);
            +						if( $matches[0] ){ 	 
            +							foreach( $matches[0] as $img ){
            +								$pattern = '#(/\d+/\d+/(.*))$#';
            +								$a = preg_match( $pattern , $img, $m );
            +								if( isset($m[1]) ){  	///echo '
            ' . print_r( $data, 1 );die;
            +									$_id = $this->find_image_id_byguid( $m[1] );
            +									if( $_id ) {
            +										$mids[$_id] = $_id;
            +									} else {
            +										$images[] = $img;
            +									}	
            +								}
            +							}
            +						}
            +					}
            +				}
            +			}
            +			echo '
             Missing Images:' . print_r( $images , 1 );  //die; 
            +			return $mids;
            + 		}
            +
            +
            + 		public function sample(){
            + 			$data = array();
            + 		
            + 			return $data; 
            + 		}
            + 		
            +
            + 		public function download_images( $attachments, $jcontent ){
            +			
            +			$folder = $this->path .'/'.$this->cfg->folder_source.'/images';  
            +
            +			if( is_dir($folder) ){
            +				$file = new Filesystem();
            +				$file->deleteDirectory( $folder );
            +			}
            + 
            +			if( !is_dir($folder) ){
            +				mkdir( $folder ); 
            +			}
            + 
            +	 		$url = $this->cfg->server_source.'/images/';
            +
            +	 		$replaces = array();
            +			foreach( $attachments  as $attachment ){
            +				$guid = str_replace( $this->server  , $this->oldurl, $attachment['guid'] ) ; 
            +				// $image = file get contents(  $guid );
            +				$image = wp_remote_get(  $guid );
            +				$name = basename( $attachment['guid'] );
            +				$path = $folder.'/'.$name;	
            +				file_put_contents( $path, $image );
            +
            +				$guid 	 = $attachment['guid'];
            +				$newurl  = $url.$name;
            +				$replaces[$guid] = $newurl;
            +			}
            +
            + 			foreach( $replaces as $key => $replace ){  
            + 				$jcontent = $this->_replace_uri( $jcontent, $key, $replace); 
            + 			}
            + 
            + 			return $jcontent;
            +		}	
            +
            +		/**
            +		 * export all sample data
            +		 */
            + 		public function source(){
            +
            + 			// $content = file get contents( $this->path.'/sample/data.json' );
            + 			$content = wp_remote_get( $this->path.'/sample/data.json' );
            +
            + 			$data = json_decode( $content, true );
            + 			
            + 			$file = new Filesystem();
            +
            + 			$content = $this->download_images(  $data['attachments'], $content ); 
            +
            + 			$file = $this->path.'/'.$this->cfg->folder_source.'/data.json';
            +		 	$this->output_file_content( $file,  $content );
            +
            +		 	$zip = new ZipArchive;
            +			if ($zip->open( $this->path.'/'.$this->cfg->folder_source .'/data.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE) === TRUE) {
            +			    $zip->addFile( $file, 'data.json');
            +			    $zip->close();
            +			    echo 'ok';
            +			} else {
            +			    echo 'failed';
            +			}
            + 		}
            +
            +		/**
            +		 * export all sample data
            +		 */
            +		public function data(){
            +
            +			$this->fix_images_parents();
            +			$data = $this->pages();
            +
            +			$data = array_merge_recursive( 
            +				$data,
            +				$this->data_posttypes(),
            +				$this->options(), 
            +				$this->get_more_options(),
            +				$this->sample()			
            +			); 
            + 
            +
            +
            +			$data = apply_filters( 'opaltools_single_wp_cli_exporter', $data , $this->cfg  );
            +			
            +			$file = $this->path.'sample/data.json'; 
            + 			
            +
            + 			/// 
            + 			$attachments = array(); 
            + 			foreach (  $data['attachments'] as $key => $value ) {
            + 				$attachments[$value['id']] = $value; 
            + 			}
            +
            + 			$data['attachments'] = $attachments; 
            + 			
            + 			$content = $this->_replace_uri( json_encode($data , JSON_PRETTY_PRINT ), $this->oldurl, $this->server ); 
            + 			$content = str_replace( $this->cfg->theme, $this->cfg->domain, $content );
            +
            +			$this->output_file_content( $file, $content );
            +
            +			$this->config_samples();
            +			$this->source();
            +		}	
            +
            +		public function fix_images_parents(){
            +			global $wpdb;
            +
            +			$fixs = array(
            +				'product-',
            +				'bg-slider',
            +				'slide-',
            +				'bg-slide'
            +			);
            +
            +			foreach( $fixs  as $fix ) {  
            +				$wpdb->query( "UPDATE wp_posts SET post_parent=0 WHERE post_title LIKE '".$fix."%'" );
            +			}
            +		}
            +	}
            +
            +	WP_CLI::add_command( 'opalestate', new OpalEstate_Command );
            +?>
            diff --git a/inc/email/class-opalesate-approve.php b/inc/email/class-opalesate-approve.php
            new file mode 100755
            index 00000000..00d73846
            --- /dev/null
            +++ b/inc/email/class-opalesate-approve.php
            @@ -0,0 +1,110 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            + 
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +/**
            + * @class   OpalEstate_Send_Email_Notification
            + *
            + * @version 1.0
            + */
            +class OpalEstate_Send_Email_Approve extends OpalEstate_Abstract_Email_Template {
            + 
            +	/**
            +	 *  
            +	 */
            +	public function get_subject () {
            +		$propety_title = '' ;
            +		return sprintf( esc_html__( 'New Property Listing Submitted: {property_name}', 'opalestate-pro' ),  $propety_title );
            +	}
            +
            +	/**
            +	 * get collection of key and value base on tags which using to replace custom tags
            +	 */
            +	public  function set_pros(  $property_id  ){
            +	 	
            +	 	$property 	   = get_post( $property_id );
            +		$user    	   = get_userdata( $property->post_author ); 
            +		$email 		   = get_user_meta( $property->post_author, OPALESTATE_USER_PROFILE_PREFIX . 'email', true ); 
            + 		$email  	   = $email ? $email : $user->data->user_email;
            +
            +		$this->args = array(
            +			'receiver_email'	 => $email,
            +			'user_mail' 		 => $email,
            +			'user_name'			 => $user->display_name,
            +			'submitted_date'	 => $property->post_date,
            +			'property_name'	 	 => $property->post_title,
            +			'property_link'		 => get_permalink( $property_id ),
            +    		'current_time'		=>  date("F j, Y, g:i a"),
            +		); 
            +
            +		return $this->args ;
            +	}
            +
            +	/**
            +	 *  
            +	 */
            +	public function get_content_template() {
            + 		return opalestate_load_template_path( 'emails/request-reviewing' );
            +	}	
            +
            +	/**
            +	 *
            +	 */
            +	public static function get_default_template() {
            +		
            +		return trim(preg_replace('/\t+/', '', "Hi {user_name},
            +
            + Thank you so much for submitting to {site_name}. +
            + We have completed the auditing process for your property '{property_name}' and are pleased to inform you that your submission has been accepted. +
            +
            + Thanks again for your contribution +
            +  
            +
            + This message was sent by {site_link} on {current_time}.")); + } + + /** + * + */ + public function to_email () { + return $this->args ['receiver_email']; + } + + /** + * + */ + public function cc_email () { + return $this->args ['sender_email']; + } + + /** + * + */ + public function get_body() { + + $post = get_post( $this->args['post_id'] ); + + $this->args['email'] = $this->args['receiver_email']; + $this->args['property_link'] = $post->post_title; + + return parent::get_body(); + } +} +?> \ No newline at end of file diff --git a/inc/email/class-opalestate-abs-email-template.php b/inc/email/class-opalestate-abs-email-template.php new file mode 100755 index 00000000..8f7d7c6c --- /dev/null +++ b/inc/email/class-opalestate-abs-email-template.php @@ -0,0 +1,125 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Send_Email_Notification + * + * @version 1.0 + */ +class OpalEstate_Abstract_Email_Template { + + public $args = array(); + + /** + * Get the unique email notification key. + * + * @return string + */ + public function get_key() { + return 'opalestate-notification'; + } + + /** + * Get the friendly name for this email notification. + * + * @return string + */ + public function get_title() { + return esc_html__( 'Admin Notice of Expiring Job Listings', 'opalestate-pro' ); + } + + /** + * Get the description for this email notification. + * + * @type abstract + * @return string + */ + public function get_description() { + return esc_html__( 'Send notices to the site administrator before a job listing expires.', 'opalestate-pro' ); + } + + public function to_email () { + + } + + public function get_content_template() { + + } + + + public function set_args ( $args ) { + return $this->args = $args; + } + + public function replace_tags ( $template ) { + + $args = $this->args; + $default = array( + 'receiver_name' => '', + 'name' => '', + 'receiver_email' => '', + 'property_link' => '', + 'message' => '', + 'site_name' => bloginfo(), + 'site_link' => get_home_url(), + 'current_time' => date("F j, Y, g:i a"), + 'phone' => '' + ); + + $args = array_merge( $default, $args ); + + $tags = array(); + $values = array() ; + + foreach ( $args as $key => $value ) { + $tags[] = "{".$key."}"; + $values[] = $value; + } + + $message = str_replace( $tags, $values, $template ); + + return $message; + } + + public function get_subject () { + + } + + public function from_email() { + return opalestate_get_option( 'from_email' , get_bloginfo( 'admin_email' ) ); + } + + public function from_name() { + return opalestate_get_option('from_name', get_bloginfo( 'name' ) ); + } + + public function get_cc() { + + } + + + public function get_body(){ + + $template = $this->get_content_template(); + return $this->replace_tags( $template ); + } + + public function get_plain_text_body () { + + } +} diff --git a/inc/email/class-opalestate-email-notifycation.php b/inc/email/class-opalestate-email-notifycation.php new file mode 100755 index 00000000..220a7d7d --- /dev/null +++ b/inc/email/class-opalestate-email-notifycation.php @@ -0,0 +1,74 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Send_Email_Notification + * + * @version 1.0 + */ +class OpalEstate_Send_Email_Notification extends OpalEstate_Abstract_Email_Template { + + public $type = ''; + + /** + * Send Email + */ + public function get_subject () { + switch ( $this->type ) { + case 'enquiry': + $subject = html_entity_decode( esc_html__('You got a message enquiry', 'opalestate-pro') ); + break; + + default: + $subject = html_entity_decode( esc_html__('You got a message contact', 'opalestate-pro') ); + break; + } + + return $subject; + } + + /** + * Send Email + */ + public function get_content_template() { + + switch ( $this->type ) { + case 'enquiry': + return opalestate_load_template_path( 'emails/enquiry' ); + break; + + default: + return opalestate_load_template_path( 'emails/contact' ); + break; + } + } + + public function to_email () { + return $this->args ['receiver_email']; + } + + public function cc_email () { + return $this->args ['sender_email']; + } + + public function get_body() { + $this->args['email'] = $this->args['receiver_email']; + return parent::get_body(); + } +} +?> \ No newline at end of file diff --git a/inc/email/class-opalestate-new-submitted.php b/inc/email/class-opalestate-new-submitted.php new file mode 100755 index 00000000..76cf91b6 --- /dev/null +++ b/inc/email/class-opalestate-new-submitted.php @@ -0,0 +1,110 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Send_Email_Notification + * + * @version 1.0 + */ +class OpalEstate_Send_Email_New_Submitted extends OpalEstate_Abstract_Email_Template { + + /** + * Send Email + */ + public function get_subject () { + $propety_title = '' ; + $d = esc_html__( 'New Property Listing Submitted: {property_name}', 'opalestate-pro' ); + $s = opalestate_get_option( 'newproperty_email_subject' , $d ); + return $s; + } + + /** + * get collection of key and value base on tags which using to replace custom tags + */ + public function set_pros( $property_id, $user_id ){ + + $property = get_post( $property_id ); + $user = get_userdata( $property->post_author ); + $email = get_user_meta( $property->post_author, OPALESTATE_USER_PROFILE_PREFIX . 'email', true ); + $email = $email ? $email : $user->data->user_email; + + $this->args = array( + 'receiver_email' => $email, + 'user_mail' => $email, + 'user_name' => $user->display_name, + 'submitted_date' => $property->post_date, + 'property_name' => $property->post_title, + 'property_link' => get_permalink( $property_id ), + 'current_time' => date("F j, Y, g:i a"), + ); + + return $this->args ; + } + + + /** + * Send Email + */ + public function get_content_template() { + + $body = opalestate_get_option( 'newproperty_email_body', self::newproperty_email_body() ); + + return $body; + } + + /** + * Send Email + */ + public static function get_default_template() { + + return trim(preg_replace('/\t+/', '',' + Hi {user_name}, +
            + Thanks you so much for submitting {property_name} at {site_name}:
            + Give us a few moments to make sure that we are got space for you. You will receive another email from us soon. + If this request was made outside of our normal working hours, we may not be able to confirm it until we are open again. +
            + You may review your property at any time by logging in to your client area. +
            + This message was sent by {site_link} on {current_time}.' + ) ); + } + + /** + * Send Email + */ + public function to_email () { + return $this->args ['receiver_email']; + } + + /** + * Send Email + */ + public function cc_email () { + return $this->args ['sender_email']; + } + + /** + * Send Email + */ + public function get_body() { + + return parent::get_body(); + } +} +?> \ No newline at end of file diff --git a/inc/email/class-opalestate-request-viewing.php b/inc/email/class-opalestate-request-viewing.php new file mode 100755 index 00000000..217163a3 --- /dev/null +++ b/inc/email/class-opalestate-request-viewing.php @@ -0,0 +1,70 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class OpalEstate_Send_Email_Notification + * + * @version 1.0 + */ +class OpalEstate_Send_Email_Request_Reviewing extends OpalEstate_Abstract_Email_Template { + + /** + * Send Email + */ + public function get_subject () { + $propety_title = '' ; + return sprintf( esc_html__( 'You have a message request reviewing: %s at', 'opalestate-pro' ), $propety_title ); + } + + /** + * Send Email + */ + public function get_content_template() { + return opalestate_load_template_path( 'emails/request-reviewing' ); + } + + /** + * Send Email + */ + public function to_email () { + return $this->args ['receiver_email']; + } + + /** + * Send Email + */ + public function cc_email () { + return $this->args ['sender_email']; + } + + /** + * Send Email + */ + public function get_body() { + + $post = get_post( $this->args['post_id'] ); + + $this->args['email'] = $this->args['receiver_email']; + $this->args['property_link'] = get_permalink( $post->ID ); + $this->args['property_name'] = $post->post_title; + + + return parent::get_body(); + } +} +?> \ No newline at end of file diff --git a/inc/function-search-fields.php b/inc/function-search-fields.php new file mode 100755 index 00000000..5201a5c5 --- /dev/null +++ b/inc/function-search-fields.php @@ -0,0 +1,129 @@ + + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * Render field template. + * + * @param string $field Field. + * @param string $label Label. + * @param string $type Type. + */ +function opalestate_property_render_field_template( $field, $label, $type = 'select' ) { + $qvalue = isset( $_GET['info'][ $field ] ) ? sanitize_text_field( $_GET['info'][ $field ] ) : ''; + $template = ''; + $template = apply_filters( 'opalestate_property_render_search_field_template', $field, $label ); + $template = apply_filters( 'opalestate_property_' . $field . '_field_template', $template ); + + if ( $template == $field ) { + $template = ''; + } + + if ( empty( $template ) ) { + switch ( $type ) { + case 'input': ?> + +
            + + +
            + + +
            +
            + + ' . esc_html( $label ) . ''; + + $template .= ''; + $template = sprintf( $template, $field, $label ); + + break; + } + } + + echo $template; // WPCS: XSS OK. +} + +/** + * Render area size field. + */ +function opalestate_property_areasize_field_template( $template = '' ) { + $search_min = isset( $_GET['min_area'] ) ? sanitize_text_field( $_GET['min_area'] ) : opalestate_options( 'search_min_area', 0 ); + $search_max = isset( $_GET['max_area'] ) ? sanitize_text_field( $_GET['max_area'] ) : opalestate_options( 'search_max_area', 1000 ); + + $data = [ + 'id' => 'area', + 'unit' => opalestate_options( 'measurement_unit', 'sq ft' ) . ' ', + 'ranger_min' => opalestate_options( 'search_min_area', 0 ), + 'ranger_max' => opalestate_options( 'search_max_area', 1000 ), + 'input_min' => $search_min, + 'input_max' => $search_max, + ]; + + opalesate_property_slide_ranger_template( esc_html__( 'Area', 'opalestate-pro' ), $data ); + + return; +} + +add_filter( "opalestate_property_areasize_field_template", 'opalestate_property_areasize_field_template' ); + +/** + * Render slider ranger template. + * + * @param $label + * @param $data + */ +function opalesate_property_slide_ranger_template( $label, $data ) { + $default = [ + 'id' => 'price', + 'unit' => '', + 'decimals' => 0, + 'ranger_min' => 0, + 'ranger_max' => 1000, + 'input_min' => 0, + 'input_max' => 1000, + 'unit_position' => 'postfix', + 'mode' => 2, + 'start' => '', + ]; + + $data = array_merge( $default, $data ); + + extract( $data ); + ?> + +
            + ' : ''; ?> + + + +
            + + + + + + + +
            + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Array2XML { + + private static $xml = null; + private static $encoding = 'UTF-8'; + + /** + * Initialize the root XML node [optional] + * @param $version + * @param $encoding + * @param $format_output + */ + public static function init($version = '1.0', $encoding = 'UTF-8', $format_output = true) { + self::$xml = new DomDocument($version, $encoding); + self::$xml->formatOutput = $format_output; + self::$encoding = $encoding; + } + + /** + * Convert an Array to XML + * @param string $node_name - name of the root node to be converted + * @param array $arr - aray to be converterd + * @return DomDocument + */ + public static function &createXML($node_name, $arr=array()) { + $xml = self::getXMLRoot(); + $xml->appendChild(self::convert($node_name, $arr)); + + self::$xml = null; // clear the xml node in the class for 2nd time use. + return $xml; + } + + /** + * Convert an Array to XML + * @param string $node_name - name of the root node to be converted + * @param array $arr - aray to be converterd + * @return DOMNode + */ + private static function &convert($node_name, $arr=array()) { + + //print_arr($node_name); + $xml = self::getXMLRoot(); + $node = $xml->createElement($node_name); + + if(is_array($arr)){ + // get the attributes first.; + if(isset($arr['@attributes'])) { + foreach($arr['@attributes'] as $key => $value) { + if(!self::isValidTagName($key)) { + throw new Exception('[Array2XML] Illegal character in attribute name. attribute: '.$key.' in node: '.$node_name); + } + $node->setAttribute($key, self::bool2str($value)); + } + unset($arr['@attributes']); //remove the key from the array once done. + } + + // check if it has a value stored in @value, if yes store the value and return + // else check if its directly stored as string + if(isset($arr['@value'])) { + $node->appendChild($xml->createTextNode(self::bool2str($arr['@value']))); + unset($arr['@value']); //remove the key from the array once done. + //return from recursion, as a note with value cannot have child nodes. + return $node; + } else if(isset($arr['@cdata'])) { + $node->appendChild($xml->createCDATASection(self::bool2str($arr['@cdata']))); + unset($arr['@cdata']); //remove the key from the array once done. + //return from recursion, as a note with cdata cannot have child nodes. + return $node; + } + } + + //create subnodes using recursion + if(is_array($arr)){ + // recurse to get the node for that key + foreach($arr as $key=>$value){ + if(!self::isValidTagName($key)) { + throw new Exception('[Array2XML] Illegal character in tag name. tag: '.$key.' in node: '.$node_name); + } + if(is_array($value) && is_numeric(key($value))) { + // MORE THAN ONE NODE OF ITS KIND; + // if the new array is numeric index, means it is array of nodes of the same kind + // it should follow the parent key name + foreach($value as $k=>$v){ + $node->appendChild(self::convert($key, $v)); + } + } else { + // ONLY ONE NODE OF ITS KIND + $node->appendChild(self::convert($key, $value)); + } + unset($arr[$key]); //remove the key from the array once done. + } + } + + // after we are done with all the keys in the array (if it is one) + // we check if it has any text value, if yes, append it. + if(!is_array($arr)) { + $node->appendChild($xml->createTextNode(self::bool2str($arr))); + } + + return $node; + } + + /* + * Get the root XML node, if there isn't one, create it. + */ + private static function getXMLRoot(){ + if(empty(self::$xml)) { + self::init(); + } + return self::$xml; + } + + /* + * Get string representation of boolean value + */ + private static function bool2str($v){ + //convert boolean to text value. + $v = $v === true ? 'true' : $v; + $v = $v === false ? 'false' : $v; + return $v; + } + + /* + * Check if the tag name or attribute name contains illegal characters + * Ref: http://www.w3.org/TR/xml/#sec-common-syn + */ + private static function isValidTagName($tag){ + $pattern = '/^[a-z_]+[a-z0-9\:\-\.\_]*[^:]*$/i'; + return preg_match($pattern, $tag, $matches) && $matches[0] == $tag; + } +} +?> diff --git a/inc/libraries/wp-session.php b/inc/libraries/wp-session.php new file mode 100755 index 00000000..692b8c16 --- /dev/null +++ b/inc/libraries/wp-session.php @@ -0,0 +1,178 @@ +cache_expiration(); +} + +/** + * Alias of wp_session_write_close() + */ +function wp_session_commit() { + wp_session_write_close(); +} + +/** + * Load a JSON-encoded string into the current session. + * + * @param string $data + */ +function wp_session_decode( $data ) { + $wp_session = WP_Session::get_instance(); + + return $wp_session->json_in( $data ); +} + +/** + * Encode the current session's data as a JSON string. + * + * @return string + */ +function wp_session_encode() { + $wp_session = WP_Session::get_instance(); + + return $wp_session->json_out(); +} + +/** + * Regenerate the session ID. + * + * @param bool $delete_old_session + * + * @return bool + */ +function wp_session_regenerate_id( $delete_old_session = false ) { + $wp_session = WP_Session::get_instance(); + + $wp_session->regenerate_id( $delete_old_session ); + + return true; +} + +/** + * Start new or resume existing session. + * + * Resumes an existing session based on a value sent by the _wp_session cookie. + * + * @return bool + */ +function wp_session_start() { + $wp_session = WP_Session::get_instance(); + do_action( 'wp_session_start' ); + + return $wp_session->session_started(); +} +add_action( 'plugins_loaded', 'wp_session_start' ); + +/** + * Return the current session status. + * + * @return int + */ +function wp_session_status() { + $wp_session = WP_Session::get_instance(); + + if ( $wp_session->session_started() ) { + return PHP_SESSION_ACTIVE; + } + + return PHP_SESSION_NONE; +} + +/** + * Unset all session variables. + */ +function wp_session_unset() { + $wp_session = WP_Session::get_instance(); + + $wp_session->reset(); +} + +/** + * Write session data and end session + */ +function wp_session_write_close() { + $wp_session = WP_Session::get_instance(); + + $wp_session->write_data(); + do_action( 'wp_session_commit' ); +} +add_action( 'shutdown', 'wp_session_write_close' ); + +/** + * Clean up expired sessions by removing data and their expiration entries from + * the WordPress options table. + * + * This method should never be called directly and should instead be triggered as part + * of a scheduled task or cron job. + */ +function wp_session_cleanup() { + global $wpdb; + + if ( defined( 'WP_SETUP_CONFIG' ) ) { + return; + } + + if ( ! defined( 'WP_INSTALLING' ) ) { + $expiration_keys = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE '_wp_session_expires_%'" ); + + $now = current_time( 'timestamp' ); + $expired_sessions = array(); + + foreach( $expiration_keys as $expiration ) { + + // If the session has expired + if ( $now > intval( $expiration->option_value ) ) { + + // Get the session ID by parsing the option_name + $session_id = substr( $expiration->option_name, 20 ); + + if( (int) -1 === (int) $session_id || ! preg_match( '/^[a-f0-9]{32}$/', $session_id ) ) { + continue; + } + + $expired_sessions[] = $expiration->option_name; + $expired_sessions[] = esc_sql( "_wp_session_$session_id" ); + } + } + + // Delete all expired sessions in a single query + if ( ! empty( $expired_sessions ) ) { + $option_names = implode( "','", $expired_sessions ); + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name IN ('$option_names')" ); + } + } + + // Allow other plugins to hook in to the garbage collection process. + do_action( 'wp_session_cleanup' ); +} +add_action( 'wp_session_garbage_collection', 'wp_session_cleanup' ); + +/** + * Register the garbage collector as a twice daily event. + */ +function wp_session_register_garbage_collection() { + if ( ! wp_next_scheduled( 'wp_session_garbage_collection' ) ) { + wp_schedule_event( current_time( 'timestamp' ), 'twicedaily', 'wp_session_garbage_collection' ); + } +} +add_action( 'wp', 'wp_session_register_garbage_collection' ); diff --git a/inc/libraries/wp_session/class-wp-session.php b/inc/libraries/wp_session/class-wp-session.php new file mode 100755 index 00000000..66e20023 --- /dev/null +++ b/inc/libraries/wp_session/class-wp-session.php @@ -0,0 +1,341 @@ +session_id = stripslashes( $_COOKIE[WP_SESSION_COOKIE] ); + } else { + $this->session_id = $this->generate_id(); + } + + $this->expires = time() + intval( apply_filters( 'wp_session_expiration', 24 * 60 ) ); + + $this->read_data(); + + setcookie( WP_SESSION_COOKIE, $this->session_id, $this->expires, COOKIEPATH, COOKIE_DOMAIN ); + } + + /** + * Generate a cryptographically strong unique ID for the session token. + * + * @return string + */ + private function generate_id() { + require_once ABSPATH . 'wp-includes/class-phpass.php'; + $hasher = new PasswordHash( 8, false ); + + return md5( $hasher->get_random_bytes( 32 ) ); + } + + /** + * Read data from a transient for the current session. + * + * Automatically resets the expiration time for the session transient to some time in the future. + * + * @return array + */ + private function read_data() { + $this->touch_session(); + $this->container = get_option( "_wp_session_{$this->session_id}", array() ); + return $this->container; + } + + /** + * Write the data from the current session to the data storage system. + */ + public function write_data() { + $session_list = get_option( '_wp_session_list', array() ); + + $this->touch_session(); + + update_option( "_wp_session_{$this->session_id}", $this->container ); + } + + private function touch_session() { + $session_list = get_option( '_wp_session_list', array() ); + + $session_list[ $this->session_id ] = $this->expires; + + foreach( $session_list as $id => $expires ) { + if ( time() > $this->expires ) { + delete_option( "_wp_session_{$id}" ); + unset( $session_list[$id] ); + } + } + + update_option( '_wp_session_list', $session_list ); + } + + /** + * Output the current container contents as a JSON-encoded string. + * + * @return string + */ + public function json_out() { + return json_encode( $this->container ); + } + + /** + * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents. + * + * @param string $data + * + * @return bool + */ + public function json_in( $data ) { + $array = json_decode( $data ); + + if ( is_array( $array ) ) { + $this->container = $array; + return true; + } + + return false; + } + + /** + * Regenerate the current session's ID. + * + * @param bool $delete_old Flag whether or not to delete the old session data from the server. + */ + public function regenerate_id( $delete_old = false ) { + if ( $delete_old ) { + delete_option( "_wp_session_{$this->session_id}" ); + + $session_list = get_option( '_wp_session_list', array() ); + unset ($session_list[ $this->session_id ] ); + update_option( '_wp_session_list', $session_list ); + } + + $this->session_id = $this->generate_id(); + + setcookie( WP_SESSION_COOKIE, $this->session_id, time() + $this->expires, COOKIEPATH, COOKIE_DOMAIN ); + } + + /** + * Check if a session has been initialized. + * + * @return bool + */ + public function session_started() { + return !!self::$instance; + } + + /** + * Return the read-only cache expiration value. + * + * @return int + */ + public function cache_expiration() { + return $this->expires; + } + + /** + * Flushes all session variables. + */ + public function reset() { + $this->container = array(); + } + + /*****************************************************************/ + /* ArrayAccess Implementation */ + /*****************************************************************/ + + /** + * Whether a offset exists + * + * @link http://php.net/manual/en/arrayaccess.offsetexists.php + * + * @param mixed $offset An offset to check for. + * + * @return boolean true on success or false on failure. + */ + public function offsetExists( $offset ) { + return isset( $this->container[ $offset ]) ; + } + + /** + * Offset to retrieve + * + * @link http://php.net/manual/en/arrayaccess.offsetget.php + * + * @param mixed $offset The offset to retrieve. + * + * @return mixed Can return all value types. + */ + public function offsetGet( $offset ) { + return isset( $this->container[ $offset ] ) ? $this->container[ $offset ] : null; + } + + /** + * Offset to set + * + * @link http://php.net/manual/en/arrayaccess.offsetset.php + * + * @param mixed $offset The offset to assign the value to. + * @param mixed $value The value to set. + * + * @return void + */ + public function offsetSet( $offset, $value ) { + if ( is_null( $offset ) ) { + $this->container[] = $value; + } else { + $this->container[ $offset ] = $value; + } + } + + /** + * Offset to unset + * + * @link http://php.net/manual/en/arrayaccess.offsetunset.php + * + * @param mixed $offset The offset to unset. + * + * @return void + */ + public function offsetUnset( $offset ) { + unset( $this->container[ $offset ] ); + } + + /*****************************************************************/ + /* Iterator Implementation */ + /*****************************************************************/ + + /** + * Current position of the array. + * + * @link http://php.net/manual/en/iterator.current.php + * + * @return mixed + */ + public function current() { + return current( $this->container ); + } + + /** + * Key of the current element. + * + * @link http://php.net/manual/en/iterator.key.php + * + * @return mixed + */ + public function key() { + return key( $this->container ); + } + + /** + * Move the internal point of the container array to the next item + * + * @link http://php.net/manual/en/iterator.next.php + * + * @return void + */ + public function next() { + next( $this->container ); + } + + /** + * Rewind the internal point of the container array. + * + * @link http://php.net/manual/en/iterator.rewind.php + * + * @return void + */ + public function rewind() { + reset( $this->container ); + } + + /** + * Is the current key valid? + * + * @link http://php.net/manual/en/iterator.rewind.php + * + * @return bool + */ + public function valid() { + return $this->offsetExists( $this->key() ); + } + + /*****************************************************************/ + /* Countable Implementation */ + /*****************************************************************/ + + /** + * Get the count of elements in the container array. + * + * @link http://php.net/manual/en/countable.count.php + * + * @return int + */ + public function count() { + return count( $this->container ); + } +} \ No newline at end of file diff --git a/inc/libraries/wp_session/wp-session.php b/inc/libraries/wp_session/wp-session.php new file mode 100755 index 00000000..13910e7d --- /dev/null +++ b/inc/libraries/wp_session/wp-session.php @@ -0,0 +1,118 @@ +cache_expiration(); +} + +/** + * Alias of wp_session_write_close() + */ +function wp_session_commit() { + wp_session_write_close(); +} + +/** + * Load a JSON-encoded string into the current session. + * + * @param string $data + */ +function wp_session_decode( $data ) { + $wp_session = WP_Session::get_instance(); + + return $wp_session->json_in( $data ); +} + +/** + * Encode the current session's data as a JSON string. + * + * @return string + */ +function wp_session_encode() { + $wp_session = WP_Session::get_instance(); + + return $wp_session->json_out(); +} + +/** + * Regenerate the session ID. + * + * @param bool $delete_old_session + * + * @return bool + */ +function wp_session_regenerate_id( $delete_old_session = false ) { + $wp_session = WP_Session::get_instance(); + + $wp_session->regenerate_id( $delete_old_session ); + + return true; +} + +/** + * Start new or resume existing session. + * + * Resumes an existing session based on a value sent by the _wp_session cookie. + * + * @return bool + */ +function wp_session_start() { + $wp_session = WP_Session::get_instance(); + + $wp_session = WP_Session::get_instance(); + do_action( 'wp_session_start' ); + + return $wp_session->session_started(); +} +add_action( 'plugins_loaded', 'wp_session_start' ); + +/** + * Return the current session status. + * + * @return int + */ +function wp_session_status() { + $wp_session = WP_Session::get_instance(); + + if ( $wp_session->session_started() ) { + return PHP_SESSION_ACTIVE; + } + + return PHP_SESSION_NONE; +} + +/** + * Unset all session variables. + */ +function wp_session_unset() { + $wp_session = WP_Session::get_instance(); + + $wp_session->reset(); +} + +/** + * Write session data and end session + */ +function wp_session_write_close() { + $wp_session = WP_Session::get_instance(); + + $wp_session->write_data(); + do_action( 'wp_session_commit' ); +} +add_action( 'shutdown', 'wp_session_write_close' ); \ No newline at end of file diff --git a/inc/message/class-opalestate-message.php b/inc/message/class-opalestate-message.php new file mode 100755 index 00000000..ad5fb2e3 --- /dev/null +++ b/inc/message/class-opalestate-message.php @@ -0,0 +1,757 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * OpalEstate_User_Message Class + * + * @since 1.0.0 + */ +class OpalEstate_User_Message { + + /** + * + */ + protected $user_id = 0; + + protected $is_log; + + /** + * + */ + public static function get_instance() { + static $_instance; + if ( ! $_instance ) { + $_instance = new self(); + } + + return $_instance; + } + + public function get_types() { + + return [ + 'request_view' => '', + 'contact' => '', + 'send_equiry' => '', + ]; + } + + /** + * + */ + public function __construct() { + + add_action( 'init', [ $this, 'init' ] ); + + /// process ajax send message + add_action( 'wp_ajax_send_email_contact', [ $this, 'process_send_email' ] ); + add_action( 'wp_ajax_nopriv_send_email_contact', [ $this, 'process_send_email' ] ); + + // process ajax + add_action( 'wp_ajax_send_email_contact_reply', [ $this, 'process_send_reply_email' ] ); + add_action( 'wp_ajax_nopriv_send_email_contact_reply', [ $this, 'process_send_reply_email' ] ); + + add_filter( 'opalestate_user_content_messages_page', [ $this, 'render_user_content_page' ] ); + } + + /** + * Set values when user logined in system + */ + public function init() { + + global $current_user; + wp_get_current_user(); + + $this->user_id = $current_user->ID; + $this->is_log = opalestate_get_option( 'message_log' ); + } + + /** + * Set values when user logined in system + */ + public function send_equiry( $post, $member ) { + + $default = [ + 'send_equiry_name' => '', + 'action' => '', + 'post_id' => '', + 'sender_id' => '', + 'email' => '', + 'phone' => '', + 'message' => '', + 'message_action' => '', + ]; + $post = array_merge( $default, $post ); + + + $post['property_link'] = (int) $post['post_id'] ? get_permalink( $post['post_id'] ) : get_home_url(); + $post['receive_name'] = $member['name']; + $subject = html_entity_decode( esc_html__( 'You got a message', 'opalestate-pro' ) ); + $post['receiver_name'] = $member['receiver_name']; + + $output = [ + 'subject' => $subject, + 'name' => $member['name'], + 'receiver_email' => $member['receiver_email'], + 'receiver_id' => $member['receiver_id'], + 'sender_id' => get_current_user_id(), + 'sender_email' => $post['email'], + 'phone' => $post['phone'], + 'message' => $post['message'], + 'post_id' => $post['post_id'], + 'type' => 'send_enquiry', + ]; + + if ( $output['sender_id'] == $output['receiver_id'] ) { + // return false; + } + + return $output; + } + + /** + * Set values when user logined in system + */ + public function send_contact( $post ) { + + $member = get_post( $post['post_id'] ); + + if ( $member->post_type == 'opalestate_agent' ) { + $receiver_id = get_post_meta( $member->ID, OPALESTATE_AGENT_PREFIX . 'user_id', true ); + $email = get_post_meta( $member->ID, OPALESTATE_AGENT_PREFIX . 'email', true ); + } else { + $receiver_id = get_post_meta( $member->ID, OPALESTATE_AGENCY_PREFIX . 'user_id', true ); + $email = get_post_meta( $member->ID, OPALESTATE_AGENCY_PREFIX . 'email', true ); + } + + $member = [ + 'receiver_email' => $email, + 'receiver_name' => $member->post_title, + 'receiver_id' => $receiver_id, + ]; + + $default = [ + 'send_equiry_name' => '', + 'action' => '', + 'post_id' => '', + 'sender_id' => '', + 'email' => '', + 'phone' => '', + 'message' => '', + 'message_action' => '', + ]; + $post = array_merge( $default, $post ); + + $post['link'] = (int) $post['post_id'] ? get_permalink( $post['post_id'] ) : get_home_url(); + $post['receive_name'] = $member['name']; + + $subject = html_entity_decode( esc_html__( 'You got a message contact', 'opalestate-pro' ) ); + + $post['receiver_name'] = $member['receiver_name']; + + + $output = [ + 'subject' => $subject, + 'name' => $member['name'], + 'receiver_email' => $member['receiver_email'], + 'receiver_id' => $member['receiver_id'], + 'sender_id' => get_current_user_id(), + 'sender_email' => $post['email'], + 'phone' => $post['phone'], + 'message' => $post['message'], + 'post_id' => $post['post_id'], + 'type' => 'send_contact', + ]; + + if ( $output['sender_id'] == $output['receiver_id'] ) { + // return false; + } + + return $output; + + } + + /** + * Set values when user logined in system + */ + public function get_member_email_data( $post_id ) { + + return opalestate_get_member_email_data( $post_id ); + } + + /** + * Set values when user logined in system + */ + public function process_send_reply_email() { + + if ( isset( $_POST ) && $this->is_log ) { + $id = 2; + $message = $this->get_message( intval( $_POST['message_id'] ) ); + + + if ( $message ) { + + $data = [ + 'message_id' => $message->id, + 'sender_id' => $this->user_id, + 'receiver_id' => $message->sender_id, + 'message' => sanitize_text_field( $_POST['message'] ), + 'created' => current_time( 'mysql', 1 ), + ]; + + $id = $this->insert_reply( $data ); + + $reply = $this->get_reply( $id ); + + $data['data'] = [ + 'created' => $reply->created, + 'message' => $reply->message, + 'avatar' => OpalEstate_User::get_author_picture( $message->sender_id ), + ]; + // send email for user to inbox email. + do_action( 'opalestate_send_email_notifycation', $data ); + $return = [ + 'status' => true, + 'msg' => esc_html__( 'Email Sent successful', 'opalestate-pro' ), + 'heading' => esc_html__( 'Sending Message', 'opalestate-pro' ), + ]; + } + } else { + $return = [ 'status' => false, 'msg' => esc_html__( 'Unable to send a message.', 'opalestate-pro' ), 'heading' => esc_html__( 'Sending Message', 'opalestate-pro' ) ]; + } + + + echo json_encode( $return ); + die(); + + } + + /** + * + */ + public function process_send_email() { + + do_action( 'opalestate_process_send_email_before' ); + + if ( isset( $_POST['type'] ) && $_POST['type'] ) { + + $content = []; + + switch ( trim( $_POST['type'] ) ) { + case 'send_equiry': + if ( wp_verify_nonce( $_POST['message_action'], 'send-enquiry-form' ) ) { + + $member = $this->get_member_email_data( (int) $_POST['post_id'] ); + $content = $this->send_equiry( $_POST, $member ); + } + break; + case 'send_contact': + if ( wp_verify_nonce( $_POST['message_action'], 'send-contact-form' ) ) { + $content = $this->send_contact( $_POST ); + } + break; + default: + break; + } + + if ( $content ) { + + + // only save in db for user only + if ( $content['receiver_id'] > 0 && $this->is_log ) { + $this->insert( $content ); + } + + // send email for user to inbox email. + do_action( 'opalestate_send_email_notifycation', $content ); + } + } + + $return = [ 'status' => false, 'msg' => esc_html__( 'Unable to send a message.', 'opalestate-pro' ) ]; + + echo json_encode( $return ); + die(); + } + + /** + * + */ + public function insert( $data ) { + + global $wpdb; + + $args = [ + 'subject' => '', + 'message' => '', + 'sender_email' => '', + 'phone' => '', + 'sender_id' => '', + 'created' => current_time( 'mysql', 1 ), + 'receiver_id' => '', + 'post_id' => '', + 'type' => '', + ]; + + foreach ( $args as $key => $value ) { + if ( isset( $data[ $key ] ) ) { + $args[ $key ] = $data[ $key ]; + } + } + + $id = $wpdb->insert( $wpdb->prefix . 'opalestate_message', $args ); + + return $wpdb->insert_id; + } + + public function insert_reply( $data ) { + + global $wpdb; + + $args = [ + 'message_id' => '', + 'message' => '', + 'sender_id' => '', + 'created' => current_time( 'mysql', 1 ), + 'receiver_id' => '', + ]; + + foreach ( $args as $key => $value ) { + if ( isset( $data[ $key ] ) ) { + $args[ $key ] = $data[ $key ]; + } + } + + $id = $wpdb->insert( $wpdb->prefix . 'opalestate_message_reply', $args ); + + return $wpdb->insert_id; + } + + public function get_reply( $id ) { + global $wpdb; + + $query = " SELECT * FROM " . $wpdb->prefix . "opalestate_message_reply where id=" . (int) $id; + $reply = $wpdb->get_row( $query ); + + return $reply; + } + + /** + * + */ + public static function install() { + try { + if ( ! function_exists( 'dbDelta' ) ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + } + + global $wpdb; + + $charset_collate = $wpdb->get_charset_collate(); + + $sql = 'CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'opalestate_message' . ' ( + `id` int(11) UNSIGNED NOT NULL, + `subject` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `message` text COLLATE utf8mb4_unicode_ci NOT NULL, + `phone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `sender_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `sender_id` int(11) DEFAULT NULL, + `created` datetime NOT NULL, + `receiver_id` int(11) NOT NULL, + `post_id` int(11) NOT NULL, + `type` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL, + `isread` tinyint(1) NOT NULL + ) ' . $charset_collate; + dbDelta( $sql ); + + /// + + $sql = 'CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'opalestate_message_reply' . ' ( + `id` int(11) NOT NULL, + `message_id` int(11) NOT NULL, + `sender_id` int(11) NOT NULL, + `message` text NOT NULL, + `created` datetime NOT NULL, + `receiver_id` int(11) NOT NULL + ) ' . $charset_collate; + dbDelta( $sql ); + + + } catch ( Exception $e ) { + + } + } + + + /** + * + */ + public function do_delete( $id ) { + + global $wpdb; + if ( $this->user_id ) { + $wpdb->delete( $wpdb->prefix . "opalestate_message", [ "id" => $id, 'user_id' => $this->user_id ], [ '%d' ] ); + } + } + + /** + * + */ + public function get_list( $args = [] ) { + + global $wpdb; + + $default = [ + 'cpage' => 1, + 'items_per_page' => 3, + ]; + + $args = array_merge( $default, $args ); + $items_per_page = $args['items_per_page']; + $offset = ( $args['cpage'] * $items_per_page ) - $items_per_page; + + $query = " SELECT * FROM " . $wpdb->prefix . "opalestate_message where receiver_id=" . $this->user_id . ' OR sender_id=' . $this->user_id; + $query .= ' ORDER BY id DESC LIMIT ' . $offset . ', ' . $items_per_page; + + return $wpdb->get_results( $query ); + } + + public function get_total() { + + global $wpdb; + $query = " SELECT count(1) as total FROM " . $wpdb->prefix . "opalestate_message where receiver_id=" . $this->user_id . ' OR sender_id=' . $this->user_id; + + return $wpdb->get_var( $query ); + } + + /** + * + */ + public function get_message( $id ) { + + global $wpdb; + + $query = " SELECT * FROM " . $wpdb->prefix . "opalestate_message where ( sender_id=" . $this->user_id . " OR receiver_id=" . $this->user_id . ') and id=' . (int) $id; + $message = $wpdb->get_results( $query ); + + if ( isset( $message[0] ) ) { + return $message[0]; + } + + return []; + } + + public function get_replies( $id ) { + + global $wpdb; + + $query = " SELECT * FROM " . $wpdb->prefix . "opalestate_message_reply where message_id=" . (int) $id . ' ORDER BY created '; + $messages = $wpdb->get_results( $query ); + + return $messages; + } + + /** + * + */ + public function is_saved() { + + } + + /** + * + */ + public function get_equiry_form_fields( $msg = '' ) { + + $prefix = ''; + + $id = ''; + $sender_id = ''; + $post_id = get_the_ID(); + $email = ''; + $current_user = wp_get_current_user(); + $name = ''; + + if ( 0 != $current_user->ID ) { + $email = $current_user->user_email; + $name = $current_user->user_firstname . ' ' . $current_user->user_lastname; + $sender_id = $current_user->ID; + } + + $fields = [ + + [ + 'id' => "type", + 'name' => esc_html__( 'Type', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => 'send_equiry', + 'description' => "", + ], + [ + 'id' => "post_id", + 'name' => esc_html__( 'Property ID', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => $post_id, + 'description' => "", + ], + + [ + 'id' => "sender_id", + 'name' => esc_html__( 'Sender ID', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => $sender_id, + 'description' => "", + ], + + [ + 'id' => "{$prefix}name", + 'name' => esc_html__( 'Name', 'opalestate-pro' ), + 'type' => 'text', + 'before_row' => '', + 'required' => 'required', + 'default' => $name, + 'description' => "", + ], + [ + 'id' => "{$prefix}email", + 'name' => esc_html__( 'Email', 'opalestate-pro' ), + 'type' => 'text', + 'default' => $email, + 'description' => "", + 'required' => 'required', + ], + + [ + 'id' => "{$prefix}phone", + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'type' => 'text', + 'description' => "", + 'required' => 'required', + ], + + [ + 'id' => "{$prefix}message", + 'name' => esc_html__( 'Message', 'opalestate-pro' ), + 'type' => 'textarea', + 'description' => "", + 'default' => $msg, + 'required' => 'required', + ], + + ]; + + return $fields; + } + + public function get_reply_form_fields() { + $prefix = ''; + $fields = [ + [ + 'id' => "type", + 'name' => esc_html__( 'Type', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => 'send_contact', + 'description' => "", + ], + [ + 'id' => "{$prefix}message", + 'name' => esc_html__( 'Message', 'opalestate-pro' ), + 'type' => 'textarea', + 'description' => "", + 'required' => 'required', + ], + ]; + + return $fields; + } + + /** + * + */ + public function get_contact_form_fields( $msg = '' ) { + + $prefix = ''; + $id = ''; + $sender_id = ''; + $post_id = get_the_ID(); + $email = ''; + $current_user = wp_get_current_user(); + $name = ''; + + if ( 0 != $current_user->ID ) { + $email = $current_user->user_email; + $name = $current_user->user_firstname . ' ' . $current_user->user_lastname; + $sender_id = $current_user->ID; + } + + $fields = [ + [ + 'id' => "type", + 'name' => esc_html__( 'Type', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => 'send_contact', + 'description' => "", + ], + [ + 'id' => "post_id", + 'name' => esc_html__( 'Property ID', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => $post_id, + 'description' => "", + ], + [ + 'id' => "sender_id", + 'name' => esc_html__( 'Sender ID', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => $sender_id, + 'description' => "", + ], + [ + 'id' => "{$prefix}name", + 'name' => esc_html__( 'Name', 'opalestate-pro' ), + 'type' => 'text', + 'default' => $name, + 'required' => 'required', + 'description' => "", + ], + [ + 'id' => "{$prefix}email", + 'name' => esc_html__( 'Email', 'opalestate-pro' ), + 'type' => 'text', + 'default' => $email, + 'description' => "", + 'required' => 'required', + ], + + [ + 'id' => "{$prefix}phone", + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'type' => 'text', + 'description' => "", + 'required' => 'required', + ], + + [ + 'id' => "{$prefix}message", + 'name' => esc_html__( 'Message', 'opalestate-pro' ), + 'type' => 'textarea', + 'description' => "", + 'default' => $msg, + 'required' => 'required', + ], + + ]; + + return $fields; + } + + public function get_request_review_form_fields( $msg = '' ) { + + $prefix = ''; + $id = ''; + $sender_id = ''; + $post_id = get_the_ID(); + $email = ''; + $current_user = wp_get_current_user(); + $name = ''; + + if ( 0 != $current_user->ID ) { + $email = $current_user->user_email; + $name = $current_user->user_firstname . ' ' . $current_user->user_lastname; + $sender_id = $current_user->ID; + } + + $fields = [ + [ + 'id' => "type", + 'name' => esc_html__( 'Type', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => 'send_request_review', + 'description' => "", + ], + [ + 'id' => "post_id", + 'name' => esc_html__( 'Property ID', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => $post_id, + 'description' => "", + ], + [ + 'id' => "sender_id", + 'name' => esc_html__( 'Sender ID', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => $sender_id, + 'description' => "", + ], + [ + 'id' => "{$prefix}date", + 'name' => esc_html__( 'Schedule', 'opalestate-pro' ), + 'type' => 'date', + 'before_row' => '', + 'required' => 'required', + 'description' => "", + ], + [ + 'id' => "{$prefix}time", + 'name' => esc_html__( 'Time', 'opalestate-pro' ), + 'type' => 'select', + 'options' => opalestate_get_time_lapses(), + 'description' => "", + ], + [ + 'id' => "{$prefix}phone", + 'name' => esc_html__( 'Phone', 'opalestate-pro' ), + 'type' => 'text', + 'description' => "", + 'required' => 'required', + ], + + [ + 'id' => "{$prefix}message", + 'name' => esc_html__( 'Message', 'opalestate-pro' ), + 'type' => 'textarea', + 'description' => "", + 'default' => $msg, + 'required' => 'required', + ], + + ]; + + return $fields; + } + + + public function render_user_content_page() { + + if ( isset( $_GET['message_id'] ) ) { + + $message = $this->get_message( absint( $_GET['message_id'] ) ); + + return opalestate_load_template_path( 'user/read-messages', + [ + 'message' => $message, + 'fields' => $this->get_reply_form_fields(), + 'replies' => $this->get_replies( absint( $_GET['message_id'] ) ), + ] + ); + + } else { + return opalestate_load_template_path( 'user/messages' ); + } + } +} + +OpalEstate_User_Message::get_instance(); diff --git a/inc/message/class-opalestate-request-reviewing.php b/inc/message/class-opalestate-request-reviewing.php new file mode 100755 index 00000000..f1120e02 --- /dev/null +++ b/inc/message/class-opalestate-request-reviewing.php @@ -0,0 +1,141 @@ + + * + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * OpalEstate_User_Message Class + * + * @since 1.0.0 + */ +class OpalEstate_User_Request_Viewing { + + /** + * @var int + */ + protected $user_id = 0; + + /** + * Gets types. + * + * @return array + */ + public function get_types() { + return [ + 'request_view' => '', + 'contact' => '', + 'send_equiry' => '', + ]; + } + + /** + * OpalEstate_User_Request_Viewing constructor. + */ + public function __construct() { + add_action( 'init', [ $this, 'init' ] ); + + /// process ajax send message + add_action( 'wp_ajax_send_email_request_reviewing', [ $this, 'process_send_email' ] ); + add_action( 'wp_ajax_nopriv_send_email_request_reviewing', [ $this, 'process_send_email' ] ); + } + + /** + * Set values when user logined in system + */ + public function init() { + global $current_user; + + wp_get_current_user(); + $this->user_id = $current_user->ID; + } + + /** + * get_member_email_data + * + * @param $post_id + * @return array + */ + public function get_member_email_data( $post_id ) { + return opalestate_get_member_email_data( $post_id ); + } + + /** + * Process send email. + */ + public function process_send_email() { + if ( wp_verify_nonce( $_POST['message_action'], 'property-request-view' ) ) { + $post = $_POST; + $member = $this->get_member_email_data( absint( $post['post_id'] ) ); + + $output = [ + 'subject' => isset( $subject ) && $subject ? esc_html( $subject ) : '', + 'name' => esc_html( $member['receiver_name'] ), + 'receiver_email' => sanitize_email( $member['receiver_email'] ), + 'receiver_id' => sanitize_text_field( $member['receiver_id'] ), + 'sender_id' => get_current_user_id(), + 'sender_email' => sanitize_email( $post['email'] ), + 'phone' => sanitize_text_field( $post['phone'] ), + 'message' => esc_html( $post['message'] ), + 'schedule_time' => sanitize_text_field( $post['time'] ), + 'schedule_date' => sanitize_text_field( $post['date'] ), + 'post_id' => absint( $post['post_id'] ), + ]; + + $this->insert( $output ); + + // insert data into request_reviewing form + do_action( 'opalestate_send_email_request_reviewing', $output ); + } + + $return = [ 'status' => false, 'msg' => esc_html__( 'Unable to send a message.', 'opalestate-pro' ) ]; + echo json_encode( $return ); + die(); + } + + public function insert( $data ) { + + } + + /** + * Install. + */ + public static function install() { + try { + if ( ! function_exists( 'dbDelta' ) ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + } + + global $wpdb; + + $charset_collate = $wpdb->get_charset_collate(); + + $sql = 'CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'opalestate_message' . ' ( + `id` int(11) UNSIGNED NOT NULL, + `subject` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `message` text COLLATE utf8mb4_unicode_ci NOT NULL, + `phone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `sender_email` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `sender_id` int(11) DEFAULT NULL, + `created` datetime NOT NULL, + `receiver_id` int(11) NOT NULL, + `post_id` int(11) NOT NULL, + `type` varchar(250) COLLATE utf8mb4_unicode_ci NOT NULL, + `isread` tinyint(1) NOT NULL + ) ' . $charset_collate; + dbDelta( $sql ); + + } catch ( Exception $e ) { + + } + } +} + +new OpalEstate_User_Request_Viewing(); diff --git a/inc/message/functions.php b/inc/message/functions.php new file mode 100755 index 00000000..e69d125f --- /dev/null +++ b/inc/message/functions.php @@ -0,0 +1,46 @@ + OpalEstate_User_Message::get_instance()->get_list( $args ), + 'total' => OpalEstate_User_Message::get_instance()->get_total( $args ) + ); + } + + function opalestate_get_member_email_data( $post_id ){ + + $output = array(); + $type = get_post_meta( $post_id, OPALESTATE_PROPERTY_PREFIX . 'author_type', true ); + + $receiver_id = 0; + switch ( $type ) { + + case 'agent': + $related_id = get_post_meta( $post_id, OPALESTATE_PROPERTY_PREFIX . 'related_id', true ); + $post = get_post( $related_id ); + $name = $post->post_title; + $email = get_post_meta( $related_id, OPALESTATE_AGENT_PREFIX . 'email', true ); + break; + + case 'agency': + $related_id = get_post_meta( $post_id, OPALESTATE_PROPERTY_PREFIX . 'related_id', true ); + $agent = get_post( $related_id ); + $name = $agent->post_title; + $email = get_post_meta( $related_id, OPALESTATE_AGENCY_PREFIX . 'email', true ); + break; + default: + $post = get_post( $post_id ); + $user = get_user_by( 'id', $post->post_author ); + $email = $user->data->user_email; + $name = $user->data->display_name; + $receiver_id = $post->post_author; + + break; + } + + return $output = array( + 'receiver_email' => $email, + 'receiver_name' => $name, + 'receiver_id' => $receiver_id + ); + } +?> \ No newline at end of file diff --git a/inc/mixes-functions.php b/inc/mixes-functions.php new file mode 100755 index 00000000..1bd5e9e7 --- /dev/null +++ b/inc/mixes-functions.php @@ -0,0 +1,1134 @@ + + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * Output message json. + * + * @param bool $result + * @param string $message + * @param array $args + * @param bool $return + * @return false|mixed|string|void + */ +function opalestate_output_msg_json( $result = false, $message = '', $args = [], $return = false ) { + $out = new stdClass(); + $out->status = $result; + $out->message = $message; + if ( $args ) { + foreach ( $args as $key => $arg ) { + $out->$key = $arg; + } + } + if ( $return ) { + return json_encode( $out ); + } else { + echo json_encode( $out ); + die; + } +} + +/** + * Process upload images for properties + */ +function opalesate_upload_image( $submitted_file, $parent_id = 0 ) { + + // do_action( 'opalestate_before_process_ajax_upload_file' ); + + require_once ABSPATH . 'wp-admin/includes/image.php'; + require_once ABSPATH . 'wp-admin/includes/file.php'; + require_once ABSPATH . 'wp-admin/includes/media.php'; + + $uploaded_image = wp_handle_upload( $submitted_file, + [ 'test_form' => false ] ); //Handle PHP uploads in WordPress, sanitizing file names, checking extensions for mime type, and moving the file to the appropriate directory within the uploads directory. + + if ( isset( $uploaded_image['file'] ) ) { + $file_name = basename( $submitted_file['name'] ); + $file_type = wp_check_filetype( $uploaded_image['file'] ); //Retrieve the file type from the file name. + + // Prepare an array of post data for the attachment. + $attachment_details = [ + 'guid' => $uploaded_image['url'], + 'post_mime_type' => $file_type['type'], + 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_name ) ), + 'post_content' => '', + 'post_status' => 'inherit', + ]; + + $attach_id = wp_insert_attachment( $attachment_details, $uploaded_image['file'], $parent_id ); // This function inserts an attachment into the media library + $attach_data = wp_generate_attachment_metadata( $attach_id, + $uploaded_image['file'] ); // This function generates metadata for an image attachment. It also creates a thumbnail and other intermediate sizes of the image attachment based on the sizes defined + wp_update_attachment_metadata( $attach_id, $attach_data ); // Update metadata for an attachment. + + $thumbnail_url = opalestate_get_upload_image_url( $attach_data ); + + $ajax_response = [ + 'success' => true, + 'url' => $thumbnail_url, + 'attachment_id' => $attach_id, + ]; + + update_post_meta( $attach_id, '_pending_to_use_', 1 ); + + return $ajax_response; + + } + + return []; +} + +/** + * + */ +function opalestate_get_time_lapses( $lapse = 15 ) { + + $output = []; + $start = '12:00AM'; + $end = '11:59PM'; + $interval = '+' . $lapse . ' minutes'; + + $start_str = strtotime( $start ); + $end_str = strtotime( $end ); + $now_str = $start_str; + + while ( $now_str <= $end_str ) { + $output[ date( 'h:i a', $now_str ) ] = date( 'h:i A', $now_str ); + $now_str = strtotime( $interval, $now_str ); + } + + return $output; +} + + +function is_single_property() { + global $post; + + $post_type = get_post_type(); + + return $post_type == 'opalestate_property' && is_single(); +} + +function is_single_agent() { + global $post; + + $post_type = get_post_type(); + + return $post_type == 'opalestate_agent' && is_single(); +} + +function is_single_agency() { + global $post; + + $post_type = get_post_type(); + + return $post_type == 'opalestate_agency' && is_single(); +} + +/** + * Gets search form styles. + * + * @return array + */ +function opalestate_search_properties_form_styles() { + return apply_filters( 'opalestate_search_properties_form_styles', [ + 'search-form-h' => esc_html__( 'Advanced V1 Form', 'opalestate-pro' ), + 'advanced-v2' => esc_html__( 'Advanced V2 Form', 'opalestate-pro' ), + 'advanced-v3' => esc_html__( 'Advanced V3 Form', 'opalestate-pro' ), + 'advanced-v4' => esc_html__( 'Advanced V4 Form', 'opalestate-pro' ), + 'advanced-v5' => esc_html__( 'Advanced V5 Form', 'opalestate-pro' ), + 'advanced-v6' => esc_html__( 'Advanced V6 Form', 'opalestate-pro' ), + 'search-form-v' => esc_html__( 'Vertical Advanced Form', 'opalestate-pro' ), + 'search-form-v2' => esc_html__( 'Vertical Advanced V2 Form', 'opalestate-pro' ), + 'search-form-v3' => esc_html__( 'Vertical Advanced V3 Form', 'opalestate-pro' ), + 'simple-city' => esc_html__( 'Simple City Form', 'opalestate-pro' ), + 'simple-keyword' => esc_html__( 'Simple Keyword Form', 'opalestate-pro' ), + 'collapse-city' => esc_html__( 'Collapse City Form', 'opalestate-pro' ), + 'collapse-keyword' => esc_html__( 'Collapse Keyword Form', 'opalestate-pro' ), + ] ); +} + +/** + * Gets loop property layouts. + * + * @return array + */ +function opalestate_get_loop_property_layouts() { + return apply_filters( 'opalestate_get_loop_property_layouts', [ + 'grid' => esc_html__( 'Grid', 'opalestate-pro' ), + 'grid-v2' => esc_html__( 'Grid v2', 'opalestate-pro' ), + 'grid-v3' => esc_html__( 'Grid v3', 'opalestate-pro' ), + 'list' => esc_html__( 'List', 'opalestate-pro' ), + 'list-v2' => esc_html__( 'List v2', 'opalestate-pro' ), + 'mark-hover' => esc_html__( 'Mark hover', 'opalestate-pro' ), + ] ); +} + +/** + * Gets loop property grid layouts. + * + * @return array + */ +function opalestate_get_loop_property_grid_layouts() { + return apply_filters( 'opalestate_get_loop_property_grid_layouts', [ + 'grid' => esc_html__( 'Grid', 'opalestate-pro' ), + 'grid-v2' => esc_html__( 'Grid v2', 'opalestate-pro' ), + 'grid-v3' => esc_html__( 'Grid v3', 'opalestate-pro' ), + 'mark-hover' => esc_html__( 'Mark hover', 'opalestate-pro' ), + ] ); +} + +/** + * Gets loop property list layouts. + * + * @return array + */ +function opalestate_get_loop_property_list_layouts() { + return apply_filters( 'opalestate_get_loop_property_list_layouts', [ + 'list' => esc_html__( 'List', 'opalestate-pro' ), + 'list-v2' => esc_html__( 'List v2', 'opalestate-pro' ), + ] ); +} + +function opalestate_get_map_api_uri() { + + $key = opalestate_options( 'google_map_api_keys' ) ? + opalestate_options( 'google_map_api_keys' ) : 'AIzaSyAvJkbm23fhVAYcbdeVB0nkHjZmDeZ62bc'; + + $api = 'https://maps.googleapis.com/maps/api/js?key=' . $key . '&libraries=geometry,places,drawing&ver=5.2.2'; + $api = apply_filters( 'opalestate_google_map_api_uri', $api ); + + return $api; +} + +function opalestate_get_map_search_api_uri( $address ) { + + $key = opalestate_options( 'google_map_api_keys' ) ? + opalestate_options( 'google_map_api_keys' ) : 'AIzaSyAvJkbm23fhVAYcbdeVB0nkHjZmDeZ62bc'; + + $api = "https://maps.googleapis.com/maps/api/geocode/json?address={$address}&key={$key}"; + + return $api; +} + +function opalestate_is_setting_enabled( $value, $compare_with = null ) { + if ( ! is_null( $compare_with ) ) { + + if ( is_array( $compare_with ) ) { + // Output. + return in_array( $value, $compare_with ); + } + + // Output. + return ( $value === $compare_with ); + } + + return ( in_array( $value, [ 'enabled', 'on', 'yes' ] ) ? true : false ); +} + + +function opalestate_get_dashdoard_page_uri() { + return home_url(); +} + + +if ( ! function_exists( 'opalestate_is_ajax_request' ) ) { + function opalestate_is_ajax_request() { + return defined( 'DOING_AJAX' ) && DOING_AJAX; + } +} + +if ( ! function_exists( 'opalmembership_add_notice' ) ) { + function opalestate_add_notice( $type = 'error', $message = '' ) { + if ( ! $type || ! $message ) { + return; + } + $notices = OpalEstate()->session->get( 'notices', [] ); + if ( ! isset( $notices[ $type ] ) ) { + $notices[ $type ] = []; + } + $notices[ $type ][] = $message; + OpalEstate()->session->set( 'notices', $notices ); + } +} + + +if ( ! function_exists( 'opalestate_print_notices' ) ) { + + /** + * print all notices + */ + function opalestate_print_notices() { + + $notices = OpalEstate()->session->get( 'notices', [] ); + if ( empty( $notices ) ) { + return; + } + ob_start(); + foreach ( $notices as $type => $messages ) { + echo opalestate_load_template_path( 'notices/' . $type, [ 'messages' => $messages ] ); + } + OpalEstate()->session->set( 'notices', [] ); + echo ob_get_clean(); + } +} + + +function opalestate_user_roles_by_user_id( $user_id ) { + $user = get_userdata( $user_id ); + + return empty( $user ) ? [] : $user->roles; +} + +/** + * Featured Image Sizes + */ +function opalestate_get_featured_image_sizes() { + global $_wp_additional_image_sizes; + $sizes = [ 'full' => esc_html__( 'Orginal Size', 'opalestate-pro' ) ]; + + foreach ( get_intermediate_image_sizes() as $_size ) { + + if ( in_array( $_size, [ 'thumbnail', 'medium', 'medium_large', 'large' ] ) ) { + $sizes[ $_size ] = $_size . ' - ' . get_option( "{$_size}_size_w" ) . 'x' . get_option( "{$_size}_size_h" ); + } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) { + $sizes[ $_size ] = $_size . ' - ' . $_wp_additional_image_sizes[ $_size ]['width'] . 'x' . $_wp_additional_image_sizes[ $_size ]['height']; + } + + } + + return apply_filters( 'opalestate_get_featured_image_sizes', $sizes ); +} + +/** + * Gets register page uri. + * + * @return string + */ +function opalestate_get_register_page_uri() { + global $opalmembership_options; + $register_page = isset( $opalmembership_options['register_page'] ) ? get_permalink( absint( $opalmembership_options['register_page'] ) ) : get_bloginfo( 'url' ); + + return apply_filters( 'opalestate_get_register_page_uri', $register_page ); +} + +/** + * Gets search agency uri. + * + * @return false|string + */ +function opalestate_search_agency_uri() { + return get_post_type_archive_link( 'opalestate_agency' ); +} + +/** + * Gets current uri. + * + * @return string + */ +function opalestate_get_current_uri() { + global $wp; + + $current_url = home_url( add_query_arg( [], $wp->request ) ); + + return $current_url; +} + +/** + * Gets URL sort mode. + * + * @param string $mode + * @return string + */ +function opalestate_get_url_sort_mode( $mode = "" ) { + global $wp; + + $get = []; + + if ( isset( $_GET ) ) { + $get = $_GET; + } + $get['display'] = $mode; + $current_url = home_url( add_query_arg( [ $get ], $wp->request ) ); + + return $current_url; +} + +/** + * + */ +function opalestate_search_agent_uri() { + global $opalestate_options; + + $search_agents = isset( $opalestate_options['search_agents'] ) ? get_permalink( absint( $opalestate_options['search_agents'] ) ) : opalestate_get_current_uri(); + + return apply_filters( 'opalestate_get_search_agents_page_uri', $search_agents ); +} + +/** + * + */ +function opalestate_get_session_location_val() { + return isset( $_SESSION['set_location'] ) ? $_SESSION['set_location'] : 0; +} + +function opalestate_get_location_active() { + $location = opalestate_get_session_location_val(); + if ( ! is_numeric( $location ) ) { + $term = get_term_by( 'slug', $location, 'opalestate_location' ); + $name = is_object( $term ) ? $term->name : esc_html__( 'Your Location', 'opalestate-pro' ); + + return $name; + } else { + return esc_html__( 'Your Location', 'opalestate-pro' ); + } +} + +function opalestate_get_upload_image_url( $attach_data ) { + $upload_dir = wp_upload_dir(); + $image_path_array = explode( '/', $attach_data['file'] ); + $image_path_array = array_slice( $image_path_array, 0, count( $image_path_array ) - 1 ); + $image_path = implode( '/', $image_path_array ); + $thumbnail_name = null; + if ( isset( $attach_data['sizes']['user-image'] ) ) { + $thumbnail_name = $attach_data['sizes']['user-image']['file']; + } elseif ( isset( $attach_data['sizes']['thumbnail']['file'] ) ) { + $thumbnail_name = $attach_data['sizes']['thumbnail']['file']; + } else { + return $upload_dir['baseurl'] . '/' . $attach_data['file']; + } + + return $upload_dir['baseurl'] . '/' . $image_path . '/' . $thumbnail_name; +} + +function opalestate_update_attachement_used( $attachment_id ) { + +} + +/** + * batch including all files in a path. + * + * @param String $path : PATH_DIR/*.php or PATH_DIR with $ifiles not empty + */ +function opalestate_includes( $path, $ifiles = [] ) { + if ( ! empty( $ifiles ) ) { + foreach ( $ifiles as $key => $file ) { + $file = $path . '/' . $file; + if ( is_file( $file ) ) { + require( $file ); + } + } + } else { + $files = glob( $path ); + foreach ( $files as $key => $file ) { + if ( is_file( $file ) ) { + require( $file ); + } + } + } +} + +/** + * Gets property. + * + * @param $id + * @return \Opalestate_Property + */ +function opalesetate_property( $id ) { + global $property; + + $property = new Opalestate_Property( $id ); + + return $property; +} + +/** + * Gets agency + * + * @param $id + * @return \Opalestate_Agency + */ +function opalesetate_agency( $id ) { + global $agency; + + $agency = new Opalestate_Agency( $id ); + + return $agency; +} + +/** + * Gets agent. + * + * @param $id + * @return \Opalestate_Agent + */ +function opalesetate_agent( $id ) { + global $agent; + + $agent = new Opalestate_Agent( $id ); + + return $agent; +} + +/** + * Gets opalestate options. + * + * @param string $key + * @param string $default + * @return mixed|void + */ +function opalestate_options( $key, $default = '' ) { + global $opalestate_options; + + $value = isset( $opalestate_options[ $key ] ) ? $opalestate_options[ $key ] : $default; + $value = apply_filters( 'opalestate_option_', $value, $key, $default ); + + return apply_filters( 'opalestate_option_' . $key, $value, $key, $default ); +} + +/** + * Gets image placeholder. + * + * @param string $size + * @param bool $url + * @return string + */ +function opalestate_get_image_placeholder( $size = '', $url = false ) { + $src = opalestate_get_image_placeholder_src(); + + $size = is_string( $size ) ? $size : ''; + + if ( $url ) { + return esc_url( $src ); + } + + return '' . sprintf( esc_html__( 'Placeholder %s', 'opalestate-pro' ), $size ) . ''; +} + +function opalestate_get_image_placeholder_src() { + return OPALESTATE_PLUGIN_URL . 'assets/images/placeholder.png'; +} + +/** + * Get User IP + * + * Returns the IP address of the current visitor + * + * @return string $ip User's IP address + */ +function opalestate_get_ip() { + $ip = '127.0.0.1'; + + if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) { + //check ip from share internet + $ip = $_SERVER['HTTP_CLIENT_IP']; + } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { + //to check ip is pass from proxy + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { + $ip = $_SERVER['REMOTE_ADDR']; + } + + return apply_filters( 'opalestate_get_ip', $ip ); +} + +/** + * Gets currencies. + * + * @return array + */ +function opalestate_get_currencies() { + $currencies = [ + 'AED' => esc_html__( 'United Arab Emirates dirham', 'opalestate-pro' ), + 'AFN' => esc_html__( 'Afghan afghani', 'opalestate-pro' ), + 'ALL' => esc_html__( 'Albanian lek', 'opalestate-pro' ), + 'AMD' => esc_html__( 'Armenian dram', 'opalestate-pro' ), + 'ANG' => esc_html__( 'Netherlands Antillean guilder', 'opalestate-pro' ), + 'AOA' => esc_html__( 'Angolan kwanza', 'opalestate-pro' ), + 'ARS' => esc_html__( 'Argentine peso', 'opalestate-pro' ), + 'AUD' => esc_html__( 'Australian dollar', 'opalestate-pro' ), + 'AWG' => esc_html__( 'Aruban florin', 'opalestate-pro' ), + 'AZN' => esc_html__( 'Azerbaijani manat', 'opalestate-pro' ), + 'BAM' => esc_html__( 'Bosnia and Herzegovina convertible mark', 'opalestate-pro' ), + 'BBD' => esc_html__( 'Barbadian dollar', 'opalestate-pro' ), + 'BDT' => esc_html__( 'Bangladeshi taka', 'opalestate-pro' ), + 'BGN' => esc_html__( 'Bulgarian lev', 'opalestate-pro' ), + 'BHD' => esc_html__( 'Bahraini dinar', 'opalestate-pro' ), + 'BIF' => esc_html__( 'Burundian franc', 'opalestate-pro' ), + 'BMD' => esc_html__( 'Bermudian dollar', 'opalestate-pro' ), + 'BND' => esc_html__( 'Brunei dollar', 'opalestate-pro' ), + 'BOB' => esc_html__( 'Bolivian boliviano', 'opalestate-pro' ), + 'BRL' => esc_html__( 'Brazilian real', 'opalestate-pro' ), + 'BSD' => esc_html__( 'Bahamian dollar', 'opalestate-pro' ), + 'BTC' => esc_html__( 'Bitcoin', 'opalestate-pro' ), + 'BTN' => esc_html__( 'Bhutanese ngultrum', 'opalestate-pro' ), + 'BWP' => esc_html__( 'Botswana pula', 'opalestate-pro' ), + 'BYR' => esc_html__( 'Belarusian ruble', 'opalestate-pro' ), + 'BZD' => esc_html__( 'Belize dollar', 'opalestate-pro' ), + 'CAD' => esc_html__( 'Canadian dollar', 'opalestate-pro' ), + 'CDF' => esc_html__( 'Congolese franc', 'opalestate-pro' ), + 'CHF' => esc_html__( 'Swiss franc', 'opalestate-pro' ), + 'CLP' => esc_html__( 'Chilean peso', 'opalestate-pro' ), + 'CNY' => esc_html__( 'Chinese yuan', 'opalestate-pro' ), + 'COP' => esc_html__( 'Colombian peso', 'opalestate-pro' ), + 'CRC' => esc_html__( 'Costa Rican colón', 'opalestate-pro' ), + 'CUC' => esc_html__( 'Cuban convertible peso', 'opalestate-pro' ), + 'CUP' => esc_html__( 'Cuban peso', 'opalestate-pro' ), + 'CVE' => esc_html__( 'Cape Verdean escudo', 'opalestate-pro' ), + 'CZK' => esc_html__( 'Czech koruna', 'opalestate-pro' ), + 'DJF' => esc_html__( 'Djiboutian franc', 'opalestate-pro' ), + 'DKK' => esc_html__( 'Danish krone', 'opalestate-pro' ), + 'DOP' => esc_html__( 'Dominican peso', 'opalestate-pro' ), + 'DZD' => esc_html__( 'Algerian dinar', 'opalestate-pro' ), + 'EGP' => esc_html__( 'Egyptian pound', 'opalestate-pro' ), + 'ERN' => esc_html__( 'Eritrean nakfa', 'opalestate-pro' ), + 'ETB' => esc_html__( 'Ethiopian birr', 'opalestate-pro' ), + 'EUR' => esc_html__( 'Euro', 'opalestate-pro' ), + 'FJD' => esc_html__( 'Fijian dollar', 'opalestate-pro' ), + 'FKP' => esc_html__( 'Falkland Islands pound', 'opalestate-pro' ), + 'GBP' => esc_html__( 'Pound sterling', 'opalestate-pro' ), + 'GEL' => esc_html__( 'Georgian lari', 'opalestate-pro' ), + 'GGP' => esc_html__( 'Guernsey pound', 'opalestate-pro' ), + 'GHS' => esc_html__( 'Ghana cedi', 'opalestate-pro' ), + 'GIP' => esc_html__( 'Gibraltar pound', 'opalestate-pro' ), + 'GMD' => esc_html__( 'Gambian dalasi', 'opalestate-pro' ), + 'GNF' => esc_html__( 'Guinean franc', 'opalestate-pro' ), + 'GTQ' => esc_html__( 'Guatemalan quetzal', 'opalestate-pro' ), + 'GYD' => esc_html__( 'Guyanese dollar', 'opalestate-pro' ), + 'HKD' => esc_html__( 'Hong Kong dollar', 'opalestate-pro' ), + 'HNL' => esc_html__( 'Honduran lempira', 'opalestate-pro' ), + 'HRK' => esc_html__( 'Croatian kuna', 'opalestate-pro' ), + 'HTG' => esc_html__( 'Haitian gourde', 'opalestate-pro' ), + 'HUF' => esc_html__( 'Hungarian forint', 'opalestate-pro' ), + 'IDR' => esc_html__( 'Indonesian rupiah', 'opalestate-pro' ), + 'ILS' => esc_html__( 'Israeli new shekel', 'opalestate-pro' ), + 'IMP' => esc_html__( 'Manx pound', 'opalestate-pro' ), + 'INR' => esc_html__( 'Indian rupee', 'opalestate-pro' ), + 'IQD' => esc_html__( 'Iraqi dinar', 'opalestate-pro' ), + 'IRR' => esc_html__( 'Iranian rial', 'opalestate-pro' ), + 'ISK' => esc_html__( 'Icelandic króna', 'opalestate-pro' ), + 'JEP' => esc_html__( 'Jersey pound', 'opalestate-pro' ), + 'JMD' => esc_html__( 'Jamaican dollar', 'opalestate-pro' ), + 'JOD' => esc_html__( 'Jordanian dinar', 'opalestate-pro' ), + 'JPY' => esc_html__( 'Japanese yen', 'opalestate-pro' ), + 'KES' => esc_html__( 'Kenyan shilling', 'opalestate-pro' ), + 'KGS' => esc_html__( 'Kyrgyzstani som', 'opalestate-pro' ), + 'KHR' => esc_html__( 'Cambodian riel', 'opalestate-pro' ), + 'KMF' => esc_html__( 'Comorian franc', 'opalestate-pro' ), + 'KPW' => esc_html__( 'North Korean won', 'opalestate-pro' ), + 'KRW' => esc_html__( 'South Korean won', 'opalestate-pro' ), + 'KWD' => esc_html__( 'Kuwaiti dinar', 'opalestate-pro' ), + 'KYD' => esc_html__( 'Cayman Islands dollar', 'opalestate-pro' ), + 'KZT' => esc_html__( 'Kazakhstani tenge', 'opalestate-pro' ), + 'LAK' => esc_html__( 'Lao kip', 'opalestate-pro' ), + 'LBP' => esc_html__( 'Lebanese pound', 'opalestate-pro' ), + 'LKR' => esc_html__( 'Sri Lankan rupee', 'opalestate-pro' ), + 'LRD' => esc_html__( 'Liberian dollar', 'opalestate-pro' ), + 'LSL' => esc_html__( 'Lesotho loti', 'opalestate-pro' ), + 'LYD' => esc_html__( 'Libyan dinar', 'opalestate-pro' ), + 'MAD' => esc_html__( 'Moroccan dirham', 'opalestate-pro' ), + 'MDL' => esc_html__( 'Moldovan leu', 'opalestate-pro' ), + 'MGA' => esc_html__( 'Malagasy ariary', 'opalestate-pro' ), + 'MKD' => esc_html__( 'Macedonian denar', 'opalestate-pro' ), + 'MMK' => esc_html__( 'Burmese kyat', 'opalestate-pro' ), + 'MNT' => esc_html__( 'Mongolian tögrög', 'opalestate-pro' ), + 'MOP' => esc_html__( 'Macanese pataca', 'opalestate-pro' ), + 'MRO' => esc_html__( 'Mauritanian ouguiya', 'opalestate-pro' ), + 'MUR' => esc_html__( 'Mauritian rupee', 'opalestate-pro' ), + 'MVR' => esc_html__( 'Maldivian rufiyaa', 'opalestate-pro' ), + 'MWK' => esc_html__( 'Malawian kwacha', 'opalestate-pro' ), + 'MXN' => esc_html__( 'Mexican peso', 'opalestate-pro' ), + 'MYR' => esc_html__( 'Malaysian ringgit', 'opalestate-pro' ), + 'MZN' => esc_html__( 'Mozambican metical', 'opalestate-pro' ), + 'NAD' => esc_html__( 'Namibian dollar', 'opalestate-pro' ), + 'NGN' => esc_html__( 'Nigerian naira', 'opalestate-pro' ), + 'NIO' => esc_html__( 'Nicaraguan córdoba', 'opalestate-pro' ), + 'NOK' => esc_html__( 'Norwegian krone', 'opalestate-pro' ), + 'NPR' => esc_html__( 'Nepalese rupee', 'opalestate-pro' ), + 'NZD' => esc_html__( 'New Zealand dollar', 'opalestate-pro' ), + 'OMR' => esc_html__( 'Omani rial', 'opalestate-pro' ), + 'PAB' => esc_html__( 'Panamanian balboa', 'opalestate-pro' ), + 'PEN' => esc_html__( 'Peruvian nuevo sol', 'opalestate-pro' ), + 'PGK' => esc_html__( 'Papua New Guinean kina', 'opalestate-pro' ), + 'PHP' => esc_html__( 'Philippine peso', 'opalestate-pro' ), + 'PKR' => esc_html__( 'Pakistani rupee', 'opalestate-pro' ), + 'PLN' => esc_html__( 'Polish złoty', 'opalestate-pro' ), + 'PRB' => esc_html__( 'Transnistrian ruble', 'opalestate-pro' ), + 'PYG' => esc_html__( 'Paraguayan guaraní', 'opalestate-pro' ), + 'QAR' => esc_html__( 'Qatari riyal', 'opalestate-pro' ), + 'RON' => esc_html__( 'Romanian leu', 'opalestate-pro' ), + 'RSD' => esc_html__( 'Serbian dinar', 'opalestate-pro' ), + 'RUB' => esc_html__( 'Russian ruble', 'opalestate-pro' ), + 'RWF' => esc_html__( 'Rwandan franc', 'opalestate-pro' ), + 'SAR' => esc_html__( 'Saudi riyal', 'opalestate-pro' ), + 'SBD' => esc_html__( 'Solomon Islands dollar', 'opalestate-pro' ), + 'SCR' => esc_html__( 'Seychellois rupee', 'opalestate-pro' ), + 'SDG' => esc_html__( 'Sudanese pound', 'opalestate-pro' ), + 'SEK' => esc_html__( 'Swedish krona', 'opalestate-pro' ), + 'SGD' => esc_html__( 'Singapore dollar', 'opalestate-pro' ), + 'SHP' => esc_html__( 'Saint Helena pound', 'opalestate-pro' ), + 'SLL' => esc_html__( 'Sierra Leonean leone', 'opalestate-pro' ), + 'SOS' => esc_html__( 'Somali shilling', 'opalestate-pro' ), + 'SRD' => esc_html__( 'Surinamese dollar', 'opalestate-pro' ), + 'SSP' => esc_html__( 'South Sudanese pound', 'opalestate-pro' ), + 'STD' => esc_html__( 'São Tomé and Príncipe dobra', 'opalestate-pro' ), + 'SYP' => esc_html__( 'Syrian pound', 'opalestate-pro' ), + 'SZL' => esc_html__( 'Swazi lilangeni', 'opalestate-pro' ), + 'THB' => esc_html__( 'Thai baht', 'opalestate-pro' ), + 'TJS' => esc_html__( 'Tajikistani somoni', 'opalestate-pro' ), + 'TMT' => esc_html__( 'Turkmenistan manat', 'opalestate-pro' ), + 'TND' => esc_html__( 'Tunisian dinar', 'opalestate-pro' ), + 'TOP' => esc_html__( 'Tongan paʻanga', 'opalestate-pro' ), + 'TRY' => esc_html__( 'Turkish lira', 'opalestate-pro' ), + 'TTD' => esc_html__( 'Trinidad and Tobago dollar', 'opalestate-pro' ), + 'TWD' => esc_html__( 'New Taiwan dollar', 'opalestate-pro' ), + 'TZS' => esc_html__( 'Tanzanian shilling', 'opalestate-pro' ), + 'UAH' => esc_html__( 'Ukrainian hryvnia', 'opalestate-pro' ), + 'UGX' => esc_html__( 'Ugandan shilling', 'opalestate-pro' ), + 'USD' => esc_html__( 'United States dollar', 'opalestate-pro' ), + 'UYU' => esc_html__( 'Uruguayan peso', 'opalestate-pro' ), + 'UZS' => esc_html__( 'Uzbekistani som', 'opalestate-pro' ), + 'VEF' => esc_html__( 'Venezuelan bolívar', 'opalestate-pro' ), + 'VND' => esc_html__( 'Vietnamese đồng', 'opalestate-pro' ), + 'VUV' => esc_html__( 'Vanuatu vatu', 'opalestate-pro' ), + 'WST' => esc_html__( 'Samoan tālā', 'opalestate-pro' ), + 'XAF' => esc_html__( 'Central African CFA franc', 'opalestate-pro' ), + 'XCD' => esc_html__( 'East Caribbean dollar', 'opalestate-pro' ), + 'XOF' => esc_html__( 'West African CFA franc', 'opalestate-pro' ), + 'XPF' => esc_html__( 'CFP franc', 'opalestate-pro' ), + 'YER' => esc_html__( 'Yemeni rial', 'opalestate-pro' ), + 'ZAR' => esc_html__( 'South African rand', 'opalestate-pro' ), + 'ZMW' => esc_html__( 'Zambian kwacha', 'opalestate-pro' ), + ]; + + return apply_filters( 'opalestate_currencies', $currencies ); +} + +/** + * Get the price format depending on the currency position + * + * @return string + */ +function opalestate_price_format_position() { + global $opalestate_options; + $currency_pos = opalestate_options( 'currency_position', 'before' ); + + $format = '%1$s%2$s'; + switch ( $currency_pos ) { + case 'before' : + $format = '%1$s%2$s'; + break; + case 'after' : + $format = '%2$s%1$s'; + break; + case 'left_space' : + $format = '%1$s %2$s'; + break; + case 'right_space' : + $format = '%2$s %1$s'; + break; + } + + return apply_filters( 'opalestate_price_format_position', $format, $currency_pos ); +} + +/** + * Price format. + * + * @param string $price + * @param array $args + * @return mixed|void + */ +function opalestate_price_format( $price, $args = [] ) { + + $price = opalestate_price( $price, $args ); + $price = sprintf( opalestate_price_format_position(), opalestate_currency_symbol(), $price ); + + return apply_filters( 'opalestate_price_format', $price ); +} + +function opalestate_get_currency() { + return opalestate_options( 'currency', 'USD' ); +} + +/** + * Gets currency symbol + * + * @param string $currency + * @return string + */ +function opalestate_currency_symbol( $currency = '' ) { + if ( ! $currency ) { + $currency = opalestate_get_currency(); + } + + $symbols = apply_filters( 'opalestate_currency_symbols', [ + 'AED' => 'د.إ', + 'AFN' => '؋', + 'ALL' => 'L', + 'AMD' => 'AMD', + 'ANG' => 'ƒ', + 'AOA' => 'Kz', + 'ARS' => '$', + 'AUD' => '$', + 'AWG' => 'ƒ', + 'AZN' => 'AZN', + 'BAM' => 'KM', + 'BBD' => '$', + 'BDT' => '৳ ', + 'BGN' => 'лв.', + 'BHD' => '.د.ب', + 'BIF' => 'Fr', + 'BMD' => '$', + 'BND' => '$', + 'BOB' => 'Bs.', + 'BRL' => 'R$', + 'BSD' => '$', + 'BTC' => '฿', + 'BTN' => 'Nu.', + 'BWP' => 'P', + 'BYR' => 'Br', + 'BZD' => '$', + 'CAD' => '$', + 'CDF' => 'Fr', + 'CHF' => 'CHF', + 'CLP' => '$', + 'CNY' => '¥', + 'COP' => '$', + 'CRC' => '₡', + 'CUC' => '$', + 'CUP' => '$', + 'CVE' => '$', + 'CZK' => 'Kč', + 'DJF' => 'Fr', + 'DKK' => 'DKK', + 'DOP' => 'RD$', + 'DZD' => 'د.ج', + 'EGP' => 'EGP', + 'ERN' => 'Nfk', + 'ETB' => 'Br', + 'EUR' => '€', + 'FJD' => '$', + 'FKP' => '£', + 'GBP' => '£', + 'GEL' => 'ლ', + 'GGP' => '£', + 'GHS' => '₵', + 'GIP' => '£', + 'GMD' => 'D', + 'GNF' => 'Fr', + 'GTQ' => 'Q', + 'GYD' => '$', + 'HKD' => '$', + 'HNL' => 'L', + 'HRK' => 'Kn', + 'HTG' => 'G', + 'HUF' => 'Ft', + 'IDR' => 'Rp', + 'ILS' => '₪', + 'IMP' => '£', + 'INR' => '₹', + 'IQD' => 'ع.د', + 'IRR' => '﷼', + 'ISK' => 'Kr.', + 'JEP' => '£', + 'JMD' => '$', + 'JOD' => 'د.ا', + 'JPY' => '¥', + 'KES' => 'KSh', + 'KGS' => 'лв', + 'KHR' => '៛', + 'KMF' => 'Fr', + 'KPW' => '₩', + 'KRW' => '₩', + 'KWD' => 'د.ك', + 'KYD' => '$', + 'KZT' => 'KZT', + 'LAK' => '₭', + 'LBP' => 'ل.ل', + 'LKR' => 'රු', + 'LRD' => '$', + 'LSL' => 'L', + 'LYD' => 'ل.د', + 'MAD' => 'د. م.', + 'MAD' => 'د.م.', + 'MDL' => 'L', + 'MGA' => 'Ar', + 'MKD' => 'ден', + 'MMK' => 'Ks', + 'MNT' => '₮', + 'MOP' => 'P', + 'MRO' => 'UM', + 'MUR' => '₨', + 'MVR' => '.ރ', + 'MWK' => 'MK', + 'MXN' => '$', + 'MYR' => 'RM', + 'MZN' => 'MT', + 'NAD' => '$', + 'NGN' => '₦', + 'NIO' => 'C$', + 'NOK' => 'kr', + 'NPR' => '₨', + 'NZD' => '$', + 'OMR' => 'ر.ع.', + 'PAB' => 'B/.', + 'PEN' => 'S/.', + 'PGK' => 'K', + 'PHP' => '₱', + 'PKR' => '₨', + 'PLN' => 'zł', + 'PRB' => 'р.', + 'PYG' => '₲', + 'QAR' => 'ر.ق', + 'RMB' => '¥', + 'RON' => 'lei', + 'RSD' => 'дин.', + 'RUB' => '₽', + 'RWF' => 'Fr', + 'SAR' => 'ر.س', + 'SBD' => '$', + 'SCR' => '₨', + 'SDG' => 'ج.س.', + 'SEK' => 'kr', + 'SGD' => '$', + 'SHP' => '£', + 'SLL' => 'Le', + 'SOS' => 'Sh', + 'SRD' => '$', + 'SSP' => '£', + 'STD' => 'Db', + 'SYP' => 'ل.س', + 'SZL' => 'L', + 'THB' => '฿', + 'TJS' => 'ЅМ', + 'TMT' => 'm', + 'TND' => 'د.ت', + 'TOP' => 'T$', + 'TRY' => '₺', + 'TTD' => '$', + 'TWD' => 'NT$', + 'TZS' => 'Sh', + 'UAH' => '₴', + 'UGX' => 'UGX', + 'USD' => '$', + 'UYU' => '$', + 'UZS' => 'UZS', + 'VEF' => 'Bs F', + 'VND' => '₫', + 'VUV' => 'Vt', + 'WST' => 'T', + 'XAF' => 'Fr', + 'XCD' => '$', + 'XOF' => 'Fr', + 'XPF' => 'Fr', + 'YER' => '﷼', + 'ZAR' => 'R', + 'ZMW' => 'ZK', + ] ); + + $currency_symbol = isset( $symbols[ $currency ] ) ? $symbols[ $currency ] : ''; + + return apply_filters( 'opalestate_currency_symbol', $currency_symbol, $currency ); +} + +/** + * Return the thousand separator for prices + * + * @return string + */ +function opalestate_get_price_thousand_separator() { + $separator = stripslashes( opalestate_options( 'thousands_separator' ) ); + + return $separator; +} + +/** + * Return the decimal separator for prices + * + * @return string + */ +function opalestate_get_price_decimal_separator() { + $separator = stripslashes( opalestate_options( 'decimal_separator', '.' ) ); + + return $separator ? $separator : '.'; +} + +/** + * Return the number of decimals after the decimal point. + * + * @return int + */ +function opalestate_get_price_decimals() { + return absint( opalestate_options( 'number_decimals', 2 ) ); +} + + +/** + * Returns Price. + * + * @param int $price + * @param array $args + * @return bool|mixed|string|void + */ +function opalestate_price( $price, $args = [] ) { + + $negative = $price < 0; + + if ( $negative ) { + $price = substr( $price, 1 ); + } + + + extract( apply_filters( 'opalestate_price_args', wp_parse_args( $args, [ + 'ex_tax_label' => false, + 'decimal_separator' => opalestate_get_price_decimal_separator(), + 'thousand_separator' => opalestate_get_price_thousand_separator(), + 'decimals' => opalestate_get_price_decimals(), + + ] ) ) ); + + $negative = $price < 0; + $price = apply_filters( 'opalestate_raw_price', floatval( $negative ? $price * -1 : $price ) ); + $price = apply_filters( 'opalestate_formatted_price', number_format( $price, $decimals, $decimal_separator, $thousand_separator ), $price, $decimals, $decimal_separator, $thousand_separator ); + + return $price; +} + +/** + * + * Applyer function to show unit for property + */ + +function opalestate_areasize_unit_format( $value = '' ) { + return $value . ' ' . '' . opalestate_options( 'measurement_unit', 'sq ft' ) . ''; +} + +add_filter( 'opalestate_areasize_unit_format', 'opalestate_areasize_unit_format' ); + +/** + * + * Applyer function to show unit for property + */ +if ( ! function_exists( 'opalestate_fnc_excerpt' ) ) { + //Custom Excerpt Function + function opalestate_fnc_excerpt( $limit, $afterlimit = '[...]' ) { + $excerpt = get_the_excerpt(); + + return opalestate_fnc_get_words( $excerpt, $limit, $afterlimit ); + } +} + +function opalestate_fnc_get_words( $excerpt, $limit, $afterlimit = '...' ) { + if ( $excerpt != '' ) { + $excerpt = explode( ' ', strip_tags( $excerpt ), $limit ); + } else { + $excerpt = explode( ' ', strip_tags( get_the_content() ), $limit ); + } + if ( count( $excerpt ) >= $limit ) { + array_pop( $excerpt ); + $excerpt = implode( " ", $excerpt ) . ' ' . $afterlimit; + } else { + $excerpt = implode( " ", $excerpt ); + } + $excerpt = preg_replace( '`[[^]]*]`', '', $excerpt ); + + return strip_shortcodes( $excerpt ); +} + +/** + * + */ +function opalestate_is_own_property( $post_id, $user_id ) { + $post = get_post( $post_id ); + wp_reset_postdata(); + if ( ! is_object( $post ) || ! $post->ID ) { + return false; + } + + return $user_id == $post->post_author; +} + + +if ( ! function_exists( 'opalesate_insert_user_agent' ) ) { + + function opalesate_insert_user_agent( $args = [] ) { + $userdata = wp_parse_args( $args, [ + 'first_name' => '', + 'last_name' => '', + 'avatar' => '', + 'job' => '', + 'email' => '', + 'phone' => '', + 'mobile' => '', + 'fax' => '', + 'web' => '', + 'address' => '', + 'twitter' => '', + 'facebook' => '', + 'google' => '', + 'linkedin' => '', + 'instagram' => '', + ] ); + + $agent_id = wp_insert_post( [ + 'post_title' => $args['first_name'] && $args['last_name'] ? $args['first_name'] . ' ' . $args['last_name'] : $userdata['email'], + 'post_content' => 'empty description', + 'post_excerpt' => 'empty excerpt', + 'post_type' => 'opalestate_agent', + 'post_status' => 'publish', + 'post_author' => 1, + ], true ); + + foreach ( $userdata as $key => $value ) { + if ( in_array( $key, [ 'first_name', 'last_name' ] ) ) { + continue; + } + update_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . $key, $value ); + } + do_action( 'opalesate_insert_user_agent', $agent_id ); + + return $agent_id; + } +} + +/** + * Returns the multilingual instance. + * + * @return Opalestate_Multilingual + */ +function opalestate_multilingual() { + $multilingual = new Opalestate_Multilingual(); + + return $multilingual; +} + +/** + * Is current WordPress is running on multi-languages. + * + * @return bool + */ +function opalestate_running_on_multilanguage() { + return apply_filters( 'opalestate_is_running_multilanguage', Opalestate_Multilingual::is_polylang() || Opalestate_Multilingual::is_wpml() ); +} + +/** + * Add hidden multilingual. + */ +function opalestate_add_hidden_multilingual() { + if ( ! opalestate_running_on_multilanguage() ) { + return; + } + ?> + + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Property_MetaBox { + + /** + * + */ + public function register_admin_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $box_options = [ + 'id' => 'property_metabox', + 'title' => esc_html__( 'Property Metabox', 'opalestate-pro' ), + 'object_types' => [ 'opalestate_property' ], + 'show_names' => true, + ]; + + // Setup meta box + $cmb = new_cmb2_box( $box_options ); + + // Setting tabs + $tabs_setting = [ + 'config' => $box_options, + 'layout' => 'vertical', // Default : horizontal + 'tabs' => [], + ]; + + + $tabs_setting['tabs'][] = [ + 'id' => 'p-general', + 'icon' => 'dashicons-admin-home', + 'title' => esc_html__( 'General', 'opalestate-pro' ), + 'fields' => $this->metaboxes_management_fields(), + ]; + + $tabs_setting['tabs'][] = [ + 'id' => 'p-prices', + 'icon' => 'dashicons-admin-tools', + 'title' => esc_html__( 'Prices', 'opalestate-pro' ), + 'fields' => $this->metaboxes_price_fields(), + ]; + + $tabs_setting['tabs'][] = [ + 'id' => 'p-information', + 'icon' => 'dashicons-admin-post', + 'title' => esc_html__( 'Information', 'opalestate-pro' ), + 'fields' => $this->metaboxes_info_fields(), + ]; + + $tabs_setting['tabs'][] = [ + 'id' => 'p-facilities', + 'icon' => 'dashicons-grid-view', + 'title' => esc_html__( 'Facility', 'opalestate-pro' ), + 'fields' => $this->metaboxes_public_facilities_fields(), + ]; + + + $tabs_setting['tabs'][] = [ + 'id' => 'p-floor-plans', + 'icon' => 'dashicons-grid-view', + 'title' => esc_html__( 'Floor Plan', 'opalestate-pro' ), + 'fields' => $this->metaboxes_floor_plans(), + ]; + + $tabs_setting['tabs'][] = [ + 'id' => 'p-apartments', + 'icon' => 'dashicons-admin-multisite', + 'title' => esc_html__( 'Apartments', 'opalestate-pro' ), + 'fields' => $this->metaboxes_apartments(), + ]; + + //// + $tabs_setting['tabs'][] = [ + 'id' => 'p-gallery', + 'icon' => 'dashicons-format-gallery', + 'title' => esc_html__( 'Gallery', 'opalestate-pro' ), + 'fields' => [ + [ + 'id' => "{$prefix}gallery", + 'name' => esc_html__( 'Images Gallery', 'opalestate-pro' ), + 'type' => 'file_list', + 'description' => esc_html__( 'Select one or more images to show as gallery', 'opalestate-pro' ), + ], + ], + ]; + /// + $tabs_setting['tabs'][] = [ + 'id' => 'p-vt_gallery', + 'title' => esc_html__( 'Virtual Tour 360', 'opalestate-pro' ), + 'icon' => 'dashicons-format-image', + 'fields' => [ + [ + 'id' => "{$prefix}vt_gallery", + 'name' => esc_html__( 'Manual Images 360 ', 'opalestate-pro' ), + 'type' => 'opal_upload', + 'description' => esc_html__( 'Select one or more images to show as gallery', 'opalestate-pro' ), + ], + [ + 'id' => "{$prefix}virtual", + 'name' => esc_html__( 'Or 360° Virtual Tour', 'opalestate-pro' ), + 'type' => 'textarea_code', + 'description' => esc_html__( 'Input iframe to show 360° Virtual Tour.', 'opalestate-pro' ), + ], + ], + ]; + + /// + $tabs_setting['tabs'][] = [ + 'id' => 'p-attachments', + 'icon' => 'dashicons-media-default', + 'title' => esc_html__( 'Attachments', 'opalestate-pro' ), + 'fields' => [ + [ + 'id' => "{$prefix}attachments", + 'name' => esc_html__( 'Attachments', 'opalestate-pro' ), + 'type' => 'file_list', + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + 'description' => esc_html__( 'Select one or more files to allow download', 'opalestate-pro' ), + ], + ], + ]; + + $tabs_setting['tabs'][] = [ + 'id' => 'p-agents', + 'icon' => 'dashicons-admin-users', + 'title' => esc_html__( 'Contact Member', 'opalestate-pro' ), + 'fields' => $this->metaboxes_members_fields(), + ]; + + $tabs_setting['tabs'][] = [ + 'id' => 'p-assignment', + 'icon' => 'dashicons-admin-users', + 'title' => esc_html__( 'User Assignment', 'opalestate-pro' ), + 'fields' => $this->metaboxes_assignment_fields(), + ]; + + $tabs_setting['tabs'][] = [ + 'id' => 'p-layout', + 'title' => esc_html__( 'Layout', 'opalestate-pro' ), + 'fields' => $this->metaboxes_layout_fields(), + ]; + + // Set tabs + $cmb->add_field( [ + 'id' => '__tabs', + 'type' => 'tabs', + 'tabs' => $tabs_setting, + ] ); + + return true; + } + + /** + * + */ + public function metaboxes_management_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'name' => esc_html__( 'Featured', 'opalestate-pro' ), + 'id' => $prefix . 'featured', + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + ], + 'default' => 0, + ], + [ + 'name' => esc_html__( 'Property SKU', 'opalestate-pro' ), + 'id' => $prefix . 'sku', + 'type' => 'text', + 'description' => esc_html__( 'Please Enter Your Property SKU', 'opalestate-pro' ), + ], + [ + 'id' => $prefix . 'map', + 'name' => esc_html__( 'Location', 'opalestate-pro' ), + 'type' => 'opal_map', + 'sanitization_cb' => 'opal_map_sanitise', + 'split_values' => true, + ], + + [ + 'name' => esc_html__( 'Postal Code / Zip', 'opalestate-pro' ), + 'id' => $prefix . 'zipcode', + 'type' => 'text', + + ], + [ + 'name' => esc_html__( 'Google Map View', 'opalestate-pro' ), + 'id' => $prefix . 'enablemapview', + 'type' => 'switch', + 'options' => [ + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + 0 => esc_html__( 'No', 'opalestate-pro' ), + ], + ], + + [ + 'name' => esc_html__( 'Address', 'opalestate-pro' ), + 'id' => $prefix . 'address', + 'type' => 'textarea_small', + 'attributes' => [ + 'required' => 'required', + ], + ], + + + [ + 'id' => "{$prefix}video", + 'name' => esc_html__( 'Video', 'opalestate-pro' ), + 'type' => 'text_url', + 'description' => esc_html__( 'Input for videos, audios from Youtube, Vimeo and all supported sites by WordPress. It has preview feature.', 'opalestate-pro' ), + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_management', $fields ); + } + + /** + * + */ + public function metaboxes_price_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + + $currency = opalestate_currency_symbol() ? ' (' . opalestate_currency_symbol() . ')' : ' ($)'; + + $fields = [ + [ + 'id' => $prefix . 'price', + 'name' => esc_html__( 'Regular Price', 'opalestate-pro' ) . $currency, + 'type' => 'text', + 'description' => esc_html__( 'Enter amount without currency', 'opalestate-pro' ), + 'attributes' => opalestate_get_option( 'require_input_price' ) ? [ 'required' => 'required' ] : '', + 'before_row' => '

            ' . ( is_admin() ? "" : esc_html__( 'Price', 'opalestate-pro' ) ) . '

            ', // callback + ], + [ + 'id' => $prefix . 'saleprice', + 'name' => esc_html__( 'Sale Price', 'opalestate-pro' ) . $currency, + 'type' => 'text', + 'description' => esc_html__( 'Enter amount without currency', 'opalestate-pro' ), + ], + [ + 'id' => $prefix . 'before_pricelabel', + 'name' => esc_html__( 'Before Price Label (optional)', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Before Price Label (e.g. "from")', 'opalestate-pro' ), + ], + [ + 'id' => $prefix . 'pricelabel', + 'name' => esc_html__( 'After Price Label (optional)', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'After Price Label (e.g. "per month")', 'opalestate-pro' ), + 'after_row' => '
            ', // callback + ], + [ + 'name' => esc_html__( 'Is Price On Call', 'opalestate-pro' ), + 'id' => $prefix . 'price_oncall', + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + ], + 'default' => 0, + ], + + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_price', $fields ); + } + + /** + * + */ + public static function metaboxes_info_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + + $fields = [ + + [ + 'name' => esc_html__( 'Built year', 'opalestate-pro' ), + 'id' => $prefix . 'builtyear', + 'type' => 'text_date', + 'description' => esc_html__( 'Enter built year', 'opalestate-pro' ), + + 'before_row' => '

            ' . ( is_admin() ? "" : esc_html__( 'Property Information', 'opalestate-pro' ) ) . '

            ', + // callback + + ], + + [ + 'name' => esc_html__( 'Parking', 'opalestate-pro' ), + 'id' => $prefix . 'parking', + 'type' => 'text', + 'attributes' => [ + 'type' => 'number', + 'min' => 0, + ], + 'description' => esc_html__( 'Enter number of Parking', 'opalestate-pro' ), + ], + + [ + 'name' => esc_html__( 'Bedrooms', 'opalestate-pro' ), + 'id' => $prefix . 'bedrooms', + 'type' => 'text', + 'attributes' => [ + 'type' => 'number', + 'min' => 0, + ], + 'description' => esc_html__( 'Enter number of bedrooms', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Bathrooms', 'opalestate-pro' ), + 'id' => $prefix . 'bathrooms', + 'type' => 'text', + 'attributes' => [ + 'type' => 'number', + 'min' => 0, + ], + 'description' => esc_html__( 'Enter number of bathrooms', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Plot Size', 'opalestate-pro' ), + 'id' => $prefix . 'plotsize', + 'type' => 'text', + 'description' => esc_html__( 'Enter size of Plot as 20x30, 20x30x40, 20x30x40x50', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Area Size', 'opalestate-pro' ), + 'id' => $prefix . 'areasize', + 'type' => 'text', + 'description' => esc_html__( 'Enter size of area in sqft', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Orientation', 'opalestate-pro' ), + 'id' => "{$prefix}orientation", + 'type' => 'text', + 'description' => esc_html__( 'Enter Orientation of property', 'opalestate-pro' ), + ], + + [ + 'name' => esc_html__( 'Living Rooms', 'opalestate-pro' ), + 'id' => "{$prefix}livingrooms", + 'type' => 'text', + 'attributes' => [ + 'type' => 'number', + 'min' => 0, + ], + 'description' => esc_html__( 'Enter Number of Living Rooms', 'opalestate-pro' ), + ], + + [ + 'name' => esc_html__( 'Kitchens', 'opalestate-pro' ), + 'id' => "{$prefix}kitchens", + 'type' => 'text', + 'attributes' => [ + 'type' => 'number', + 'min' => 0, + ], + 'description' => esc_html__( 'Enter Number of Kitchens', 'opalestate-pro' ), + ], + + [ + 'name' => esc_html__( 'Rooms', 'opalestate-pro' ), + 'id' => "{$prefix}amountrooms", + 'type' => 'text', + 'attributes' => [ + 'type' => 'number', + 'min' => 0, + ], + 'description' => esc_html__( 'Enter Number of Amount Rooms', 'opalestate-pro' ), + + 'after_row' => '
            ', + + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_info', $fields ); + } + + /** + * + */ + public function metaboxes_public_facilities_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'id' => $prefix . 'public_facilities_group', + 'type' => 'group', + 'fields' => [ + [ + 'id' => $prefix . 'public_facilities_key', + 'name' => esc_html__( 'Label', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'public_facilities_value', + 'name' => esc_html__( 'Content', 'opalestate-pro' ), + 'type' => 'text', + ], + ], + 'options' => [ + 'group_title' => esc_html__( 'Facility {#}', 'opalestate-pro' ), + 'add_button' => esc_html__( 'Add more', 'opalestate-pro' ), + 'remove_button' => esc_html__( 'Remove', 'opalestate-pro' ), + 'sortable' => true, + 'closed' => false, + ], + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_public_facilities', $fields ); + } + + /** + * + */ + public function metaboxes_members_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + global $post; + + $types = [ + 'hide' => esc_html__( 'Hide Author Information', 'opalestate-pro' ), + 'user' => esc_html__( 'User Author Information', 'opalestate-pro' ), + 'agent' => esc_html__( 'Agent Information', 'opalestate-pro' ), + 'agency' => esc_html__( 'Agency Information', 'opalestate-pro' ), + ]; + + // agent + $agents = [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + ]; + if ( isset( $_GET['post'] ) && $_GET['post'] ) { + $id = get_post_meta( (int) $_GET['post'], OPALESTATE_PROPERTY_PREFIX . 'agent', true ); + if ( $id ) { + $agents[ $id ] = get_the_title( $id ); + } + } + // agency + $agency = [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + ]; + if ( isset( $_GET['post'] ) && $_GET['post'] ) { + $id = get_post_meta( (int) $_GET['post'], OPALESTATE_PROPERTY_PREFIX . 'agency', true ); + if ( $id ) { + $agency[ $id ] = get_the_title( $id ); + } + } + + $fields = [ + [ + 'name' => esc_html__( 'Author Information', 'opalestate-pro' ), + 'id' => "{$prefix}author_type", + 'type' => 'select', + 'options' => $types, + 'default' => 'user', + ], + [ + 'name' => esc_html__( 'Agent', 'opalestate-pro' ), + 'id' => "{$prefix}agent", + 'type' => 'select', + 'options' => $agents, + ], + [ + 'name' => esc_html__( 'Agency', 'opalestate-pro' ), + 'id' => "{$prefix}agency", + 'type' => 'select', + 'options' => $agency, + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_agent', $fields ); + } + + /** + * + */ + public function metaboxes_assignment_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + global $post; + + // users + $users = [ + 0 => esc_html__( 'Default User', 'opalestate-pro' ), + ]; + + $all_users = get_users(); + + foreach ( $all_users as $user ) { + $users[ $user->ID ] = $user->display_name; + } + + $fields = [ + [ + 'name' => esc_html__( 'User', 'opalestate-pro' ), + 'id' => "post_author_override", + 'type' => 'select', + "description" => esc_html__( 'Change to new owner of this property, which be listed in That user dashboard', 'opalestate-pro' ), + 'options' => $users, + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_assignment', $fields ); + } + + /** + * + */ + public function metaboxes_layout_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + + $templates = opalestate_single_layout_prieview(); + + $fields = [ + [ + 'name' => esc_html__( 'Layout Display', 'opalestate-pro' ), + 'id' => "{$prefix}layout", + 'type' => 'select', + 'options' => apply_filters( 'opalestate_single_layout_templates', [ '' => esc_html__( 'Inherit', 'opalestate-pro' ) ] ), + 'description' => esc_html__( 'Select a layout to display full information of this property', 'opalestate-pro' ), + ], + + [ + 'name' => esc_html__( 'Preview Display', 'opalestate-pro' ), + 'id' => "{$prefix}preview", + 'type' => 'select', + 'options' => $templates, + 'description' => esc_html__( 'Select a layout to display full information of this property', 'opalestate-pro' ), + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_layout', $fields ); + } + + /** + * + */ + public function metaboxes_floor_plans() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'id' => $prefix . 'public_floor_group', + 'type' => 'group', + 'fields' => [ + [ + 'id' => $prefix . 'floor_name', + 'name' => esc_html__( 'Name', 'opalestate-pro' ), + 'type' => 'text', + + ], + [ + 'id' => $prefix . 'floor_price', + 'name' => esc_html__( 'Price', 'opalestate-pro' ), + 'before_row' => '
            ', + 'type' => 'text', + ], + [ + 'id' => $prefix . 'floor_size', + 'name' => esc_html__( 'Size', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'floor_room', + 'name' => esc_html__( 'Rooms', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'floor_bath', + 'name' => esc_html__( 'Baths', 'opalestate-pro' ), + 'type' => 'text', + 'after_row' => '
            ', + ], + [ + 'id' => $prefix . 'floor_content', + 'name' => esc_html__( 'Content', 'opalestate-pro' ), + 'type' => 'textarea_small', + ], + [ + 'id' => "{$prefix}floor_image", + 'name' => esc_html__( 'Image Preview', 'opalestate-pro' ), + 'type' => 'file', + 'query_args' => [ + 'type' => [ + 'image/gif', + 'image/jpeg', + 'image/png', + ], + ], + 'description' => esc_html__( 'Input iframe to show 360° Virtual Tour.', 'opalestate-pro' ), + ], + ], + 'options' => [ + 'group_title' => esc_html__( 'Floor {#}', 'opalestate-pro' ), + 'add_button' => esc_html__( 'Add more', 'opalestate-pro' ), + 'remove_button' => esc_html__( 'Remove', 'opalestate-pro' ), + 'sortable' => true, + 'closed' => false, + ], + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_floor_plans', $fields ); + } + + /** + * + */ + public function metaboxes_apartments() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'id' => $prefix . 'apartments', + 'type' => 'group', + 'fields' => [ + [ + 'id' => $prefix . 'apartment_plot', + 'name' => esc_html__( 'Plot', 'opalestate-pro' ), + 'before_row' => '
            ', + 'type' => 'text', + + ], + [ + 'id' => $prefix . 'apartment_beds', + 'name' => esc_html__( 'Beds', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'apartment_price_from', + 'name' => esc_html__( 'Price from', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'apartment_floor', + 'name' => esc_html__( 'Floor', 'opalestate-pro' ), + 'type' => 'text', + 'after_row' => '
            ', + ], + [ + 'id' => $prefix . 'apartment_building_address', + 'name' => esc_html__( 'Building / Address', 'opalestate-pro' ), + 'type' => 'textarea_small', + ], + [ + 'id' => $prefix . 'apartment_status', + 'name' => esc_html__( 'Status', 'opalestate-pro' ), + 'type' => 'select', + 'options' => apply_filters( 'opalestate_property_apartment_statuses', [ + '' => esc_html__( 'None', 'opalestate-pro' ), + 'available' => esc_html__( 'Available', 'opalestate-pro' ), + 'unavailable' => esc_html__( 'Unavailable', 'opalestate-pro' ), + ] ), + 'before_row' => '
            ', + ], + [ + 'id' => $prefix . 'apartment_link', + 'name' => esc_html__( 'Link', 'opalestate-pro' ), + 'type' => 'text', + 'after_row' => '
            ', + ], + ], + 'options' => [ + 'group_title' => esc_html__( 'Apartment {#}', 'opalestate-pro' ), + 'add_button' => esc_html__( 'Add more', 'opalestate-pro' ), + 'remove_button' => esc_html__( 'Remove', 'opalestate-pro' ), + 'sortable' => true, + 'closed' => false, + ], + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_apartments', $fields ); + } +} diff --git a/inc/property/class-opalestate-favorite.php b/inc/property/class-opalestate-favorite.php new file mode 100755 index 00000000..482f7213 --- /dev/null +++ b/inc/property/class-opalestate-favorite.php @@ -0,0 +1,150 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class Opalestate_Favorite_Property: work as wishlist function + * + * @version 1.0 + */ +class Opalestate_Favorite_Property{ + + /** + * @var integer $userId + */ + protected $userId ; + + /** + * Get instance of this object + */ + public static function get_instance(){ + static $_instance; + if( !$_instance ){ + $_instance = new Opalestate_Favorite_Property(); + } + return $_instance; + } + + /** + * Constructor + */ + public function __construct(){ + + add_shortcode( 'opalestate_favorite_button' , array( $this, 'favorite_button' ) ); + add_shortcode( 'opalestate_user_favious_properties' , array( $this, 'favorite_properties' ) ); + + /** + * Ajax action + */ + add_action( 'wp_ajax_opalestate_toggle_status', array($this,'toggle_status') ); + add_action( 'wp_ajax_nopriv_opalestate_toggle_status', array($this,'toggle_status') ); + add_action( 'init', array($this,'init') ); + + + // show content page in user dashboard + add_filter( 'opalestate_user_content_favorite_page' , array( $this, 'favorite_properties' ) ); + } + + /** + * Set values when user logined in system + */ + public function init(){ + + global $current_user; + wp_get_current_user(); + $this->userId = $current_user->ID; + } + + /** + * Allow set or remove favorite + */ + public function toggle_status(){ + + if( isset($_POST['property_id']) ){ + + $property_id = absint( $_POST['property_id'] ); + + $items = (array)get_user_meta( $this->userId, 'opalestate_user_favorite', true ); + + $key = array_search( $property_id, $items); + if( $key != false || $key != '' ){ + unset($items[$key]); + }else { + $items[] = $property_id; + } + // remove items emty + foreach( $items as $key => $value ) { + if( empty($value) ) { + unset( $items[$key] ); + } + } + update_user_meta( $this->userId, 'opalestate_user_favorite', $items ); + } + + echo $this->favorite_button( array('property_id' => $property_id ) ); + + exit; + } + + + /** + * render favorite button in loop + */ + public function favorite_button( $atts ){ + $atts['userId'] = $this->userId; + if( !isset($atts['property_id']) ){ + $atts['property_id'] = get_the_ID(); + } + + $items = (array)get_user_meta( $this->userId, 'opalestate_user_favorite', true ); + + $key = array_search( $atts['property_id'], $items); + $atts['existed'] = $key; + + ob_start(); + echo opalestate_load_template_path( 'user/favorite-button' , $atts ); + $ouput = ob_get_contents(); + ob_end_clean(); + + return $ouput; + } + + /** + * show all favorited properties with pagination. + */ + public function favorite_properties(){ + + $paged = ( get_query_var('paged') == 0 ) ? 1 : get_query_var('paged'); + $per_page = 9; + $items = (array)get_user_meta( $this->userId, 'opalestate_user_favorite', true ); + + $args = array( + 'post_type' => 'opalestate_property', + 'paged' => $paged, + 'posts_per_page' => $per_page, + 'post__in' => !empty($items) ? $items : array( 9999999 ) + ); + + $loop = new WP_Query( $args ); + + + return opalestate_load_template_path( 'user/favorite-properties' , array('loop' => $loop) ); + } + +} + +Opalestate_Favorite_Property::get_instance(); diff --git a/inc/property/class-opalestate-posttype.php b/inc/property/class-opalestate-posttype.php new file mode 100755 index 00000000..9d1f81b0 --- /dev/null +++ b/inc/property/class-opalestate-posttype.php @@ -0,0 +1,79 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * Class Opalestate_PostType_Agency + * + * @version 1.0 + */ +class Opalestate_PostType_Property { + + /** + * Opalestate_PostType_Property constructor. + */ + public function __construct() { + add_action( 'init', [ __CLASS__, 'definition' ] ); + } + + /** + * Register Post type and taxonomies + */ + public static function definition() { + if ( ! is_blog_installed() || post_type_exists( 'opalestate_property' ) ) { + return; + } + + $labels = [ + 'name' => esc_html__( 'Properties', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Property', 'opalestate-pro' ), + 'add_new' => esc_html__( 'Add New Property', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Property', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Property', 'opalestate-pro' ), + 'new_item' => esc_html__( 'New Property', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Properties', 'opalestate-pro' ), + 'view_item' => esc_html__( 'View Property', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Property', 'opalestate-pro' ), + 'not_found' => esc_html__( 'No Properties found', 'opalestate-pro' ), + 'not_found_in_trash' => esc_html__( 'No Properties found in Trash', 'opalestate-pro' ), + 'parent_item_colon' => '', + 'menu_name' => esc_html__( 'Properties', 'opalestate-pro' ), + ]; + + $labels = apply_filters( 'opalestate_postype_property_labels', $labels ); + + register_post_type( 'opalestate_property', + apply_filters( 'opalestate_property_post_type_parameters', [ + 'labels' => $labels, + 'supports' => [ 'title', 'editor', 'thumbnail', 'comments', 'author' ], + 'public' => true, + 'has_archive' => true, + 'menu_position' => 51, + 'categories' => [], + 'menu_icon' => 'dashicons-admin-home', + 'map_meta_cap' => true, + 'publicly_queryable' => true, + 'exclude_from_search' => false, + 'query_var' => true, + 'hierarchical' => false, // Hierarchical causes memory issues - WP loads all records! + 'show_in_nav_menus' => true, + 'rewrite' => [ 'slug' => esc_html_x( 'property', 'property slug', 'opalestate-pro' ) ], + ] ) + ); + } +} + +new Opalestate_PostType_Property(); diff --git a/inc/property/class-opalestate-property-query.php b/inc/property/class-opalestate-property-query.php new file mode 100755 index 00000000..a5ec11f0 --- /dev/null +++ b/inc/property/class-opalestate-property-query.php @@ -0,0 +1,71 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Property_Query { + /** + * The args to pass to the give_get_donors() query + * + * @since 1.8.14 + * @access public + * + * @var array + */ + public $args = array(); + + /** + * The collection found based on the criteria set + * + * @since 1.8.14 + * @access public + * + * @var array + */ + + public $count = 0; + + public $collection = array(); + + + public function insert( ) { + + } + + public function update() { + + } + + public function mapping_query(){ + + } + + public function query( $args ){ + $this->count = ''; + $this->collection = ''; + $data = ''; + } + + public function get_list ( $args ){ + return $collection; + } + + public function count() { + + } + + +} \ No newline at end of file diff --git a/inc/property/class-opalestate-property.php b/inc/property/class-opalestate-property.php new file mode 100755 index 00000000..4701d47c --- /dev/null +++ b/inc/property/class-opalestate-property.php @@ -0,0 +1,727 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +/** + * @class Opalestate_Property + * + * @version 1.0 + */ +class Opalestate_Property { + + /** + * @var Integer $post_id + * + * @access protected + */ + public $post_id; + + /** + * @var array $metabox_info + * + * @access protected + */ + protected $metabox_info; + + /** + * @var float $price + * + * @access protected + */ + protected $price; + + /** + * @var float $saleprice + * + * @access protected + */ + protected $saleprice; + + /** + * @var String $map + * + * @access protected + */ + protected $map; + + /** + * @var Integer $address + * + * @access protected + */ + public $address; + + /** + * @var String $sku + * + * @access protected + */ + public $sku; + + /** + * @var String $latitude + * + * @access protected + */ + public $latitude; + + /** + * @var String $longitude + * + * @access protected + */ + public $longitude; + + /** + * @var Integer $featured 1 or 0 + * + * @access protected + */ + public $featured; + + /** + * @var array Property page settings $property_settings + * + * @access public + */ + public $property_settings; + + /** + * Constructor + */ + public function __construct( $post_id ) { + $this->post_id = $post_id; + + $this->map = $this->get_metabox_value( 'map' ); + $this->address = $this->get_metabox_value( 'address' ); + $this->price = $this->get_metabox_value( 'price' ); + $this->saleprice = $this->get_metabox_value( 'saleprice' ); + $this->before_pricelabel = $this->get_metabox_value( 'before_pricelabel' ); + $this->pricelabel = $this->get_metabox_value( 'pricelabel' ); + $this->featured = $this->get_metabox_value( 'featured' ); + $this->sku = $this->get_metabox_value( 'sku' ); + + $this->latitude = isset( $this->map['latitude'] ) ? $this->map['latitude'] : ''; + $this->longitude = isset( $this->map['longitude'] ) ? $this->map['longitude'] : ''; + } + + /** + * Get A Instance Of Opalestate_Property + */ + public static function get_instance( $post_id ) { + + static $_instance; + + if ( ! $_instance ) { + $_instance = new Opalestate_Property( $post_id ); + } + + return $_instance; + } + + public function get_block_setting( $key ) { + if ( ! $this->property_settings ) { + $keys = [ + 'amenities', + 'attachments', + 'facilities', + 'video', + 'map', + 'nearby', + 'walkscores', + 'apartments', + 'floor_plans', + 'views_statistics', + ]; + + foreach ( $keys as $key ) { + $this->property_settings[ $key ] = opalestate_get_option( 'enable_single_' . $key, 'on' ); + } + } + + return $this->property_settings[ $key ]; + } + + /** + * Gets Amenities + * + * @access public + * @param string $all + * @return array + */ + public function get_meta_fullinfo() { + if ( empty( $this->metabox_info ) ) { + $fields = Opalestate_Property_MetaBox::metaboxes_info_fields(); + + foreach ( $fields as $a => $field ) { + + $id = str_replace( OPALESTATE_PROPERTY_PREFIX, "", $field['id'] ); + + if ( $field['type'] == 'multicheck' || $field['type'] == 'select' ) { + + $opt_values = (array) get_post_meta( $this->post_id, $field['id'] ); + if ( ! empty( $opt_values ) && isset( $field['options'] ) ) { + $tmp = []; + foreach ( $opt_values as $key => $val ) { + if ( isset( $field['options'][ $val ] ) ) { + $tmp[ $val ] = $field['options'][ $val ]; + } + } + $opt_values = $tmp; + } + $value = implode( ", ", $opt_values ); + } else { + $value = get_post_meta( $this->post_id, $field['id'], true ); + } + + $value = isset( $field['unit'] ) ? $value . ' ' . $field['unit'] : $value; + + $this->metabox_info[ $id ] = [ 'label' => $field['name'], 'value' => $value ]; + } + } + + return $this->metabox_info; + } + + public function get_id() { + return $this->post_id; + } + + /** + * + */ + public function is_featured() { + return $this->featured; + } + + /** + * + */ + public function get_meta_search_objects() { + $prop = new stdClass(); + $map = $this->get_metabox_value( 'map' ); + $image_id = get_post_thumbnail_id( $this->post_id ); + if ( $image_id ) { + $url = wp_get_attachment_url( $image_id, opalestate_options( 'loop_image_size', 'large' ), true ); + } else { + $url = opalestate_get_image_placeholder( apply_filters( 'opalestate_loop_property_thumbnail', 'large' ), true ); + } + + + $prop->id = $this->post_id; + $prop->title = get_the_title(); + $prop->url = get_permalink( $this->post_id ); + + $prop->lat = $map['latitude']; + $prop->lng = $map['longitude']; + $prop->address = $this->address; + + $prop->pricehtml = opalestate_price_format( $this->get_price() ); + $prop->pricelabel = $this->get_price_label(); + $prop->thumb = $url; + + if ( file_exists( get_template_directory() . '/images/map/market_icon.png' ) ) { + $prop->icon = get_template_directory_uri() . '/images/map/market_icon.png'; + } else { + $prop->icon = OPALESTATE_PLUGIN_URL . '/assets/map/market_icon.png'; + } + + + $prop->featured = $this->featured; + + $metas = Opalestate_Property_MetaBox::metaboxes_info_fields(); + + foreach ( $metas as $key => $field ) { + $id = str_replace( OPALESTATE_PROPERTY_PREFIX, "", $field['id'] ); + $prop->$id = get_post_meta( $this->post_id, $field['id'], true ); + } + $metas = $this->get_meta_shortinfo(); + + $prop->metas = $metas; + $prop->status = $this->render_statuses(); + $terms = wp_get_post_terms( $this->post_id, 'opalestate_types' ); + if ( $terms ) { + $term = reset( $terms ); + $icon = get_term_meta( $term->term_id, 'opalestate_type_iconmarker', true ); + if ( $icon ) { + $prop->icon = $icon; + } + } + + return $prop; + } + + /** + * Gets Amenities + * + * @access public + * @param string $all + * @return array + */ + public function get_meta_shortinfo() { + $output = []; + + $meta = opalestate_options( 'show_property_meta' ); + $meta = apply_filters( 'opalestate_property_meta_shortinfo_fields', $meta ); + + if ( ! empty( $meta ) ) { + $fields = $this->get_meta_fullinfo(); + foreach ( $meta as $key => $value ) { + + if ( isset( $fields[ $value ] ) ) { + $output[ $value ] = $fields[ $value ]; + } + } + } + + return $output; + } + + /** + * Gets Amenities + * + * @access public + * @param string $all + * @return array + */ + public function get_amenities( $all = true ) { + + if ( $all ) { + $terms = Opalestate_Query::get_amenities(); + } else { + $terms = wp_get_post_terms( $this->post_id, 'opalestate_amenities' ); + } + + return $terms; + } + + /** + * + */ + public function get_locations() { + $terms = wp_get_post_terms( $this->post_id, 'opalestate_location' ); + + if ( $terms ) { + return $terms; + } + + return []; + } + + /** + * Gets locations + * + * @access public + * @return array + */ + public function render_locations() { + $terms = wp_get_post_terms( $this->post_id, 'opalestate_location' ); + if ( $terms ) { + $output = ''; + foreach ( $terms as $key => $term ) { + $output .= '' . $term->name . ''; + if ( $key < ( count( $terms ) - 1 ) ) { + $output .= ", "; + } + } + $output .= ''; + echo $output; + } + } + + /** + * Gets labels + * + * @access public + * @return array + */ + public function get_labels() { + return wp_get_post_terms( $this->post_id, 'opalestate_label' ); + } + + /** + * Render labels. + * + * @access public + * @return string + */ + public function render_labels() { + $labels = $this->get_labels(); + + if ( empty( $labels ) ) { + return; + } + + $output = '
              '; + foreach ( $labels as $key => $value ) { + $output .= '
            • ' . esc_html( $value->name ) . '
            • '; + } + $output .= '
            '; + + return $output; + } + + /** + * Gets statuses + * + * @access public + * @return array + */ + public function get_status() { + $terms = wp_get_post_terms( $this->post_id, 'opalestate_status' ); + + return $terms; + } + + /** + * Render statuses. + * + * @access public + * @return string + */ + public function render_statuses() { + $statuses = $this->get_status(); + + if ( empty( $statuses ) ) { + return; + } + + $output = '
              '; + foreach ( $statuses as $key => $value ) { + $output .= '
            • ' . esc_html( $value->name ) . '
            • '; + } + $output .= '
            '; + + return $output; + } + + /** + * + */ + public function getAuthor() { + + } + + + public function get_author_type() { + return $this->get_metabox_value( 'author_type' ); + } + + /** + * + */ + public function render_author_link() { + switch ( $this->get_author_type() ) { + + case 'hide': + + return; + break; + + case 'agent': + $agent_id = $this->get_metabox_value( 'agent' ); + $data = OpalEstate_Agent::get_link( $agent_id ); + break; + + case 'agency': + $agency_id = $this->get_metabox_value( 'agency' ); + $data = OpalEstate_Agency::get_link( $agency_id ); + break; + default: + $data = $this->get_author_link(); + break; + } + + $avatar = $data['avatar'] ? $data['avatar'] : opalestate_get_image_avatar_placehold(); + $avatar = '' . $data['name'] . ''; + + return '' . $avatar . '' . $data['name'] . ''; + } + + private function get_author_link() { + + $image_id = get_user_meta( get_the_author_meta( 'ID' ), OPALESTATE_USER_PROFILE_PREFIX . 'avatar_id', true ); + $related_id = get_user_meta( get_the_author_meta( 'ID' ), OPALESTATE_USER_PROFILE_PREFIX . 'related_id', true ); + + if ( $image_id ) { + $url = wp_get_attachment_url( $image_id ); + } else { + $url = get_avatar_url( get_the_author_meta( 'email' ) ); + } + + if ( $related_id ) { + $authorlink = get_permalink( $related_id ); + $author = get_the_title( $related_id ); + } else { + $authorlink = get_author_posts_url( get_the_author_meta( 'ID' ) ); + $author = get_the_author(); + } + + return [ + 'name' => $author, + 'avatar' => $url, + 'link' => $authorlink, + ]; + } + + /** + * Gets status + * + * @access public + * @return array + */ + public function get_category_tax() { + $terms = wp_get_post_terms( $this->post_id, 'property_category' ); + + return $terms; + } + + public function get_types_tax() { + $terms = wp_get_post_terms( $this->post_id, 'opalestate_types' ); + + return $terms; + } + + /** + * Gets meta box value + * + * @access public + * @param $key + * @param $single + * @return string + */ + public function get_metabox_value( $key, $single = true ) { + return get_post_meta( $this->post_id, OPALESTATE_PROPERTY_PREFIX . $key, $single ); + } + + /** + * Gets map value + * + * @access public + * @return string + */ + public function get_map() { + return $this->map; + } + + /** + * Gets address value + * + * @access public + * @return string + */ + public function get_address() { + return $this->address; + } + + /** + * Gets sku value + * + * @access public + * @return string + */ + public function get_sku() { + return $this->sku; + } + + /** + * Gets video url value + * + * @access public + * @return string + */ + + public function get_video_url() { + return $this->get_metabox_value( 'video' ); + } + + /** + * Gets 360 virtual tour value + * + * @access public + * @return string + */ + public function get_virtual_tour() { + return $this->get_metabox_value( 'virtual' ); + } + + /** + * Gets gallery ids value + * + * @access public + * @return array + */ + public function get_gallery() { + return $this->get_metabox_value( 'gallery', true ); + } + + + public function get_gallery_count() { + $count = $this->get_gallery(); + + return count( $count ); + } + + /** + * Gets price value + * + * @access public + * @return string + */ + public function get_price() { + return $this->price; + } + + /** + * Gets sale price value + * + * @access public + * @return string + */ + public function get_sale_price() { + return $this->saleprice; + } + + /** + * Gets price value + * + * @access public + * @return string + */ + public function get_before_price_label() { + return $this->before_pricelabel; + } + + /** + * Gets price value + * + * @access public + * @return string + */ + public function get_price_label() { + return $this->pricelabel; + } + + /** + * Gets price format value + * + * @access public + * @return string + */ + public function get_format_price() { + return $this->get_metabox_value( 'formatprice' ); + } + + public function enable_google_mapview() { + return $this->get_metabox_value( 'enablemapview' ); + } + + public function get_google_map_link() { + $url = 'https://maps.google.com/maps?q=' . $this->address . '&ll=' . $this->latitude . ',' . $this->longitude . '&z=17'; + + return $url; + } + + public static function is_allowed_remove( $user_id, $item_id ) { + $item = get_post( $item_id ); + + if ( ! empty( $item->post_author ) ) { + if ( $item->post_author == $user_id ) { + return true; + } + } + + return false; + } + + public function get_price_oncall() { + return $this->get_metabox_value( 'price_oncall' ); + } + + public function get_facilities() { + return $this->get_metabox_value( 'public_facilities_group' ); + } + + public function get_attachments() { + return $this->get_metabox_value( 'attachments' ); + } + + + public function get_content_single_layout() { + return $this->get_metabox_value( 'layout' ); + } + + public function get_preview_template() { + return $this->get_metabox_value( 'preview' ); + } + + /** + * Get rating count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_rating_counts() { + return $this->get_metabox_value( 'rating_count' ) ? $this->get_metabox_value( 'rating_count' ) : 0; + } + + /** + * Get average rating. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return float + */ + public function get_average_rating() { + return $this->get_metabox_value( 'average_rating' ) ? $this->get_metabox_value( 'average_rating' ) : 0; + } + + /** + * Get review count. + * + * @param string $context What the value is for. Valid values are view and edit. + * @return int + */ + public function get_review_count() { + return $this->get_metabox_value( 'review_count' ) ? $this->get_metabox_value( 'review_count' ) : 0; + } + + public function get_rating_count_stats() { + return $this->get_metabox_value( 'rating_count_stats' ) ? $this->get_metabox_value( 'rating_count_stats' ) : [ + 5 => 0, + 4 => 0, + 3 => 0, + 2 => 0, + 1 => 0, + ]; + } + + public function get_rating_average_stats() { + return $this->get_metabox_value( 'rating_average_stats' ); + } + + public function get_apartments() { + return $this->get_metabox_value( 'apartments' ); + } + + public function get_floor_plans() { + return $this->get_metabox_value( 'public_floor_group' ); + } + + public function get_posted() { + return human_time_diff( get_the_time( 'U' ), current_time( 'timestamp' ) ) . ' ' . esc_html__( 'ago' ); + } +} diff --git a/inc/property/class-opalestate-query.php b/inc/property/class-opalestate-query.php new file mode 100755 index 00000000..464f4849 --- /dev/null +++ b/inc/property/class-opalestate-query.php @@ -0,0 +1,402 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Query { + + /** + * Set active location + */ + public static $LOCATION; + + /** + * Get Query Object to display list of agents + */ + public static function get_agents( $args = [], $featured = false ) { + $default = [ + 'post_type' => 'opalestate_agent', + 'posts_per_page' => 10, + ]; + + $args = array_merge( $default, $args ); + if ( $featured ) { + $args['meta_key'] = OPALESTATE_AGENT_PREFIX . 'featured'; + $args['meta_value'] = 1; + $args['meta_compare'] = '='; + } + + return new WP_Query( $args ); + } + + /** + * Get Query Object to display list of agents + */ + public static function get_agencies( $args = [], $featured = false ) { + $default = [ + 'post_type' => 'opalestate_agency', + 'posts_per_page' => 10, + ]; + $args = array_merge( $default, $args ); + if ( $featured ) { + $args['meta_key'] = OPALESTATE_AGENCY_PREFIX . 'featured'; + $args['meta_value'] = 1; + $args['meta_compare'] = '='; + } + + return new WP_Query( $args ); + } + + /** + * Get Query Object By post and agent with setting items per page. + */ + public static function get_agency_property( $agency_id = null, $user_id = null, $per_page = 10, $page = null ) { + if ( null == $agency_id ) { + $agency_id = get_the_ID(); + } + + $paged = $page ? $page : ( ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' ) ); + + // if this has not any relationship with any user + if ( $user_id ) { + + $author = [ $user_id ]; //echo '
            '.print_r( $post_id, 1 );die;
            +			$team   = get_post_meta( $agency_id, OPALESTATE_AGENCY_PREFIX . 'team', true );
            +
            +			if ( is_array( $team ) ) {
            +				$author = array_merge( $author, $team );
            +			}
            +
            +			$args = [
            +				'post_type'      => 'opalestate_property',
            +				'author__in'     => $author,
            +				'posts_per_page' => $per_page,
            +				'paged'          => $paged,
            +			];
            +		} else {
            +			$agents             = get_post_meta( $agency_id, OPALESTATE_AGENCY_PREFIX . 'team', true );
            +			$args               = [
            +				'post_type'      => 'opalestate_property',
            +				'posts_per_page' => $per_page,
            +				'paged'          => $paged,
            +			];
            +			$args['meta_query'] = [ 'relation' => 'OR' ];
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'agency',
            +				'value'   => $agency_id,
            +				'compare' => '=',
            +			] );
            +
            +			if ( $agents ) {
            +				array_push( $args['meta_query'], [
            +					'key'   => OPALESTATE_PROPERTY_PREFIX . 'agent',
            +					'value' => $agents,
            +				] );
            +			}
            +
            +		}
            +
            +		$query = new WP_Query( $args );
            +
            +		return $query;
            +	}
            +
            +	/**
            +	 * Get Query Object By post and agent with setting items per page.
            +	 */
            +	public static function get_agent_property( $post_id = null, $agent_id = null, $per_page = 10, $isfeatured = false ) {
            +		if ( null == $post_id ) {
            +			$post_id = get_the_ID();
            +		}
            +
            +		$user_id = get_post_meta( $post_id, OPALESTATE_AGENT_PREFIX . 'user_id', true );
            +
            +		$paged = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' );
            +
            +		$args = [
            +			'post_type'      => 'opalestate_property',
            +			'posts_per_page' => $per_page,
            +			'post__not_in'   => [ $post_id ],
            +			'paged'          => $paged,
            +		];
            +
            +		$args['meta_query'] = [ 'relation' => 'AND' ];
            +
            +		if ( $user_id ) {
            +			$args['author'] = $user_id;
            +		} else {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'agent',
            +				'value'   => $agent_id,
            +				'compare' => '=',
            +			] );
            +		}
            +
            +		if ( $isfeatured ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'featured',
            +				'value'   => 'on',
            +				'compare' => '=',
            +			] );
            +		}
            +		$query = new WP_Query( $args );
            +
            +		return $query;
            +	}
            +
            +	/**
            +	 * Get Query Object to show featured properties with custom setting via Arguments passing.
            +	 */
            +	public static function get_featured_properties_query( $args = [] ) {
            +		$default = [
            +			'post_type'      => 'opalestate_property',
            +			'posts_per_page' => 10,
            +			'meta_key'       => OPALESTATE_PROPERTY_PREFIX . 'featured',
            +			'meta_value'     => 1,
            +			'meta_compare'   => '=',
            +
            +		];
            +
            +		$args = array_merge( $default, $args );
            +
            +		return new WP_Query( $args );
            +	}
            +
            +	/**
            +	 * Set filter location to query when user set his location as global filterable.
            +	 */
            +	public static function set_location( $args ) {
            +		if ( $args && self::$LOCATION ) {
            +			$tax_query         = [
            +				[
            +					'taxonomy' => 'opalestate_location',
            +					'field'    => 'slug',
            +					'terms'    => self::$LOCATION,
            +				],
            +			];
            +			$args['tax_query'] = [ 'relation' => 'AND' ];
            +			$args['tax_query'] = array_merge( $args['tax_query'], $tax_query );
            +		}
            +
            +		return $args;
            +	}
            +
            +	/**
            +	 * Get WP Query Object with custom passing arguments and User request as get data.
            +	 */
            +	public static function get_property_query( $args = [] ) {
            +		$condition = [
            +			'post_type'      => 'opalestate_property',
            +			'posts_per_page' => isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : 5,
            +			'paged'          => isset( $args['paged'] ) ? $args['paged'] : 1,
            +		];
            +
            +		$condition = array_merge( $condition, $args );
            +		$relation  = "AND";
            +
            +		$condition['meta_query'] = [];
            +
            +		$condition['tax_query'] = [
            +			'relation' => $relation,
            +		];
            +
            +		if ( ! empty( $args['categories'] ) ) {
            +			array_push( $condition['tax_query'], [
            +				'taxonomy' => 'property_category',
            +				'terms'    => implode( ',', $args['categories'] ),
            +				'field'    => 'slug',
            +				'operator' => 'IN',
            +			] );
            +		}
            +
            +		if ( ! empty( $args['types'] ) ) {
            +			array_push( $condition['tax_query'], [
            +				'taxonomy' => 'opalestate_types',
            +				'terms'    => $args['types'],
            +				'field'    => 'slug',
            +				'operator' => 'IN',
            +			] );
            +		}
            +
            +
            +		if ( ! empty( $args['statuses'] ) ) {
            +			array_push( $condition['tax_query'], [
            +				'taxonomy' => 'opalestate_status',
            +				'terms'    => $args['statuses'],
            +				'field'    => 'slug',
            +				'operator' => 'IN',
            +			] );
            +		}
            +
            +
            +		if ( ! empty( $args['labels'] ) ) {
            +			array_push( $condition['tax_query'], [
            +				'taxonomy' => 'opalestate_label',
            +				'terms'    => $args['labels'],
            +				'field'    => 'slug',
            +			] );
            +		}
            +
            +		if ( ! empty( $args['cities'] ) ) {
            +			array_push( $condition['tax_query'], [
            +				'taxonomy' => 'opalestate_city',
            +				'terms'    => $args['cities'],
            +				'field'    => 'slug',
            +				'operator' => 'IN',
            +			] );
            +		}
            +
            +		if ( ! empty( $args['showmode'] ) ) {
            +			if ( $args['showmode'] == 'featured' ) {
            +				array_push( $condition['meta_query'], [
            +					'key'     => OPALESTATE_PROPERTY_PREFIX . 'featured',
            +					'value'   => 'on',
            +					'compare' => '=',
            +				] );
            +			} elseif ( $args['showmode'] == 'normal' ) {
            +				array_push( $condition['meta_query'], [
            +					'relation' => 'OR',
            +					[
            +						'key'     => OPALESTATE_PROPERTY_PREFIX . 'featured',
            +						'compare' => 'NOT EXISTS',
            +						'value'   => '' // This is ignored, but is necessary...
            +					],
            +					[
            +						'key'     => OPALESTATE_PROPERTY_PREFIX . 'featured',
            +						'value'   => 'on',
            +						'compare' => '!=',
            +					],
            +				] );
            +			}
            +		}
            +
            +		$query = new WP_Query( $condition );
            +
            +		wp_reset_postdata();
            +
            +		return $query;
            +	}
            +
            +	/**
            +	 * Get Agent id by property id
            +	 */
            +	public static function get_agent_by_property( $post_id = null ) {
            +		if ( null == $post_id ) {
            +			$post_id = get_the_ID();
            +		}
            +		$agent_id = get_post_meta( $post_id, OPALESTATE_PROPERTY_PREFIX . 'agent', true );
            +
            +		return $agent_id;
            +	}
            +
            +	/**
            +	 * Get List of properties by user
            +	 */
            +	public static function get_properties_by_user( $oargs = [], $user_id = null ) {
            +
            +		$paged    = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' );
            +		$per_page = 9;
            +
            +		$args = [
            +			'post_type'      => 'opalestate_property',
            +			'paged'          => $paged,
            +			'post_status'    => 'any',
            +			'author'         => $user_id,
            +			'posts_per_page' => $per_page,
            +
            +		];
            +		if ( ! empty( $oargs ) || is_array( $oargs ) ) {
            +			$args = array_merge( $args, $oargs );
            +		}
            +
            +		if ( isset( $args['featured'] ) && $args['featured'] ) {
            +			$args = array_merge( $args,
            +				[
            +					'meta_key'     => OPALESTATE_PROPERTY_PREFIX . 'featured',
            +					'meta_value'   => 'on',
            +					'meta_compare' => '=',
            +				] );
            +			unset( $args['featured'] );
            +
            +		}
            +		$query = new WP_Query( $args );
            +		wp_reset_postdata();
            +
            +		return $query;
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public static function get_amenities() {
            +		return get_terms( 'opalestate_amenities', [ 'hide_empty' => false ] );
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public static function filter_by_location( $geo_lat, $geo_long, $radius, $prefix = OPALESTATE_PROPERTY_PREFIX ) {
            +
            +		global $wpdb;
            +
            +		$radius_measure = '';
            +		$earth          = 3959;
            +
            +		if ( $radius_measure == 'km' ) {
            +			$earth = 6371;
            +		}
            +
            +		$latitude  = $prefix . 'map_latitude';
            +		$longitude = $prefix . 'map_longitude';
            +
            +		$sql = "SELECT $wpdb->posts.ID,
            +            ( %s * acos(
            +                    cos( radians(%s) ) *
            +                    cos( radians( latitude.meta_value ) ) *
            +                    cos( radians( longitude.meta_value ) - radians(%s) ) +
            +                    sin( radians(%s) ) *
            +                    sin( radians( latitude.meta_value ) )
            +            ) )
            +            AS distance, latitude.meta_value AS latitude, longitude.meta_value AS longitude
            +            FROM $wpdb->posts
            +            INNER JOIN $wpdb->postmeta
            +                    AS latitude
            +                    ON $wpdb->posts.ID = latitude.post_id
            +            INNER JOIN $wpdb->postmeta
            +                    AS longitude
            +                    ON $wpdb->posts.ID = longitude.post_id
            +            WHERE 1=1
            +
            +                    AND latitude.meta_key = '" . $latitude . "'
            +                    AND longitude.meta_key= '" . $longitude . "'
            +            HAVING distance < %s
            +            ORDER BY $wpdb->posts.menu_order ASC, distance ASC";
            +
            +		$query = $wpdb->prepare( $sql,
            +
            +			$earth,
            +			$geo_lat,
            +			$geo_long,
            +			$geo_lat,
            +			$radius
            +		);
            +
            +		$post_ids = $wpdb->get_results( $query, OBJECT_K );
            +		if ( $post_ids ) {
            +			$post_ids = array_keys( $post_ids );
            +
            +			return $post_ids;
            +		}
            +
            +		return [ 0 ];
            +	}
            +}
            diff --git a/inc/property/class-opalestate-search.php b/inc/property/class-opalestate-search.php
            new file mode 100755
            index 00000000..f4e1ae24
            --- /dev/null
            +++ b/inc/property/class-opalestate-search.php
            @@ -0,0 +1,484 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            +
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +class OpalEstate_Search {
            +	/**
            +	 * Add action to ajax search to display query data results with json format.
            +	 */
            +	public static function init() {
            +		add_action( 'wp_ajax_opalestate_ajx_get_properties', [ __CLASS__, 'get_search_json' ] );
            +		add_action( 'wp_ajax_nopriv_opalestate_ajx_get_properties', [ __CLASS__, 'get_search_json' ] );
            +
            +		add_action( 'wp_ajax_opalestate_render_get_properties', [ __CLASS__, 'render_get_properties' ] );
            +		add_action( 'wp_ajax_nopriv_opalestate_render_get_properties', [ __CLASS__, 'render_get_properties' ] );
            +		//	add_filter( "pre_get_posts",   array( __CLASS__, 'change_archive_query' )   );
            +	}
            +
            +	/**
            +	 * Get Query Object to display collection of property with user request which submited via search form
            +	 */
            +	public static function get_search_results_query( $limit = 9 ) {
            +		// global $paged;
            +		global $wp_query;
            +
            +		$show_featured_first = opalestate_options( 'show_featured_first', 1 );
            +		$search_min_price    = isset( $_GET['min_price'] ) ? sanitize_text_field( $_GET['min_price'] ) : '';
            +		$search_max_price    = isset( $_GET['max_price'] ) ? sanitize_text_field( $_GET['max_price'] ) : '';
            +
            +		$search_min_area = isset( $_GET['min_area'] ) ? sanitize_text_field( $_GET['min_area'] ) : '';
            +		$search_max_area = isset( $_GET['max_area'] ) ? sanitize_text_field( $_GET['max_area'] ) : '';
            +		$s               = isset( $_GET['search_text'] ) ? sanitize_text_field( $_GET['search_text'] ) : null;
            +		$location_text   = isset( $_GET['location_text'] ) ? sanitize_text_field( $_GET['location_text'] ) : null;
            +
            +		$posts_per_page = apply_filters( 'opalestate_search_property_per_page', opalestate_options( 'search_property_per_page', $limit ) );
            +
            +		$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
            +		$paged = isset( $wp_query->query['paged'] ) ? $wp_query->query['paged'] : $paged;
            +		$paged = ! empty( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : $paged;
            +
            +		if ( isset( $_GET['paged'] ) && intval( $_GET['paged'] ) > 0 ) {
            +			$paged = intval( $_GET['paged'] );
            +		}
            +
            +		$infos = [];
            +
            +		$args = [
            +			'posts_per_page' => $posts_per_page,
            +			'paged'          => $paged,
            +			'post_type'      => 'opalestate_property',
            +			'post_status'    => 'publish',
            +			's'              => $s,
            +		];
            +
            +
            +		$tax_query = [];
            +
            +		if ( isset( $_GET['location'] ) && $_GET['location'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_location',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['location'] ),
            +				];
            +		}
            +
            +		if ( isset( $_GET['state'] ) && $_GET['state'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_state',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['state'] ),
            +				];
            +		}
            +
            +		if ( isset( $_GET['city'] ) && $_GET['city'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_city',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['city'] ),
            +				];
            +		}
            +
            +		if ( isset( $_GET['types'] ) && $_GET['types'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_types',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['types'] ),
            +				];
            +		}
            +
            +		if ( isset( $_GET['status'] ) && $_GET['status'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_status',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['status'] ),
            +				];
            +		}
            +
            +		if ( isset( $_GET['amenities'] ) && is_array( $_GET['amenities'] ) ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_amenities',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['amenities'] ),
            +				];
            +		}
            +
            +		if ( $tax_query ) {
            +			$args['tax_query'] = [ 'relation' => 'AND' ];
            +			$args['tax_query'] = array_merge( $args['tax_query'], $tax_query );
            +		}
            +
            +		$args['meta_query'] = [ 'relation' => 'AND' ];
            +		if ( isset( $_GET['info'] ) && is_array( $_GET['info'] ) ) {
            +			$metaquery = [];
            +			foreach ( $_GET['info'] as $key => $value ) {
            +				if ( trim( $value ) ) {
            +					if ( is_numeric( trim( $value ) ) ) {
            +						$fieldquery = [
            +							'key'     => OPALESTATE_PROPERTY_PREFIX . $key,
            +							'value'   => sanitize_text_field( trim( $value ) ),
            +							'compare' => '>=',
            +							'type'    => 'NUMERIC',
            +						];
            +					} else {
            +						$fieldquery = [
            +							'key'     => OPALESTATE_PROPERTY_PREFIX . $key,
            +							'value'   => sanitize_text_field( trim( $value ) ),
            +							'compare' => 'LIKE',
            +						];
            +					}
            +					$sarg        = apply_filters( 'opalestate_search_field_query_' . $key, $fieldquery );
            +					$metaquery[] = $sarg;
            +
            +				}
            +			}
            +			$args['meta_query'] = array_merge( $args['meta_query'], $metaquery );
            +		}
            +
            +		if ( $search_min_price != '' && $search_min_price != '' && is_numeric( $search_min_price ) && is_numeric( $search_max_price ) ) {
            +			if ( $search_min_price ) {
            +
            +				array_push( $args['meta_query'], [
            +					'key'     => OPALESTATE_PROPERTY_PREFIX . 'price',
            +					'value'   => [ $search_min_price, $search_max_price ],
            +					'compare' => 'BETWEEN',
            +					'type'    => 'NUMERIC',
            +				] );
            +			} else {
            +				array_push( $args['meta_query'], [
            +					[
            +						[
            +							'key'     => OPALESTATE_PROPERTY_PREFIX . 'price',
            +							'compare' => 'NOT EXISTS',
            +						],
            +						'relation' => 'OR',
            +						[
            +							'key'     => OPALESTATE_PROPERTY_PREFIX . 'price',
            +							'value'   => $search_max_price,
            +							'compare' => '<=',
            +							'type'    => 'NUMERIC',
            +						],
            +					],
            +				] );
            +			}
            +
            +		} elseif ( $search_min_price != '' && is_numeric( $search_min_price ) ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'price',
            +				'value'   => $search_min_price,
            +				'compare' => '>=',
            +				'type'    => 'NUMERIC',
            +			] );
            +		} elseif ( $search_max_price != '' && is_numeric( $search_max_price ) ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'price',
            +				'value'   => $search_max_price,
            +				'compare' => '<=',
            +				'type'    => 'NUMERIC',
            +			] );
            +		}
            +
            +		if ( $search_min_area != '' && $search_min_area != '' && is_numeric( $search_min_area ) && is_numeric( $search_max_area ) ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'areasize',
            +				'value'   => [ $search_min_area, $search_max_area ],
            +				'compare' => 'BETWEEN',
            +				'type'    => 'NUMERIC',
            +			] );
            +		} elseif ( $search_min_area != '' && is_numeric( $search_min_area ) ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'areasize',
            +				'value'   => $search_min_area,
            +				'compare' => '>=',
            +				'type'    => 'NUMERIC',
            +			] );
            +		} elseif ( $search_max_area != '' && is_numeric( $search_max_area ) ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_PROPERTY_PREFIX . 'areasize',
            +				'value'   => $search_max_area,
            +				'compare' => '<=',
            +				'type'    => 'NUMERIC',
            +			] );
            +		}
            +
            +		///// search by address and geo location ///
            +		if ( isset( $_GET['geo_long'] ) && isset( $_GET['geo_lat'] ) ) {
            +
            +			if ( $_GET['location_text'] && ( empty( $_GET['geo_long'] ) || empty( $_GET['geo_lat'] ) ) ) {
            +				array_push( $args['meta_query'], [
            +					'key'      => OPALESTATE_PROPERTY_PREFIX . 'map_address',
            +					'value'    => sanitize_text_field( trim( $_GET['location_text'] ) ),
            +					'compare'  => 'LIKE',
            +					'operator' => 'OR',
            +				] );
            +
            +			} elseif ( $_GET['geo_lat'] && $_GET['geo_long'] ) {
            +				$radius           = isset( $_GET['geo_radius'] ) ? $_GET['geo_radius'] : 5;
            +				$post_ids         = Opalestate_Query::filter_by_location( $_GET['geo_lat'], $_GET['geo_long'], $radius );
            +				$args['post__in'] = $post_ids;
            +			}
            +		}
            +
            +		/// ///
            +		$ksearchs = [];
            +
            +		if ( isset( $_REQUEST['opalsortable'] ) && ! empty( $_REQUEST['opalsortable'] ) ) {
            +			$ksearchs = explode( "_", $_REQUEST['opalsortable'] );
            +		} elseif ( isset( $_SESSION['opalsortable'] ) && ! empty( $_SESSION['opalsortable'] ) ) {
            +			$ksearchs = explode( "_", $_SESSION['opalsortable'] );
            +		}
            +
            +		if ( ! empty( $ksearchs ) && count( $ksearchs ) == 2 ) {
            +			$args['meta_key'] = OPALESTATE_PROPERTY_PREFIX . $ksearchs[0];
            +			$args['orderby']  = 'meta_value_num';
            +			$args['order']    = $ksearchs[1];
            +		}
            +
            +		$args = apply_filters( 'opalestate_get_search_results_query_args', $args );
            +
            +		$query = new WP_Query( $args );
            +
            +		wp_reset_postdata();
            +
            +		return $query;
            +	}
            +
            +	/**
            +	 * Get search query base on user request to filter collection of Agents
            +	 */
            +	public static function get_search_agents_query( $args = [] ) {
            +		$min = opalestate_options( 'search_agent_min_price', 0 );
            +		$max = opalestate_options( 'search_agent_max_price', 10000000 );
            +
            +		$search_min_price = isset( $_GET['min_price'] ) ? sanitize_text_field( $_GET['min_price'] ) : '';
            +		$search_max_price = isset( $_GET['max_price'] ) ? sanitize_text_field( $_GET['max_price'] ) : '';
            +
            +		$search_min_area = isset( $_GET['min_area'] ) ? sanitize_text_field( $_GET['min_area'] ) : '';
            +		$search_max_area = isset( $_GET['max_area'] ) ? sanitize_text_field( $_GET['max_area'] ) : '';
            +		$s               = isset( $_GET['search_text'] ) ? sanitize_text_field( $_GET['search_text'] ) : null;
            +
            +		$paged   = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' );
            +		$default = [
            +			'post_type'      => 'opalestate_agent',
            +			'posts_per_page' => apply_filters( 'opalestate_agent_per_page', 12 ),
            +			'paged'          => $paged,
            +		];
            +		$args    = array_merge( $default, $args );
            +
            +		$tax_query = [];
            +
            +
            +		if ( isset( $_GET['location'] ) && $_GET['location'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_location',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['location'] ),
            +				];
            +		}
            +
            +		if ( isset( $_GET['types'] ) && $_GET['types'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_types',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['types'] ),
            +				];
            +		}
            +
            +		if ( $tax_query ) {
            +			$args['tax_query'] = [ 'relation' => 'AND' ];
            +			$args['tax_query'] = array_merge( $args['tax_query'], $tax_query );
            +		}
            +
            +		$args['meta_query'] = [ 'relation' => 'AND' ];
            +
            +		if ( $search_min_price != $min && is_numeric( $search_min_price ) ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_AGENT_PREFIX . 'target_min_price',
            +				'value'   => $search_min_price,
            +				'compare' => '>=',
            +				// 'type' => 'NUMERIC'
            +			] );
            +		}
            +		if ( is_numeric( $search_max_price ) && $search_max_price != $max ) {
            +			array_push( $args['meta_query'], [
            +				'key'     => OPALESTATE_AGENT_PREFIX . 'target_max_price',
            +				'value'   => $search_max_price,
            +				'compare' => '<=',
            +				// 'type' => 'NUMERIC'
            +			] );
            +		}
            +
            +		return new WP_Query( $args );
            +	}
            +
            +
            +	/**
            +	 * Get search query base on user request to filter collection of Agents
            +	 */
            +	public static function get_search_agencies_query( $args = [] ) {
            +		$s = isset( $_GET['search_text'] ) ? sanitize_text_field( $_GET['search_text'] ) : null;
            +
            +		$paged   = ( get_query_var( 'paged' ) == 0 ) ? 1 : get_query_var( 'paged' );
            +		$default = [
            +			'post_type'      => 'opalestate_agency',
            +			'posts_per_page' => apply_filters( 'opalestate_agency_per_page', 12 ),
            +			'paged'          => $paged,
            +		];
            +		$args    = array_merge( $default, $args );
            +
            +		$tax_query = [];
            +
            +
            +		if ( isset( $_GET['location'] ) && $_GET['location'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_location',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['location'] ),
            +				];
            +		}
            +
            +		if ( isset( $_GET['types'] ) && $_GET['types'] != -1 ) {
            +			$tax_query[] =
            +				[
            +					'taxonomy' => 'opalestate_types',
            +					'field'    => 'slug',
            +					'terms'    => sanitize_text_field( $_GET['types'] ),
            +				];
            +		}
            +
            +		if ( $tax_query ) {
            +			$args['tax_query'] = [ 'relation' => 'AND' ];
            +			$args['tax_query'] = array_merge( $args['tax_query'], $tax_query );
            +		}
            +
            +		$args['meta_query'] = [ 'relation' => 'AND' ];
            +
            +
            +		return new WP_Query( $args );
            +	}
            +
            +
            +	public function filter_by_geolocations() {
            +
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public static function get_setting_search_fields( $option = '' ) {
            +		$options = [
            +			OPALESTATE_PROPERTY_PREFIX . 'bedrooms'  => esc_html__( 'Bed Rooms', 'opalestate-pro' ),
            +			OPALESTATE_PROPERTY_PREFIX . 'parking'   => esc_html__( 'Parking', 'opalestate-pro' ),
            +			OPALESTATE_PROPERTY_PREFIX . 'bathrooms' => esc_html__( 'Bath Rooms', 'opalestate-pro' ),
            +		];
            +
            +		$default = apply_filters( 'opalestate_default_fields_setting', $options );
            +
            +		$metas     = Opalestate_Property_MetaBox::metaboxes_info_fields();
            +		$esettings = [];
            +		$found     = false;
            +		foreach ( $metas as $key => $meta ) {
            +			$value = opalestate_options( $meta['id'] . '_opt' . $option );
            +
            +			if ( preg_match( "#areasize#", $meta['id'] ) ) {
            +				continue;
            +			}
            +
            +			if ( $value ) {
            +				$id               = str_replace( OPALESTATE_PROPERTY_PREFIX, "", $meta['id'] );
            +				$esettings[ $id ] = $meta['name'];
            +			}
            +			if ( $value == 0 ) {
            +				$found = true;
            +			}
            +		}
            +
            +		if ( ! empty( $esettings ) ) {
            +			return $esettings;
            +		} elseif ( $found ) {
            +			return [];
            +		}
            +
            +		return $default;
            +	}
            +
            +	/**
            +	 * Get Json data by action ajax filter
            +	 */
            +	public static function get_search_json() {
            +
            +		$query = self::get_search_results_query();
            +
            +		$output = [];
            +
            +		while ( $query->have_posts() ) {
            +
            +			$query->the_post();
            +			$property = opalesetate_property( get_the_ID() );
            +			$output[] = $property->get_meta_search_objects();
            +		}
            +
            +		wp_reset_query();
            +
            +		echo json_encode( $output );
            +		exit;
            +	}
            +
            +	public static function render_get_properties() {
            +		// $_GET = $_POST;
            +		echo opalestate_load_template_path( 'shortcodes/ajax-map-search-result' );
            +		die;
            +	}
            +
            +	/**
            +	 * Render search property form in horizontal
            +	 */
            +	public static function render_horizontal_form( $atts = [] ) {
            +		echo opalestate_load_template_path( 'search-box/search-form-h', $atts );
            +	}
            +
            +	/**
            +	 * Render search property form in vertical
            +	 */
            +	public static function render_vertical_form( $atts = [] ) {
            +		echo opalestate_load_template_path( 'search-box/search-form-v', $atts );
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public static function render_field_price() {
            +
            +	}
            +
            +	/**
            +	 *
            +	 */
            +	public static function render_field_area() {
            +
            +	}
            +}
            +
            +OpalEstate_Search::init();
            diff --git a/inc/property/class-opalestate-shortcodes.php b/inc/property/class-opalestate-shortcodes.php
            new file mode 100755
            index 00000000..352b5cfe
            --- /dev/null
            +++ b/inc/property/class-opalestate-shortcodes.php
            @@ -0,0 +1,125 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            + 
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +/**
            + * @class OpalEstate_Shortcodes
            + *
            + * @version 1.0
            + */
            +class OpalEstate_Shortcodes{
            +
            +	/**
            +	 * Static $shortcodes
            +	 */
            +	public $shortcodes;
            +
            +	/**
            +	 * defined list of shortcode and functions of this for each.
            +	 */
            +	public function __construct(){
            +
            +	 	$this->shortcodes = array(
            +
            +	 		'search_properties_result'	=> array( 'code' => 'search_properties_result', 'label' => esc_html__( 'Search Properties Result', 'opalestate-pro' ) ),
            +	 		'search_properties'    		=> array( 'code' => 'search_properties', 'label'    	=> esc_html__( 'Search Properties', 'opalestate-pro' ) ),
            +	 		'search_properties_v'  		=> array( 'code' => 'search_properties_v', 'label'   	=> esc_html__( 'Search Properties Vertical', 'opalestate-pro' ) ),
            +	 	
            +	 		'search_map_properties'		=> array( 'code' => 'search_map_properties', 'label' 	=> esc_html__( 'Search Map Properties', 'opalestate-pro' ) ),
            +	 		'ajax_map_search'			=> array( 'code' => 'ajax_map_search', 'label' 			=> esc_html__( 'Ajax Search Map Properties', 'opalestate-pro' ) ),
            +	 		'ajax_map_quick_search'	    => array( 'code' => 'ajax_map_quick_search', 'label' 	=> esc_html__( 'Ajax Search Map Properties', 'opalestate-pro' ) ),
            +	 		'register_form'	    		=> array( 'code' => 'register_form', 'label' 			=> esc_html__( 'Register User Form', 'opalestate-pro' ) ),
            +	 		'login_form'	    	    => array( 'code' => 'login_form', 'label' 				=> esc_html__( 'Login Form', 'opalestate-pro' ) ),
            +	 	);
            +
            +	 	foreach( $this->shortcodes as $shortcode ){ 
            +	 		add_shortcode( 'opalestate_'.$shortcode['code'] , array( $this, $shortcode['code'] ) );
            +	 	}
            +
            +	 	if( is_admin() ){
            +	 		add_action( 'media_buttons', array( $this, 'shortcode_button' ) );
            +	 	}
            +
            +	}
            +
            +	public function shortcode_button(){
            +		
            +	}
            +
            +	public function search_properties_result(){
            +		return opalestate_load_template_path( 'shortcodes/search-properties-result' );
            +	}
            +
            +
            +
            +	/**
            +	 * Display all properties follow user when logined
            +	 */
            +	public function agent_property(){
            +		return opalestate_load_template_path( 'shortcodes/agent-property-listing' );
            +	}
            +
            +	/**
            +	 * Render search property page with horizontal form and map
            +	 */
            +	public function search_properties(){
            +		return opalestate_load_template_path( 'shortcodes/search-properties', array( 'loop' => '') );
            +	}
            +
            +	/**
            +	 * Render search property page with vertical form and map
            +	 */
            +	public function search_properties_v(){
            +		return opalestate_load_template_path( 'shortcodes/search-properties-v', array( 'loop' => '') );
            +	}
            +
            +	public function search_map_properties(){
            +		return opalestate_load_template_path( 'shortcodes/search-map-properties', array( 'loop' => '') );	
            +	}
            +
            +	public function ajax_map_search(){ 
            +		wp_enqueue_script( 'sticky-kit', OPALESTATE_PLUGIN_URL . 'assets/js/jquery.sticky-kit.min.js'  );
            +		return opalestate_load_template_path( 'shortcodes/ajax-map-search', array( 'loop' => '') );	
            +	}
            +
            +	public function ajax_map_quick_search(){ 
            +		return  opalestate_load_template_path( 'shortcodes/ajax-map-quick-search', array( 'loop' => '') );	
            +	}
            +
            +	/* register form show up */
            +	public function register_form( $atts = array() ) {
            +		$atts = shortcode_atts( array(
            + 				'message' 	=> '',
            + 				'redirect'	=> '',
            + 				'hide_title'	=> false
            +			), $atts );
            +		return opalestate_load_template_path( 'user/register-form', $atts );
            +	}
            +
            +	/* sign in show up */
            +	public function login_form( $atts = array() ) {
            +		$atts = shortcode_atts( array(
            + 				'message' 	=> '',
            + 				'redirect'	=> '',
            + 				'hide_title'	=> false
            +			), $atts );
            +		return opalestate_load_template_path( 'user/login-form', $atts );
            +	}
            +
            +}
            +
            +new OpalEstate_Shortcodes();
            diff --git a/inc/property/class-opalestate-view-stats.php b/inc/property/class-opalestate-view-stats.php
            new file mode 100755
            index 00000000..d5008d1a
            --- /dev/null
            +++ b/inc/property/class-opalestate-view-stats.php
            @@ -0,0 +1,155 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            +
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +class Opalestate_View_Stats {
            +	protected $id;
            +
            +	protected $record;
            +
            +	public function __construct( $id, $record = 8 ) {
            +
            +		$this->id = $id;
            +
            +		$this->record = $record;
            +
            +		$this->count_page_stats();
            +	}
            +
            +	/**
            +	 * @return mixed
            +	 */
            +	public static function get_real_ip_addr() {
            +		if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) { //check ip from share internet
            +			$ip = $_SERVER['HTTP_CLIENT_IP'];
            +		} elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { //to check ip is pass from proxy
            +			$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            +		} elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
            +			$ip = $_SERVER['REMOTE_ADDR'];
            +		} else {
            +			$ip = '';
            +		}
            +
            +		return $ip;
            +	}
            +
            +	/**
            +	 * Count page views.
            +	 */
            +	public function count_page_stats() {
            +		// Get IPs.
            +		$ips = $this->get_ips_viewed();
            +
            +		$current_ip = static::get_real_ip_addr();
            +
            +		if ( ! in_array( $current_ip, $ips ) ) {
            +			// Update IPS.
            +			array_push( $ips, $current_ip );
            +			update_post_meta( $this->id, 'opalestate_ips_viewed', $ips );
            +
            +			// Count and update total views.
            +			$total_views = intval( get_post_meta( $this->id, 'opalestate_total_views', true ) );
            +			if ( $total_views == '' ) {
            +				$total_views = 1;
            +			} else {
            +				$total_views++;
            +			}
            +
            +			update_post_meta( $this->id, 'opalestate_total_views', $total_views );
            +
            +			// Update detailed views.
            +			$today          = date( 'm-d-Y', time() );
            +			$detailed_views = get_post_meta( $this->id, 'opalestate_detailed_views', true );
            +
            +			if ( $detailed_views == '' || ! is_array( $detailed_views ) ) {
            +				$detailed_views           = [];
            +				$detailed_views[ $today ] = 1;
            +			} else {
            +				if ( ! isset( $detailed_views[ $today ] ) ) {
            +					if ( count( $detailed_views ) > 15 ) {
            +						array_shift( $detailed_views );
            +					}
            +
            +					$detailed_views[ $today ] = 1;
            +				} else {
            +					$detailed_views[ $today ] = intval( $detailed_views[ $today ] ) + 1;
            +				}
            +			}
            +
            +			$detailed_views = update_post_meta( $this->id, 'opalestate_detailed_views', $detailed_views );
            +		}
            +	}
            +
            +
            +	public function get_traffic_labels() {
            +		$detailed_views = get_post_meta( $this->id, 'opalestate_detailed_views', true );
            +
            +		if ( ! is_array( $detailed_views ) ) {
            +			$detailed_views = [];
            +		}
            +
            +		$array_label = array_keys( $detailed_views );
            +		$array_label = array_slice( $array_label, -1 * $this->record, $this->record, false );
            +
            +		return $array_label;
            +	}
            +
            +
            +	public function get_traffic_data() {
            +		$detailed_views = get_post_meta( $this->id, 'opalestate_detailed_views', true );
            +		if ( ! is_array( $detailed_views ) ) {
            +			$detailed_views = [];
            +		}
            +		$array_values = array_values( $detailed_views );
            +		$array_values = array_slice( $array_values, -1 * $this->record, $this->record, false );
            +
            +		return $array_values;
            +	}
            +
            +
            +	public function get_traffic_data_accordion() {
            +		$detailed_views = get_post_meta( $this->id, 'opalestate_detailed_views', true );
            +		if ( ! is_array( $detailed_views ) ) {
            +			$detailed_views = [];
            +		}
            +
            +		// since this runs before we increment the visits - on acc page style
            +		$today = date( 'm-d-Y', time() );
            +
            +		if ( isset( $detailed_views[ $today ] ) ) {
            +			$detailed_views[ $today ] = intval( $detailed_views[ $today ] ) + 1;
            +		}
            +
            +		$array_values = array_values( $detailed_views );
            +		$array_values = array_slice( $array_values, -1 * $this->record, $this->record, false );
            +
            +		return $array_values;
            +	}
            +
            +	/**
            +	 * Get IPs viewed.
            +	 *
            +	 * @return array
            +	 */
            +	public function get_ips_viewed() {
            +		$ips = get_post_meta( $this->id, 'opalestate_ips_viewed', true );
            +		if ( ! $ips ) {
            +			$ips = [];
            +		}
            +
            +		return $ips;
            +	}
            +}
            diff --git a/inc/property/functions.php b/inc/property/functions.php
            new file mode 100755
            index 00000000..e69de29b
            diff --git a/inc/query-functions.php b/inc/query-functions.php
            new file mode 100755
            index 00000000..aa724889
            --- /dev/null
            +++ b/inc/query-functions.php
            @@ -0,0 +1,84 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            +
            +if ( ! defined( 'ABSPATH' ) ) {
            +    exit; // Exit if accessed directly
            +}
            +
            +function opalestate_clean_attachments( $user_id ){
            +    
            +  
            +    $query = new WP_Query( 
            +        array( 
            +            'post_type'   => 'attachment', 
            +            'post_status' => 'inherit', 
            +            'author'      => $user_id , 
            +            'meta_query' => array(
            +                array(
            +                    'key' => '_pending_to_use_',
            +                     'value' => 1,
            +                     'compare' => '>=',
            +                )
            +            )    
            +        ) 
            +    );
            +  
            +    if( $query->have_posts() ){   
            +        while( $query->have_posts() ){ $query->the_post();
            +            wp_delete_attachment( get_the_ID() );
            +        }
            +    }
            +    wp_reset_postdata(); 
            +}
            + 
            +
            +/****/
            +add_filter( 'pre_get_posts', 'opalestate_archives_property_query', 1 );
            +function opalestate_archives_property_query( $query ){
            +
            +    if( $query->is_main_query() && ( is_post_type_archive( 'opalestate_property' ) || is_tax('property_category') || is_tax('opalestate_amenities') || is_tax('opalestate_location') || is_tax('opalestate_types') ) ){
            +
            +        $args = array();
            +        $ksearchs = array();
            +       
            +        if( isset($_REQUEST['opalsortable']) && !empty($_REQUEST['opalsortable']) ){
            +            $ksearchs = explode( "_", $_REQUEST['opalsortable'] );  
            +        } 
            +    
            +        if( !empty($ksearchs) && count($ksearchs) == 2 ){
            +            $args['meta_key'] = OPALESTATE_PROPERTY_PREFIX.$ksearchs[0];
            +            $args['orderby']  = 'meta_value_num';
            +            $args['order']    = $ksearchs[1];   
            +        }
            +
            +        if( isset( $_GET['status']) &&  !empty($_GET['status']) && $_GET['status'] != 'all' ){
            +            $tax_query = array(
            +                array(
            +                    'taxonomy' => 'opalestate_status',
            +                    'field'    => 'slug',
            +                    'terms'    =>  sanitize_text_field( $_GET['status'] ),
            +                ),
            +            );
            +            $args['tax_query'] = array('relation' => 'AND');
            +            $args['tax_query'] = array_merge( $args['tax_query'], $tax_query );
            +        }
            +
            +        if( $args ){
            +            foreach( $args as $key => $value ){
            +                $query->set( $key, $value );
            +            }
            +        }
            +
            +    }
            +}
            diff --git a/inc/rating/class-opalestate-rating-features-posttype.php b/inc/rating/class-opalestate-rating-features-posttype.php
            new file mode 100755
            index 00000000..89025971
            --- /dev/null
            +++ b/inc/rating/class-opalestate-rating-features-posttype.php
            @@ -0,0 +1,87 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            +
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +/**
            + * Class Opalestate_PostType_Rating_Features
            + */
            +class Opalestate_PostType_Rating_Features {
            +	/**
            +	 * Init action and filter data to define property post type
            +	 */
            +	public function __construct() {
            +		add_action( 'init', [ $this, 'definition' ] );
            +	}
            +
            +	/**
            +	 * Definition
            +	 */
            +	public function definition() {
            +		if ( ! is_blog_installed() ) {
            +			return;
            +		}
            +
            +		$rating_supports = Opalestate_Rating::get_rating_supports();
            +
            +		foreach ( $rating_supports as $key => $support ) {
            +			$this->register_post_type( $support['features_cpt'], $support['post_type'] );
            +		}
            +	}
            +
            +	public function register_post_type( $cpt_feature, $cpt_support ) {
            +		if ( post_type_exists( $cpt_feature ) ) {
            +			return;
            +		}
            +
            +		register_post_type( $cpt_feature, apply_filters( $cpt_feature . '_cpt_args', [
            +			'labels'              => [
            +				'name'                  => esc_html_x( 'Rating Features', 'Feature plural name', 'opalestate-pro' ),
            +				'singular_name'         => esc_html_x( 'Rating Feature', 'Feature singular name', 'opalestate-pro' ),
            +				'menu_name'             => esc_html_x( 'Rating Features', 'Admin menu name', 'opalestate-pro' ),
            +				'add_new'               => esc_html__( 'Add rating feature', 'opalestate-pro' ),
            +				'add_new_item'          => esc_html__( 'Add new rating feature', 'opalestate-pro' ),
            +				'edit'                  => esc_html__( 'Edit', 'opalestate-pro' ),
            +				'edit_item'             => esc_html__( 'Edit rating feature', 'opalestate-pro' ),
            +				'new_item'              => esc_html__( 'New rating feature', 'opalestate-pro' ),
            +				'view_item'             => esc_html__( 'View rating feature', 'opalestate-pro' ),
            +				'search_items'          => esc_html__( 'Query rating features', 'opalestate-pro' ),
            +				'not_found'             => esc_html__( 'No rating features found', 'opalestate-pro' ),
            +				'not_found_in_trash'    => esc_html__( 'No rating features found in trash', 'opalestate-pro' ),
            +				'parent'                => esc_html__( 'Parent rating features', 'opalestate-pro' ),
            +				'filter_items_list'     => esc_html__( 'Filter rating features', 'opalestate-pro' ),
            +				'items_list_navigation' => esc_html__( 'Rating Features navigation', 'opalestate-pro' ),
            +				'items_list'            => esc_html__( 'Rating Features List', 'opalestate-pro' ),
            +			],
            +			'description'         => esc_html__( 'This is where store rating features are stored.', 'opalestate-pro' ),
            +			'public'              => false,
            +			'hierarchical'        => false,
            +			'exclude_from_search' => true,
            +			'publicly_queryable'  => false,
            +			'show_ui'             => true,
            +			'show_in_menu'        => 'edit.php?post_type=' . $cpt_support,
            +			'show_in_nav_menus'   => false,
            +			'show_in_admin_bar'   => false,
            +			'show_in_rest'        => true,
            +			'map_meta_cap'        => true,
            +			'supports'            => [ 'title' ],
            +			'rewrite'             => false,
            +			'has_archive'         => false,
            +		] ) );
            +	}
            +}
            +
            +new Opalestate_PostType_Rating_Features();
            diff --git a/inc/rating/class-opalestate-rating-helper.php b/inc/rating/class-opalestate-rating-helper.php
            new file mode 100755
            index 00000000..3f24dcad
            --- /dev/null
            +++ b/inc/rating/class-opalestate-rating-helper.php
            @@ -0,0 +1,169 @@
            + $feature_title ) {
            +				$sum += absint( get_comment_meta( $comment->comment_ID, $cpt_feature . '_' . $feature_slug, true ) );
            +			}
            +
            +			$average = number_format( $sum / count( $features ), 1 );
            +		} else {
            +			$average = absint( get_comment_meta( $comment->comment_ID, 'opalestate_rating', true ) );
            +		}
            +
            +		return $average;
            +	}
            +
            +	/**
            +	 * Get property rating for a property. Please note this is not cached.
            +	 *
            +	 * @return float
            +	 */
            +	public static function get_average_rating_for_post( $post_id, $cpt_feature ) {
            +		$comments = get_comments( [ 'post_id' => $post_id, 'status' => 'approve' ] );
            +		if ( ! $comments ) {
            +			return 0;
            +		}
            +
            +		$sum = 0;
            +		foreach ( $comments as $comment ) {
            +			$sum += static::get_average_rating( $comment, $cpt_feature );
            +		}
            +
            +		return number_format( $sum / static::get_review_count_for_post( $post_id ), 2 );
            +	}
            +
            +	/**
            +	 * Get property review count for a property (not replies). Please note this is not cached.
            +	 */
            +	public static function get_review_count_for_post( $post_id ) {
            +		global $wpdb;
            +
            +		$count = $wpdb->get_var(
            +			$wpdb->prepare(
            +				"
            +			SELECT COUNT(*) FROM $wpdb->comments
            +			WHERE comment_parent = 0
            +			AND comment_post_ID = %d
            +			AND comment_approved = '1'
            +				",
            +				$post_id
            +			)
            +		);
            +
            +		return $count;
            +	}
            +
            +	/**
            +	 * Get property rating count for a property. Please note this is not cached.
            +	 */
            +	public static function get_rating_counts_for_post( $post_id, $cpt_feature ) {
            +		$features = static::get_features( $cpt_feature );
            +		if ( $features ) {
            +			return static::get_review_count_for_post( $post_id ) * count( $features );
            +		}
            +
            +		return static::get_review_count_for_post( $post_id );
            +	}
            +
            +	public static function get_rating_count_stats_for_post( $post_id, $cpt_feature ) {
            +		$output = [
            +			5 => 0,
            +			4 => 0,
            +			3 => 0,
            +			2 => 0,
            +			1 => 0,
            +		];
            +
            +		$features = static::get_features( $cpt_feature );
            +
            +		for ( $i = 5; $i >= 1; $i-- ) {
            +			$args = [
            +				'post_id' => $post_id,
            +				'count'   => true,
            +				'status' => 'approve',
            +			];
            +
            +			if ( $features ) {
            +				$features_query = [];
            +				foreach ( $features as $feature_slug => $feature_title ) {
            +					$features_query[] = [
            +						'key'   => $cpt_feature . '_' . $feature_slug,
            +						'value' => $i,
            +					];
            +				}
            +				$args['meta_query']             = $features_query;
            +				$args['meta_query']['relation'] = 'OR';
            +			} else {
            +				$args['meta_query'] = [
            +					[
            +						'key'   => 'opalestate_rating',
            +						'value' => $i,
            +					],
            +				];
            +			}
            +
            +			$output[ $i ] = get_comments( $args );
            +		}
            +
            +		return $output;
            +	}
            +
            +	public static function get_rating_average_stats_by_features_for_post( $post_id, $cpt_feature, $meta_prefix ) {
            +		global $wpdb;
            +
            +		$output   = [];
            +		$count    = get_post_meta( $post_id, $meta_prefix . 'review_count', true );
            +		$features = static::get_features( $cpt_feature );
            +
            +		if ( ! $features || ! $count ) {
            +			return $output;
            +		}
            +
            +		foreach ( $features as $feature_slug => $feature_title ) {
            +			$meta_key = $cpt_feature . '_' . $feature_slug;
            +
            +			$ratings                 = $wpdb->get_var(
            +				$wpdb->prepare(
            +					"
            +				SELECT SUM(meta_value) FROM $wpdb->commentmeta
            +				LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
            +				WHERE meta_key = %s
            +				AND comment_post_ID = %d
            +				AND comment_approved = '1'
            +				AND meta_value > 0
            +					",
            +					$meta_key,
            +					$post_id
            +				)
            +			);
            +			$average                 = number_format( $ratings / $count, 2, '.', '' );
            +			$output[ $feature_slug ] = $average;
            +		}
            +
            +		return $output;
            +	}
            +
            +	public static function get_features( $cpt_feature, $posts_per_page = -1 ) {
            +		$args = [
            +			'post_type'      => $cpt_feature,
            +			'post_status'    => 'publish',
            +			'posts_per_page' => $posts_per_page,
            +			'order'          => 'ASC',
            +			'orderby'        => 'meta_value_num',
            +			'meta_key'       => 'opalestate_feature_order',
            +		];
            +
            +		$features = get_posts( $args );
            +
            +		return wp_list_pluck( $features, 'post_title', 'post_name' );
            +	}
            +}
            +
            +new Opalestate_Rating_Helper();
            diff --git a/inc/rating/class-opalestate-rating-init.php b/inc/rating/class-opalestate-rating-init.php
            new file mode 100755
            index 00000000..c5a8db6a
            --- /dev/null
            +++ b/inc/rating/class-opalestate-rating-init.php
            @@ -0,0 +1,245 @@
            +cpt_support = $cpt_support;
            +		$this->cpt_feature = $cpt_feature;
            +		$this->meta_prefix = $meta_prefix;
            +
            +		// Check comment fields.
            +		add_filter( 'comments_open', [ $this, 'comments_open' ], 10, 2 );
            +		add_filter( 'preprocess_comment', [ $this, 'check_comment_rating' ], 0 );
            +
            +		// Add comment rating.
            +		add_action( 'comment_post', [ $this, 'add_comment_rating' ], 1 );
            +
            +		// Clear transients.
            +		add_action( 'wp_update_comment_count', [ $this, 'clear_transients' ] );
            +
            +		// Support avatars for `review` comment type.
            +		add_filter( 'get_avatar_comment_types', [ $this, 'add_avatar_for_review_comment_type' ] );
            +
            +		// Set comment type.
            +		add_filter( 'preprocess_comment', [ $this, 'update_comment_type' ], 1 );
            +
            +		// Remove comment meta boxes.
            +		add_action( 'admin_menu', [ $this, 'remove_meta_boxes' ] );
            +
            +		// Clean
            +		add_action( 'trashed_post', [ $this, 'trash_feature' ] );
            +		add_action( 'untrashed_post', [ $this, 'trash_feature' ] );
            +		add_action( 'delete_post', [ $this, 'clear_meta' ] );
            +	}
            +
            +	/**
            +	 * Gets comment type.
            +	 *
            +	 * @return string
            +	 */
            +	public function get_comment_type() {
            +		return str_replace( 'opalestate_', '', $this->cpt_support ) . '_review';
            +	}
            +
            +	/**
            +	 * See if comments are open.
            +	 *
            +	 * @param bool $open    Whether the current post is open for comments.
            +	 * @param int  $post_id Post ID.
            +	 * @return bool
            +	 */
            +	public function comments_open( $open, $post_id ) {
            +		if ( $this->cpt_support === get_post_type( $post_id ) && ! post_type_supports( $this->cpt_support, 'comments' ) ) {
            +			$open = false;
            +		}
            +
            +		return $open;
            +	}
            +
            +	/**
            +	 * Validate the comment ratings.
            +	 *
            +	 * @param array $comment_data Comment data.
            +	 * @return array
            +	 */
            +	public function check_comment_rating( $comment_data ) {
            +		// If posting a comment (not trackback etc) and not logged in.
            +		$features = Opalestate_Rating_Helper::get_features( $this->cpt_feature );
            +		if ( $features ) {
            +			foreach ( $features as $feature_slug => $feature_title ) {
            +				$post = $this->cpt_feature . '_' . $feature_slug;
            +				if ( ! is_admin() && isset( $_POST['comment_post_ID'], $_POST[ $post ], $comment_data['comment_type'] ) && $this->cpt_support === get_post_type( absint( $_POST['comment_post_ID'] ) ) && empty( $_POST[ $post ] ) && '' === $comment_data['comment_type'] ) { // WPCS: input var ok, CSRF ok.
            +					wp_die( esc_html__( 'Please rate all features.', 'opalestate-pro' ) );
            +					exit;
            +				}
            +			}
            +		} else {
            +			if ( ! is_admin() && isset( $_POST['comment_post_ID'], $_POST['opalestate_rating'], $comment_data['comment_type'] ) && $this->cpt_support === get_post_type( absint( $_POST['comment_post_ID'] ) ) && empty( $_POST['opalestate_rating'] ) && '' === $comment_data['comment_type'] ) { // WPCS: input var ok, CSRF ok.
            +				wp_die( esc_html__( 'Please rate.', 'opalestate-pro' ) );
            +				exit;
            +			}
            +		}
            +
            +		return $comment_data;
            +	}
            +
            +	/**
            +	 * Rating field for comments.
            +	 *
            +	 * @param int $comment_id Comment ID.
            +	 */
            +	public function add_comment_rating( $comment_id ) {
            +		if ( ! isset( $_POST['comment_post_ID'] ) || ( $this->cpt_support !== get_post_type( absint( $_POST['comment_post_ID'] ) ) ) ) {
            +			return;
            +		}
            +
            +		$features = Opalestate_Rating_Helper::get_features( $this->cpt_feature );
            +		if ( $features ) {
            +			foreach ( $features as $feature_slug => $feature_title ) {
            +				$post = $this->cpt_feature . '_' . $feature_slug;
            +				if ( isset( $_POST[ $post ] ) ) {
            +					if ( ! $_POST[ $post ] || $_POST[ $post ] > 5 || $_POST[ $post ] < 0 ) { // WPCS: input var ok, CSRF ok, sanitization ok.
            +						continue;
            +					}
            +					add_comment_meta( $comment_id, $post, intval( $_POST[ $post ] ), true ); // WPCS: input var ok, CSRF ok.
            +				}
            +			}
            +		} else {
            +			if ( isset( $_POST['opalestate_rating'] ) ) { // WPCS: input var ok, CSRF ok.
            +				if ( ! $_POST['opalestate_rating'] || $_POST['opalestate_rating'] > 5 || $_POST['opalestate_rating'] < 0 ) { // WPCS: input var ok, CSRF ok, sanitization ok.
            +					return;
            +				}
            +				add_comment_meta( $comment_id, 'opalestate_rating', intval( $_POST['opalestate_rating'] ), true ); // WPCS: input var ok, CSRF ok.
            +			}
            +		}
            +
            +		$post_id = isset( $_POST['comment_post_ID'] ) ? absint( $_POST['comment_post_ID'] ) : 0; // WPCS: input var ok, CSRF ok.
            +		if ( $post_id ) {
            +			$this->clear_transients( $post_id );
            +		}
            +	}
            +
            +	/**
            +	 * Make sure WP displays avatars for comments with the `$this->cpt_support` type.
            +	 *
            +	 * @param array $comment_types Comment types.
            +	 * @return array
            +	 */
            +	public function add_avatar_for_review_comment_type( $comment_types ) {
            +		return array_merge( $comment_types, [ $this->get_comment_type() ] );
            +	}
            +
            +	/**
            +	 * Ensure property average rating and review count is kept up to date.
            +	 *
            +	 * @param int $post_id Post ID.
            +	 */
            +	public function clear_transients( $post_id ) {
            +		if ( $this->cpt_support === get_post_type( $post_id ) ) {
            +			do_action( 'opalestate_rating_before_clear_transients', $post_id, $this->cpt_support, $this->cpt_feature );
            +
            +			update_post_meta( $post_id, $this->meta_prefix . 'rating_count', Opalestate_Rating_Helper::get_rating_counts_for_post( $post_id, $this->cpt_feature ) );
            +			update_post_meta( $post_id, $this->meta_prefix . 'average_rating', Opalestate_Rating_Helper::get_average_rating_for_post( $post_id, $this->cpt_feature ) );
            +			update_post_meta( $post_id, $this->meta_prefix . 'review_count', Opalestate_Rating_Helper::get_review_count_for_post( $post_id ) );
            +			update_post_meta( $post_id, $this->meta_prefix . 'rating_count_stats', Opalestate_Rating_Helper::get_rating_count_stats_for_post( $post_id, $this->cpt_feature ) );
            +			update_post_meta( $post_id, $this->meta_prefix . 'rating_average_stats', Opalestate_Rating_Helper::get_rating_average_stats_by_features_for_post( $post_id, $this->cpt_feature,
            +				$this->meta_prefix ) );
            +
            +			do_action( 'opalestate_rating_after_clear_transients', $post_id, $this->cpt_support, $this->cpt_feature );
            +		}
            +	}
            +
            +	/**
            +	 * Update comment type of property reviews.
            +	 *
            +	 * @param array $comment_data Comment data.
            +	 * @return array
            +	 */
            +	public function update_comment_type( $comment_data ) {
            +		if ( ! is_admin() && isset( $_POST['comment_post_ID'], $comment_data['comment_type'] ) && '' === $comment_data['comment_type'] && $this->cpt_support === get_post_type( absint( $_POST['comment_post_ID'] ) ) ) { // WPCS: input var ok, CSRF ok.
            +			$comment_data['comment_type'] = $this->get_comment_type();
            +		}
            +
            +		return $comment_data;
            +	}
            +
            +	public function remove_meta_boxes() {
            +		// remove_meta_box( 'commentstatusdiv', $this->cpt_support, 'normal' );
            +		remove_meta_box( 'commentsdiv', $this->cpt_support, 'normal' );
            +	}
            +
            +	public function trash_feature( $id ) {
            +		if ( ! $id ) {
            +			return;
            +		}
            +
            +		$post_type = get_post_type( $id );
            +
            +		if ( $post_type !== $this->cpt_feature ) {
            +			return;
            +		}
            +
            +		$this->clean_and_recal();
            +	}
            +
            +	public function clear_meta( $id ) {
            +		if ( ! current_user_can( 'delete_posts' ) || ! $id ) {
            +			return;
            +		}
            +
            +		$post_type = get_post_type( $id );
            +
            +		if ( $post_type !== $this->cpt_feature ) {
            +			return;
            +		}
            +
            +		global $wpdb;
            +		$feature = get_post( $id );
            +		if ( ! $feature ) {
            +			return;
            +		}
            +
            +		$meta_key = $this->cpt_feature . '_' . str_replace( '__trashed', '', $feature->post_name );
            +		if ( $meta_key && ( 0 !== $meta_key ) ) {
            +			$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->commentmeta} WHERE meta_key = %s;", $meta_key ) );
            +		}
            +
            +		$this->clean_and_recal();
            +	}
            +
            +	protected function clean_and_recal() {
            +		$posts = get_posts( [
            +			'post_type'      => $this->cpt_support,
            +			'posts_per_page' => -1,
            +			'post_status'    => 'any',
            +		] );
            +
            +		foreach ( $posts as $post ) {
            +			$this->clear_transients( $post->ID );
            +		}
            +	}
            +}
            diff --git a/inc/rating/class-opalestate-rating-metabox.php b/inc/rating/class-opalestate-rating-metabox.php
            new file mode 100755
            index 00000000..d751528e
            --- /dev/null
            +++ b/inc/rating/class-opalestate-rating-metabox.php
            @@ -0,0 +1,175 @@
            +
            + * @copyright  Copyright (C) 2019 wpopal.com. All Rights Reserved.
            + * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
            + *
            + * @website  http://www.wpopal.com
            + * @support  http://www.wpopal.com/support/forum.html
            + */
            +
            +if ( ! defined( 'ABSPATH' ) ) {
            +	exit; // Exit if accessed directly
            +}
            +
            +/**
            + * Class Opalestate_Rating_MetaBox
            + */
            +class Opalestate_Rating_MetaBox {
            +
            +	public function register_admin_comment_fields() {
            +		$rating_supports = Opalestate_Rating::get_rating_supports();
            +
            +		foreach ( $rating_supports as $key => $support ) {
            +			$this->register_comment_metabox( $support['post_type'], $support['features_cpt'] );
            +		}
            +	}
            +
            +	public function register_admin_feature_fields() {
            +		$rating_supports = Opalestate_Rating::get_rating_supports();
            +
            +		foreach ( $rating_supports as $key => $support ) {
            +			$this->register_feature_metabox( $support['features_cpt'] );
            +		}
            +	}
            +
            +	/**
            +	 * Hook in and register a metabox for the admin comment edit page.
            +	 */
            +	public function register_comment_metabox( $cpt_support, $cpt_feature ) {
            +		if ( ! isset( $_GET['c'] ) ) {
            +			return;
            +		}
            +
            +		$comment_type = get_comment_type( sanitize_text_field( $_GET['c'] ) );
            +
            +		if ( $comment_type !== $this->get_comment_type( $cpt_support ) ) {
            +			return;
            +		}
            +
            +		$features = Opalestate_Rating_Helper::get_features( $cpt_feature );
            +
            +		$cmb = new_cmb2_box( [
            +			'id'           => $cpt_support . '_comment_meta',
            +			'title'        => $features ? esc_html__( 'Rating features', 'opalestate-pro' ) : esc_html__( 'Rating', 'opalestate-pro' ),
            +			'object_types' => [ 'comment' ],
            +		] );
            +
            +		if ( $features ) {
            +			foreach ( $features as $feature_slug => $feature_title ) {
            +				$id = $cpt_feature . '_' . $feature_slug;
            +
            +				$cmb->add_field( [
            +					'id'      => $id,
            +					'type'    => 'select',
            +					'name'    => $feature_title,
            +					'options' => [
            +						'1' => '1 ★',
            +						'2' => '2 ★★',
            +						'3' => '3 ★★★',
            +						'4' => '4 ★★★★',
            +						'5' => '5 ★★★★★',
            +					],
            +					// 'show_on_cb' => function ( $cmb ) {
            +					// 	return isset( $_GET['c'] );
            +					// },
            +				] );
            +			}
            +		} else {
            +			$cmb->add_field( [
            +				'id'      => 'opalestate_rating',
            +				'type'    => 'select',
            +				'options' => [
            +					'1' => '1 ★',
            +					'2' => '2 ★★',
            +					'3' => '3 ★★★',
            +					'4' => '4 ★★★★',
            +					'5' => '5 ★★★★★',
            +				],
            +				// 'show_on_cb' => function ( $cmb ) {
            +				// 	return isset( $_GET['c'] );
            +				// },
            +			] );
            +		}
            +	}
            +
            +	/**
            +	 * Hook in and register a metabox for the admin comment edit page.
            +	 */
            +	public function register_feature_metabox( $cpt_feature ) {
            +		$cmb = new_cmb2_box( [
            +			'id'           => $cpt_feature . '_meta',
            +			'title'        => esc_html__( 'Data', 'opalestate-pro' ),
            +			'object_types' => [ $cpt_feature ],
            +		] );
            +
            +		$cmb->add_field( [
            +			'name' => esc_html__( 'Description', 'opalestate-pro' ),
            +			'id'   => 'opalestate_feature_desc',
            +			'type' => 'textarea_small',
            +		] );
            +
            +		$cmb->add_field( [
            +			'name'       => esc_html__( 'Order', 'opalestate-pro' ),
            +			'desc'       => esc_html__( 'Set a priority to display', 'opalestate-pro' ),
            +			'id'         => 'opalestate_feature_order',
            +			'type'       => 'text_small',
            +			'attributes' => [
            +				'type' => 'number',
            +			],
            +			'default'    => 0,
            +		] );
            +	}
            +
            +	/**
            +	 * Save meta box data
            +	 *
            +	 * @param mixed $data Data to save.
            +	 * @return mixed
            +	 */
            +	public static function save( $data ) {
            +		if ( ! isset( $data['comment_post_ID'] ) || ! $data['comment_post_ID'] ) {
            +			return $data;
            +		}
            +
            +		$comment_post_ID = $data['comment_post_ID'];
            +		$cpt_support     = get_post_type( $comment_post_ID );
            +		$rating_supports = Opalestate_Rating::get_rating_supports();
            +
            +		if ( ! isset( $rating_supports[ $cpt_support ] ) || ! isset( $rating_supports[ $cpt_support ]['features_cpt'] ) ) {
            +			return $data;
            +		}
            +
            +		$cpt_feature = $rating_supports[ $cpt_support ]['features_cpt'];
            +		$comment_id  = $data['comment_ID'];
            +		$features    = Opalestate_Rating_Helper::get_features( $cpt_feature );
            +
            +		if ( $features ) {
            +			foreach ( $features as $feature_slug => $feature_title ) {
            +				$id = $cpt_feature . '_' . $feature_slug;
            +				if ( isset( $_POST[ $id ] ) && ( $_POST[ $id ] > 0 ) && ( $_POST[ $id ] <= 5 ) ) {
            +					update_comment_meta( $comment_id, $id, intval( wp_unslash( $_POST[ $id ] ) ) ); // WPCS: input var ok.
            +				}
            +			}
            +		} else {
            +			if ( isset( $_POST['opalestate_rating'] ) && ( $_POST['opalestate_rating'] > 0 ) && ( $_POST['opalestate_rating'] <= 5 ) ) {
            +				update_comment_meta( $comment_id, 'opalestate_rating', intval( wp_unslash( $_POST['opalestate_rating'] ) ) ); // WPCS: input var ok.
            +			}
            +		}
            +
            +		// Return regular value after updating.
            +		return $data;
            +	}
            +
            +	/**
            +	 * Gets comment type.
            +	 *
            +	 * @return string
            +	 */
            +	public function get_comment_type( $cpt_support ) {
            +		return str_replace( 'opalestate_', '', $cpt_support ) . '_review';
            +	}
            +}
            diff --git a/inc/rating/class-opalestate-rating.php b/inc/rating/class-opalestate-rating.php
            new file mode 100755
            index 00000000..4080d97b
            --- /dev/null
            +++ b/inc/rating/class-opalestate-rating.php
            @@ -0,0 +1,102 @@
            +includes();
            +		$this->process();
            +
            +		// Template loader.
            +		add_filter( 'comments_template', [ $this, 'comments_template_loader' ] );
            +
            +		// Add shortcode User property reviews.
            +		add_shortcode( 'opalestate_user_property_reviews', [ $this, 'property_reviews_template' ] );
            +		add_filter( 'opalestate_user_content_reviews_page', [ $this, 'property_reviews_template' ] );
            +	}
            +
            +	public function includes() {
            +		require_once 'class-opalestate-rating-features-posttype.php';
            +		require_once 'class-opalestate-rating-metabox.php';
            +		require_once 'class-opalestate-rating-helper.php';
            +		require_once 'class-opalestate-rating-init.php';
            +		require_once 'rating-functions.php';
            +		require_once 'rating-hook-functions.php';
            +	}
            +
            +	public static function get_rating_supports() {
            +		return [
            +			// Support property rating.
            +			'opalestate_property' => [
            +				'post_type'    => 'opalestate_property',
            +				'features_cpt' => 'opalestate_rating_ft',
            +				'prefix'       => OPALESTATE_PROPERTY_PREFIX,
            +			],
            +			// Support agency rating.
            +			'opalestate_agency'   => [
            +				'post_type'    => 'opalestate_agency',
            +				'features_cpt' => 'opalestate_agency_ft',
            +				'prefix'       => OPALESTATE_AGENCY_PREFIX,
            +			],
            +			// Support agent rating.
            +			'opalestate_agent'    => [
            +				'post_type'    => 'opalestate_agent',
            +				'features_cpt' => 'opalestate_agent_ft',
            +				'prefix'       => OPALESTATE_AGENT_PREFIX,
            +			],
            +		];
            +	}
            +
            +	public function process() {
            +		$rating_supports = static::get_rating_supports();
            +		foreach ( $rating_supports as $key => $support ) {
            +			new Opalestate_Rating_Init( $support['post_type'], $support['features_cpt'], $support['prefix'] );
            +		}
            +	}
            +
            +	/**
            +	 * Load comments template.
            +	 *
            +	 * @param string $template template to load.
            +	 * @return string
            +	 */
            +	public function comments_template_loader( $template ) {
            +		$supports           = static::get_rating_supports();
            +		$post_type_supports = array_keys( $supports );
            +
            +		if ( ! in_array( get_post_type(), $post_type_supports ) ) {
            +			return $template;
            +		}
            +
            +		$check_dirs = [
            +			trailingslashit( get_stylesheet_directory() ) . 'opalestate/rating/',
            +			trailingslashit( get_template_directory() ) . 'opalestate/rating/',
            +			trailingslashit( get_stylesheet_directory() ),
            +			trailingslashit( get_template_directory() ),
            +			trailingslashit( OPALESTATE_PLUGIN_DIR ) . 'templates/rating/',
            +		];
            +
            +		foreach ( $check_dirs as $dir ) {
            +			$file = 'opalestate-ratings.php';
            +			if ( file_exists( trailingslashit( $dir ) . $file ) ) {
            +				return trailingslashit( $dir ) . $file;
            +			}
            +		}
            +	}
            +
            +	public function property_reviews_template() {
            +		if ( ! is_user_logged_in() || ! $current_user_id = get_current_user_id() ) {
            +			return '';
            +		}
            +
            +		$args = [
            +			'post_author__in' => [ $current_user_id ],
            +			'status'          => 'approve',
            +			'type'            => 'property_review',
            +		];
            +
            +		$comments = get_comments( $args );
            +
            +		return opalestate_load_template_path( 'user/property-ratings', [ 'comments' => $comments ] );
            +	}
            +}
            +
            +new Opalestate_Rating();
            diff --git a/inc/rating/rating-functions.php b/inc/rating/rating-functions.php
            new file mode 100755
            index 00000000..65210173
            --- /dev/null
            +++ b/inc/rating/rating-functions.php
            @@ -0,0 +1,107 @@
            + $comment,
            +				'args'    => $args,
            +				'depth'   => $depth,
            +			]
            +		);
            +	}
            +}
            +
            +if ( ! function_exists( 'opalestate_review_display_gravatar' ) ) {
            +	/**
            +	 * Display the review authors gravatar
            +	 *
            +	 * @param array $comment WP_Comment.
            +	 * @return void
            +	 */
            +	function opalestate_review_display_gravatar( $comment ) {
            +		echo get_avatar( $comment, apply_filters( 'opalestate_review_gravatar_size', '60' ), '' );
            +	}
            +}
            +
            +if ( ! function_exists( 'opalestate_review_display_rating' ) ) {
            +	/**
            +	 * Display the reviewers star rating
            +	 *
            +	 * @return void
            +	 */
            +	function opalestate_review_display_rating() {
            +		echo opalestate_load_template_path( 'rating/review-rating' );
            +	}
            +}
            +
            +if ( ! function_exists( 'opalestate_review_display_meta' ) ) {
            +	/**
            +	 * Display the review authors meta (name, verified owner, review date)
            +	 *
            +	 * @return void
            +	 */
            +	function opalestate_review_display_meta() {
            +		echo opalestate_load_template_path( 'rating/review-meta' );
            +	}
            +}
            +
            +if ( ! function_exists( 'opalestate_review_display_comment_text' ) ) {
            +
            +	/**
            +	 * Display the review content.
            +	 */
            +	function opalestate_review_display_comment_text() {
            +		echo '
            '; + comment_text(); + echo '
            '; + } +} + +function opalestate_get_property_rating_features() { + return Opalestate_Rating_Helper::get_features( 'opalestate_rating_ft' ); +} + +function opalestate_get_agency_rating_features() { + return Opalestate_Rating_Helper::get_features( 'opalestate_agency_ft' ); +} + +function opalestate_get_agent_rating_features() { + return Opalestate_Rating_Helper::get_features( 'opalestate_agent_ft' ); +} diff --git a/inc/rating/rating-hook-functions.php b/inc/rating/rating-hook-functions.php new file mode 100755 index 00000000..8c396ca3 --- /dev/null +++ b/inc/rating/rating-hook-functions.php @@ -0,0 +1,13 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Property_MetaBox_Submission { + + /** + * Defines custom front end fields + * + * @access public + * @param array $metaboxes + * @return array + */ + public function register_form( array $metaboxes ) { + + $prefix = OPALESTATE_PROPERTY_PREFIX; + + $fields = array_merge( + $this->metaboxes_general_fields_front(), + + $this->is_enabled_tab( 'media' ) ? $this->metaboxes_media_fields() : [], + $this->is_enabled_tab( 'location' ) ? $this->metaboxes_location_fields() : [], + $this->is_enabled_tab( 'information' ) ? $this->metaboxes_info_fields() : [], + $this->is_enabled_tab( 'amenities' ) ? $this->metaboxes_amenities_fields() : [], + $this->is_enabled_tab( 'facilities' ) ? $this->metaboxes_public_facilities_fields() : [], + $this->is_enabled_tab( 'apartments' ) ? $this->metaboxes_public_apartments_fields() : [], + $this->is_enabled_tab( 'floor_plans' ) ? $this->metaboxes_public_floor_plans_fields() : [] + ); + + $metaboxes[ $prefix . 'front' ] = [ + 'id' => $prefix . 'front', + 'title' => esc_html__( 'Name and Description', 'opalestate-pro' ), + 'object_types' => [ 'opalestate_property' ], + 'context' => 'normal', + 'priority' => 'high', + 'save_fields' => false, + 'show_names' => true, + 'fields' => $fields, + 'cmb_styles' => false, + + ]; + + return $metaboxes; + } + + public function get_fields_groups() { + return [ + 'general' => [ 'status' => true, 'title' => esc_html__( 'General', 'opalestate-pro' ) ], + + 'media' => [ 'status' => $this->is_enabled_tab( 'media' ), 'title' => esc_html__( 'Media', 'opalestate-pro' ) ], + 'location' => [ 'status' => $this->is_enabled_tab( 'location' ), 'title' => esc_html__( 'Location', 'opalestate-pro' ) ], + 'information' => [ 'status' => $this->is_enabled_tab( 'information' ), 'title' => esc_html__( 'Information', 'opalestate-pro' ) ], + 'amenities' => [ 'status' => $this->is_enabled_tab( 'amenities' ), 'title' => esc_html__( 'Amenities', 'opalestate-pro' ) ], + 'facilities' => [ 'status' => $this->is_enabled_tab( 'facilities' ), 'title' => esc_html__( 'Facilities', 'opalestate-pro' ) ], + 'apartments' => [ 'status' => $this->is_enabled_tab( 'apartments' ), 'title' => esc_html__( 'Apartments', 'opalestate-pro' ) ], + 'floor_plans' => [ 'status' => $this->is_enabled_tab( 'floor_plans' ), 'title' => esc_html__( 'Floor plans', 'opalestate-pro' ) ] + ]; + } + + public function metaboxes_general_fields_front() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + + $post_id = ''; + if ( ! empty( $_GET['id'] ) ) { + $post = get_post( intval( $_GET['id'] ) ); + $featured_image = wp_get_attachment_image_src( get_post_thumbnail_id( absint( $_GET['id'] ) ) ); + $post_id = $post->ID; + } + + $currency = opalestate_currency_symbol() ? ' (' . opalestate_currency_symbol() . ')' : ' ($)'; + + $fields = [ + [ + 'id' => 'post_type', + 'type' => 'hidden', + 'default' => 'opalestate_property', + + ], + [ + 'id' => 'post_id', + 'type' => 'hidden', + 'default' => $post_id, + + ], + + [ + 'name' => esc_html__( 'Title', 'opalestate-pro' ) . ' *', + 'id' => $prefix . 'title', + 'type' => 'text', + 'default' => ! empty( $post ) ? $post->post_title : '', + 'before_row' => '
            ', + 'attributes' => [ + 'required' => 'required', + ], + ], + [ + 'name' => esc_html__( 'Description', 'opalestate-pro' ), + 'id' => $prefix . 'text', + 'type' => 'wysiwyg', + 'default' => ! empty( $post ) ? $post->post_content : '', + 'before_row' => '
            ', + ], + + [ + 'id' => $prefix . 'price', + 'name' => esc_html__( 'Regular Price', 'opalestate-pro' ) . $currency . ' *', + 'type' => 'text', + 'description' => esc_html__( 'Enter amount without currency', 'opalestate-pro' ), + 'attributes' => opalestate_get_option( 'require_input_price' ) ? [ 'required' => 'required' ] : '', + 'before_row' => '
            ', // callback + ], + [ + 'id' => $prefix . 'saleprice', + 'name' => esc_html__( 'Sale Price', 'opalestate-pro' ) . $currency, + 'type' => 'text', + 'description' => esc_html__( 'Enter amount without currency', 'opalestate-pro' ), + ], + [ + 'id' => $prefix . 'before_pricelabel', + 'name' => esc_html__( 'Before Price Label (optional)', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'Before Price Label (e.g. "from")', 'opalestate-pro' ), + ], + [ + 'id' => $prefix . 'pricelabel', + 'name' => esc_html__( 'After Price Label (optional)', 'opalestate-pro' ), + 'type' => 'text', + 'description' => esc_html__( 'After Price Label (e.g. "per month")', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Statuses', 'opalestate-pro' ), + 'id' => $prefix . 'status', + 'type' => 'taxonomy_select', + 'taxonomy' => 'opalestate_status', + 'class' => 'form-control', + 'attributes' => [ + 'required' => 'required', + ], + 'before_row' => '

            ', // callback + ], + [ + 'name' => esc_html__( 'Types', 'opalestate-pro' ), + 'id' => $prefix . 'type', + 'type' => 'taxonomy_select', + 'taxonomy' => 'opalestate_types', + 'class' => 'form-control', + 'attributes' => [ + 'required' => 'required', + ], + 'after_row' => '

            ', // callback + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_general', $fields ); + } + + public function metaboxes_media_fields() { + + $id = 0; + + if( isset($_GET['id']) ){ + $post_id = intval( $_GET['id'] ); + $id = get_post_thumbnail_id( $post_id ); + } + + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + + [ + 'id' => "{$prefix}featured_image", + 'name' => esc_html__( 'Featured Image', 'opalestate-pro' ), + 'type' => 'uploader', + 'single' => true, + 'value' => $id, + 'description' => esc_html__( 'Select one or more images to show as gallery', 'opalestate-pro' ), + 'before_row' => '
            ', + + ], + + [ + 'id' => "{$prefix}gallery", + 'name' => esc_html__( 'Images Gallery', 'opalestate-pro' ), + 'type' => 'uploader', + 'description' => esc_html__( 'Select one or more images to show as gallery', 'opalestate-pro' ), + + ], + + [ + 'id' => "{$prefix}video", + 'name' => esc_html__( 'Video', 'opalestate-pro' ), + 'type' => 'text_url', + 'before_row' => '
            ', + 'description' => esc_html__( 'Input for videos, audios from Youtube, Vimeo and all supported sites by WordPress. It has preview feature.', 'opalestate-pro' ), + ], + [ + 'id' => "{$prefix}virtual", + 'name' => esc_html__( '360° Virtual Tour', 'opalestate-pro' ), + 'type' => 'textarea_small', + 'description' => esc_html__( 'Input iframe to show 360° Virtual Tour.', 'opalestate-pro' ), + 'before_row' => '
            ' + ], + [ + 'id' => "{$prefix}attachments", + 'name' => esc_html__( 'Attachments', 'opalestate-pro' ), + 'type' => 'uploader', + 'before_row' => '
            ', + 'show_icon' => true, + 'accept' => 'application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'options' => [ + 'url' => true, // Hide the text input for the url + ], + 'description' => esc_html__( 'Select one or more files to allow download', 'opalestate-pro' ), + 'after_row' => '
            ', + ], + ]; + + return apply_filters( 'opalestate_postype_property_metaboxes_fields_price', $fields ); + } + + public function metaboxes_info_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + + $fields = [ + [ + 'name' => esc_html__( 'Built year', 'opalestate-pro' ), + 'id' => $prefix . 'builtyear', + 'type' => 'text_date', + 'description' => esc_html__( 'Enter built year', 'opalestate-pro' ), + + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Parking', 'opalestate-pro' ), + 'id' => $prefix . 'parking', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + ), + 'sanitization_cb' => 'absint', + 'escape_cb' => 'absint', + 'description' => esc_html__( 'Enter number of Parking', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Bedrooms', 'opalestate-pro' ), + 'id' => $prefix . 'bedrooms', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + ), + 'sanitization_cb' => 'absint', + 'escape_cb' => 'absint', + 'description' => esc_html__( 'Enter number of bedrooms', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Bathrooms', 'opalestate-pro' ), + 'id' => $prefix . 'bathrooms', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + ), + 'sanitization_cb' => 'absint', + 'escape_cb' => 'absint', + 'description' => esc_html__( 'Enter number of bathrooms', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Plot Size', 'opalestate-pro' ), + 'id' => $prefix . 'plotsize', + 'type' => 'text', + 'description' => esc_html__( 'Enter size of Plot as 20x30, 20x30x40, 20x30x40x50', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Area Size', 'opalestate-pro' ), + 'id' => $prefix . 'areasize', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + ), + 'sanitization_cb' => 'absint', + 'escape_cb' => 'absint', + 'description' => esc_html__( 'Enter size of area in sqft', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Orientation', 'opalestate-pro' ), + 'id' => "{$prefix}orientation", + 'type' => 'text', + 'description' => esc_html__( 'Enter Orientation of property', 'opalestate-pro' ), + ], + [ + 'name' => esc_html__( 'Living Rooms', 'opalestate-pro' ), + 'id' => "{$prefix}livingrooms", + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + ), + 'sanitization_cb' => 'absint', + 'escape_cb' => 'absint', + 'description' => esc_html__( 'Enter Number of Living Rooms', 'opalestate-pro' ), + ], + + [ + 'name' => esc_html__( 'Kitchens', 'opalestate-pro' ), + 'id' => "{$prefix}kitchens", + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + ), + 'sanitization_cb' => 'absint', + 'escape_cb' => 'absint', + 'description' => esc_html__( 'Enter Number of Kitchens', 'opalestate-pro' ), + ], + + [ + 'name' => esc_html__( 'Rooms', 'opalestate-pro' ), + 'id' => "{$prefix}amountrooms", + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + ), + 'sanitization_cb' => 'absint', + 'escape_cb' => 'absint', + 'description' => esc_html__( 'Enter Number of Amount Rooms', 'opalestate-pro' ), + 'after_row' => '

            ', + + ], + ]; + + return apply_filters( 'opalestate_metaboxes_public_info_fields', $fields ); + } + + public function metaboxes_location_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $management = [ + [ + 'name' => esc_html__( 'Country', 'opalestate-pro' ), + 'id' => $prefix . 'location', + 'type' => 'taxonomy_select', + 'taxonomy' => 'opalestate_location', + 'before_row' => '
            ', + ], + [ + 'name' => esc_html__( 'States / Province', 'opalestate-pro' ), + 'id' => $prefix . 'state', + 'type' => 'taxonomy_select', + 'taxonomy' => 'opalestate_state', + ], + [ + 'name' => esc_html__( 'City / Town', 'opalestate-pro' ), + 'id' => $prefix . 'city', + 'type' => 'taxonomy_select', + 'taxonomy' => 'opalestate_city', + ], + [ + 'name' => esc_html__( 'Postal Code / Zip', 'opalestate-pro' ), + 'id' => $prefix . 'zipcode', + 'type' => 'text', + 'after_row'=> '

            ' + + ], + [ + 'name' => esc_html__( 'Address', 'opalestate-pro' ) . ' *', + 'id' => $prefix . 'address', + 'type' => 'text', + 'attributes' => [ + 'required' => 'required', + ], + ], + [ + 'name' => esc_html__( 'Google Map View', 'opalestate-pro' ), + 'id' => $prefix . 'enablemapview', + 'type' => 'switch', + 'options' => [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + ], + 'description' => esc_html__( 'Enable Google Map', 'opalestate-pro' ), + ], + [ + 'id' => $prefix . 'map', + 'name' => esc_html__( 'Google Map', 'opalestate-pro' ), + 'type' => 'opal_map', + 'sanitization_cb' => 'opal_map_sanitise', + 'split_values' => true, + 'after_row' => '
            ', + ], + ]; + + return $management; + } + + public function metaboxes_amenities_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'name' => esc_html__( 'Amenities', 'opalestate-pro' ), + 'id' => $prefix . 'amenity', + 'type' => 'taxonomy_multicheck', + 'before_row' => '
            ', + 'after_row' => '
            ', + 'taxonomy' => 'opalestate_amenities', + 'render_row_cb' => [ $this, 'amenities_html_callback' ], + ], + ]; + + return apply_filters( 'opalestate_metaboxes_amenities_fields', $fields ); + } + + public function metaboxes_public_facilities_fields() { + + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'id' => $prefix . 'public_facilities_group', + 'type' => 'group', + 'before_group' => '
            ', + 'after_group' => '
            ', + 'fields' => [ + [ + 'id' => $prefix . 'public_facilities_key', + 'name' => esc_html__( 'Label', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'public_facilities_value', + 'name' => esc_html__( 'Content', 'opalestate-pro' ), + 'type' => 'text', + ], + ], + 'options' => [ + 'group_title' => esc_html__( 'Facility {#}', 'opalestate-pro' ), + 'add_button' => esc_html__( 'Add more', 'opalestate-pro' ), + 'remove_button' => esc_html__( 'Remove', 'opalestate-pro' ), + 'sortable' => true, + 'closed' => true, + ], + ], + ]; + + return apply_filters( 'opalestate_metaboxes_public_facilities_fields', $fields ); + } + + public function metaboxes_public_apartments_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'name' => esc_html__( 'Apartments', 'opalestate-pro' ), + 'id' => $prefix . 'enable_apartments', + 'type' => 'heading', + 'options' => [ + 0 => esc_html__( 'No', 'opalestate-pro' ), + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + ], + 'before_row' => '
            ', + ], + [ + 'id' => $prefix . 'apartments', + 'type' => 'group', + 'after_group' => '
            ', + 'fields' => [ + [ + 'id' => $prefix . 'apartment_plot', + 'name' => esc_html__( 'Plot', 'opalestate-pro' ), + 'before_row' => '
            ', + 'type' => 'text', + + ], + + [ + 'id' => $prefix . 'apartment_beds', + 'name' => esc_html__( 'Beds', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'apartment_price_from', + 'name' => esc_html__( 'Price from', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'apartment_floor', + 'name' => esc_html__( 'Floor', 'opalestate-pro' ), + 'type' => 'text', + 'after_row' => '
            ', + ], + [ + 'id' => $prefix . 'apartment_building_address', + 'name' => esc_html__( 'Building / Address', 'opalestate-pro' ), + 'type' => 'textarea_small', + ], + [ + 'id' => $prefix . 'apartment_status', + 'name' => esc_html__( 'Status', 'opalestate-pro' ), + 'type' => 'select', + 'options' => apply_filters( 'opalestate_property_apartment_statuses', [ + 'available' => esc_html__( 'Available', 'opalestate-pro' ), + 'unavailable' => esc_html__( 'Unavailable', 'opalestate-pro' ), + ] ), + 'before_row' => '
            ', + ], + [ + 'id' => $prefix . 'apartment_link', + 'name' => esc_html__( 'Link', 'opalestate-pro' ), + 'type' => 'text', + 'default' => '#', + 'after_row' => '
            ', + ], + ], + 'options' => [ + 'group_title' => esc_html__( 'Apartment {#}', 'opalestate-pro' ), + 'add_button' => esc_html__( 'Add more', 'opalestate-pro' ), + 'remove_button' => esc_html__( 'Remove', 'opalestate-pro' ), + 'sortable' => true, + 'closed' => true, + ], + ], + ]; + + return apply_filters( 'opalestate_metaboxes_public_apartments_fields', $fields ); + } + + public function metaboxes_public_floor_plans_fields() { + $prefix = OPALESTATE_PROPERTY_PREFIX; + $fields = [ + [ + 'name' => esc_html__( 'Floor Plans', 'opalestate-pro' ), + 'id' => $prefix . 'enable_floor', + 'type' => 'heading', + 'before_row' => '
            ', + ], + [ + 'id' => $prefix . 'public_floor_group', + 'type' => 'group', + 'after_group' => '
            ', + 'fields' => [ + [ + 'id' => $prefix . 'floor_name', + 'name' => esc_html__( 'Name', 'opalestate-pro' ), + 'type' => 'text', + + ], + [ + 'id' => $prefix . 'floor_price', + 'name' => esc_html__( 'Price', 'opalestate-pro' ), + 'before_row' => '
            ', + 'type' => 'text', + ], + [ + 'id' => $prefix . 'floor_size', + 'name' => esc_html__( 'Size', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'floor_room', + 'name' => esc_html__( 'Rooms', 'opalestate-pro' ), + 'type' => 'text', + ], + [ + 'id' => $prefix . 'floor_bath', + 'name' => esc_html__( 'Baths', 'opalestate-pro' ), + 'type' => 'text', + 'after_row' => '
            ', + ], + [ + 'id' => $prefix . 'floor_content', + 'name' => esc_html__( 'Content', 'opalestate-pro' ), + 'type' => 'textarea_small', + ], + [ + 'id' => "{$prefix}floor_image_id", + 'name' => esc_html__( 'Image Preview', 'opalestate-pro' ), + 'type' => 'uploader', + 'single' => 1, + + 'query_args' => [ + 'type' => [ + 'image/gif', + 'image/jpeg', + 'image/png', + ], + ], + 'description' => esc_html__( 'Input iframe to show 360° Virtual Tour.', 'opalestate-pro' ), + ], + ], + 'options' => [ + 'group_title' => esc_html__( 'Floor {#}', 'opalestate-pro' ), + 'add_button' => esc_html__( 'Add more', 'opalestate-pro' ), + 'remove_button' => esc_html__( 'Remove', 'opalestate-pro' ), + 'sortable' => true, + 'closed' => false, + ], + ], + ]; + + return apply_filters( 'opalestate_metaboxes_public_floor_plans_fields', $fields ); + } + + protected function is_enabled_tab( $tab ) { + return ( 'on' === opalestate_get_option( 'enable_submission_tab_' . $tab, true ) ); + } + + /** + * Manually render a field column display. + * + * @param array $field_args Array of field arguments. + * @param CMB2_Field $field The field object + */ + public function amenities_html_callback( $field_args, $field ) { + $id = $field->args( 'id' ); + $label = $field->args( 'name' ); + $name = $field->args( '_name' ); + $value = $field->escaped_value(); + $description = $field->args( 'description' ); + + $amenites = get_terms( [ + 'taxonomy' => 'opalestate_amenities', + 'orderby' => 'name', + 'order' => 'ASC', + 'hide_empty' => false, + ] ); + + if ( ! $amenites ) { + return; + } + ?> +
            +
            +
            + +
            + +
            +
              + $amenity ) : ?> +
            • + + +
            • + +
            +
            +
            + + +
            + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +if ( ! session_id() ) { + @session_start(); +} + +/** + * @class OpalEstate_Submission + * + * @version 1.0 + */ +class OpalEstate_Submission { + + /** + * + * + */ + public $metabox; + + /** + * + * + */ + public $new_attachmenet_ids = array(); + + /** + * Constructor + */ + public function __construct() { + + /** + * Can not use $this->is_submission_page() || use 'wp_enqueue_scripts' here + * because inside this hook global $post == null + */ + add_action( 'wp_head', [ $this, 'head_check_page' ] ); + + add_action( 'cmb2_after_init', [ $this, 'process_submission' ], 10000 ); + + add_action( 'opalestate_single_property_before', [ $this, 'render_button_edit' ] ); + + if ( is_admin() ) { + add_filter( 'opalestate_settings_tabs', [ $this, 'setting_content_tab' ] ); + add_filter( 'opalestate_registered_submission_page_settings', [ $this, 'setting_content_fields' ] ); + } + + add_action( 'opalestate_user_content_submission_list_page', [ $this, 'submission_list' ] ); + add_action( 'opalestate_user_content_submission_page', [ $this, 'submission' ] ); + add_action( 'wp_enqueue_scripts', [ $this, 'scripts_styles' ], 99 ); + + $this->register_shortcodes(); + } + + /** + * Save post. + */ + public function scripts_styles() { + + wp_register_style( 'opalesate-submission', OPALESTATE_PLUGIN_URL . 'assets/submission.css' ); + wp_register_style( 'opalesate-cmb2-front', OPALESTATE_PLUGIN_URL . 'assets/cmb2-front.css' ); + wp_register_script( + 'opalestate-submission', + OPALESTATE_PLUGIN_URL . 'assets/js/frontend/submission.js', + [ + 'jquery', + ], + '1.0', + true + ); + } + + /* + * Is submission page. 'submission_page' option in General Setting + */ + public function register_shortcodes() { + $shortcodes = [ + 'submission' => [ + 'code' => 'submission', + 'label' => esc_html__( 'Submission Form', 'opalestate-pro' ), + ], + 'submission_list' => [ + 'code' => 'submission_list', + 'label' => esc_html__( 'My Properties', 'opalestate-pro' ), + ] + ]; + + foreach ( $shortcodes as $shortcode ) { + add_shortcode( 'opalestate_' . $shortcode['code'], [ $this, $shortcode['code'] ] ); + } + } + + /* + * Is submission page. 'submission_page' option in General Setting + */ + public function setting_content_tab( $tabs ) { + $tabs['submission_page'] = esc_html__( 'Submission Page', 'opalestate-pro' ); + + return $tabs; + } + + /* + * Is submission page. 'submission_page' option in General Setting + */ + public function setting_content_fields( $fields = [] ) { + $fields = [ + 'id' => 'submission_page', + 'title' => esc_html__( 'Email Settings', 'opalestate-pro' ), + 'show_on' => [ 'key' => 'options-page', 'value' => [ 'opalestate_settings' ], ], + 'fields' => apply_filters( 'opalestate_settings_submission', [ + [ + 'name' => esc_html__( 'Submission Page Settings', 'opalestate-pro' ), + 'id' => 'opalestate_title_submission_page_settings', + 'type' => 'title', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Property Submission Page', 'opalestate-pro' ), + 'desc' => esc_html__( 'This is the submission page. The [opalestate_submission] shortcode should be on this page.', 'opalestate-pro' ), + 'id' => 'submission_page', + 'type' => 'select', + 'options' => opalestate_cmb2_get_post_options( [ + 'post_type' => 'page', + 'numberposts' => -1, + ] ), + ], + + [ + 'name' => esc_html__( 'Show Content Use Not Login', 'opalestate-pro' ), + 'desc' => esc_html__( 'Show Login/Register form and submission form if user not logined', 'opalestate-pro' ), + 'id' => 'submission_show_content', + 'type' => 'select', + 'default' => '', + 'options' => [ + '' => esc_html__( 'Show Login Form', 'opalestate-pro' ), + 'login_submission' => esc_html__( 'Show Login Form and Submission Form', 'opalestate-pro' ), + ], + ], + + [ + 'name' => esc_html__( 'Enable Admin Approve', 'opalestate-pro' ), + 'desc' => esc_html__( 'the Property will be auto approve when user submit, if you do not enable it.', 'opalestate-pro' ), + 'id' => 'admin_approve', + 'type' => 'checkbox', + ], + [ + 'name' => esc_html__( 'Enable Require Price', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable or Disable require user enter price and price label.', 'opalestate-pro' ), + 'id' => 'require_input_price', + 'type' => 'checkbox', + + ], + [ + 'name' => esc_html__( 'Submission Tab Settings', 'opalestate-pro' ), + 'id' => 'opalestate_title_submission_tab_settings', + 'type' => 'title', + 'before_row' => '
            ', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Enable Media tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Media tab', 'opalestate-pro' ), + 'id' => 'enable_submission_tab_media', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable Location tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Location tab', 'opalestate-pro' ), + 'id' => 'enable_submission_tab_location', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable Information tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Information tab', 'opalestate-pro' ), + 'id' => 'enable_submission_tab_information', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable Amenities tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Amenities tab', 'opalestate-pro' ), + 'id' => 'enable_submission_tab_amenities', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable Facilities tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Facilities tab', 'opalestate-pro' ), + 'id' => 'enable_submission_tab_facilities', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable Apartments tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Apartments tab', 'opalestate-pro' ), + 'id' => 'enable_submission_tab_apartments', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Enable Floor plans tab', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Floor plans tab', 'opalestate-pro' ), + 'id' => 'enable_submission_tab_floor_plans', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + ], + ] + ), + ]; + + return $fields; + } + + /* + * Is submission page. 'submission_page' option in General Setting + */ + public function head_check_page() { + + } + + /* + * Is submission page. 'submission_page' option in General Setting + */ + public function render_button_edit() { + + global $post, $current_user; + wp_get_current_user(); + + if ( $current_user->ID == $post->post_author ) { + echo ''; + } + } + + /* + * Is submission page. 'submission_page' option in General Setting + */ + public function is_submission_page() { + global $post; + if ( ! $post || ! isset( $post->ID ) || ! $post->ID ) { + return false; + } + + return opalestate_get_option( 'submission_page' ) == $post->ID; + } + + + /** + * + * + */ + public function register_metabox() { + + $metabox = new Opalestate_Property_MetaBox_Submission(); + + add_filter( 'cmb2_meta_boxes', [ $metabox, 'register_form' ], 9999 ); + + return $metabox; + } + + /** + * FrontEnd Submission + */ + public function submission() { + + global $current_user; + + if ( ! is_user_logged_in() ) { + echo opalestate_load_template_path( 'submission/require-login' ); + if( empty(opalestate_get_option("submission_show_content")) ){ + return ""; + } + } + + if( isset($_GET['do']) && $_GET['do'] == 'completed' ){ + + OpalEstate()->session->set( 'submission', 'addnew' ); + + echo opalestate_load_template_path( 'submission/completed' ); + return ; + } + + // remove all dirty images before edit/create new a property + $this->cleanup(); + + wp_enqueue_script( 'opalestate-submission' ); + wp_enqueue_style( 'opalesate-submission' ); + wp_enqueue_style( 'opalesate-cmb2-front' ); + + + $metabox = $this->register_metabox(); + $metaboxes = apply_filters( 'cmb2_meta_boxes', [] ); + + + if ( ! isset( $metaboxes[ OPALESTATE_PROPERTY_PREFIX . 'front' ] ) ) { + return esc_html__( 'A metabox with the specified \'metabox_id\' doesn\'t exist.', 'opalestate-pro' ); + } + $post_id = 0; + + if( is_user_logged_in() ) { + // CMB2 is getting fields values from current post what means it will fetch data from submission page + // We need to remove all data before. + $post_id = ! empty( $_GET['id'] ) ? absint( $_GET['id'] ) : false; + if ( ! $post_id ) { + unset( $_POST ); + foreach ( $metaboxes[ OPALESTATE_PROPERTY_PREFIX . 'front' ]['fields'] as $field_name => $field_value ) { + delete_post_meta( get_the_ID(), $field_value['id'] ); + } + } + + if ( ! empty( $post_id ) && ! empty( $_POST['object_id'] ) ) { + $post_id = absint( $_POST['object_id'] ); + + } + + if ( $post_id && ! opalestate_is_own_property( $post_id, $current_user->ID ) ) { + echo opalestate_load_template_path( 'parts/has-warning' ); + return ; + } + } + return opalestate_load_template_path( 'submission/submission-form', + [ + 'post_id' => $post_id, + 'metaboxes' => $metaboxes, + 'navigation' => $metabox->get_fields_groups(), + ] ); + } + + /** + * + * + */ + public function cmb2_get_metabox() { + $object_id = 'fake-oject-id'; + return cmb2_get_metabox( OPALESTATE_PROPERTY_PREFIX . 'front', $object_id ); + } + + /** + * FrontEnd Submission + */ + public function process_submission() { + + if ( isset( $_POST['submission_action'] ) && ! empty( $_POST['submission_action'] ) ) { + + if ( wp_verify_nonce( $_POST['submission_action'], 'submitted-property' ) ) { + + $user_id = get_current_user_id(); + $edit = false; + $prefix = OPALESTATE_PROPERTY_PREFIX; + $blocked = OpalEstate_User::is_blocked(); + + // Setup and sanitize data + if ( isset( $_POST[ $prefix . 'title' ] ) && ! $blocked && $user_id ) { + + $metabox = $this->register_metabox(); + $metaboxes = apply_filters( 'cmb2_meta_boxes', [] ); + + + + + $post_id = ! empty( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : false; + + if( $post_id ){ + do_action( 'opalestate_process_edit_submission_before' ); + } else { + do_action( 'opalestate_process_submission_before' ); + } + + + $review_before = opalestate_get_option( 'admin_approve' ); + + $post_status = 'pending'; + + if ( ! $review_before ) { + $post_status = 'publish'; + } + + // If we are updating the post get old one. We need old post to set proper + // post_date value because just modified post will at the top in archive pages. + if ( ! empty( $post_id ) ) { + $old_post = get_post( $post_id ); + $post_date = $old_post->post_date; + } else { + $post_date = ''; + } + + $post_content = isset( $_POST[ $prefix . 'text' ] ) ? wp_kses( $_POST[ $prefix . 'text' ], + '

            ' ) : ''; + + + $data = [ + 'post_title' => sanitize_text_field( $_POST[ $prefix . 'title' ] ), + 'post_author' => $user_id, + 'post_status' => $post_status, + 'post_type' => 'opalestate_property', + 'post_date' => $post_date, + 'post_content' => $post_content, + ]; + + $unset_fields = [ + 'text', + 'title', + 'post_type', + ]; + + unset( $_POST['post_type'] ); + + foreach ( $unset_fields as $field ) { + unset( $_POST[ $prefix . $field ] ); + } + + if ( ! empty( $post_id ) ) { + $edit = true; + $data['ID'] = $post_id; + + do_action( 'opalestate_process_edit_submission_before' ); + } else { + do_action( 'opalestate_process_add_submission_before' ); + } + + if ( empty( $data['post_title'] ) || empty( $data['post_author'] ) ) { + return opalestate_output_msg_json( false, + __( 'Please enter data for all require fields before submitting', 'opalestate-pro' ), + array( + 'heading' => esc_html__('Submission Information' ,'opalestate-pro') + )) ; + } + + $post_id = wp_insert_post( $data, true ); + + if ( ! empty( $post_id ) && ! empty( $_POST['object_id'] ) ) { + $_POST['object_id'] = (int) $post_id; + + $metaboxes = apply_filters( 'cmb2_meta_boxes', [] ); + + /* + * Processing upload files + */ + $this->process_upload_files( $post_id, $_POST ); + + /** + * Fetch sanitized values + */ + cmb2_get_metabox_form( $metaboxes[ $prefix. 'front' ], $post_id ); + $cmb = $this->cmb2_get_metabox(); + $sanitized_values = $cmb->get_sanitized_values( $_POST ); + $cmb->save_fields( $post_id, 'post', $sanitized_values ); + + // Create featured image + $featured_image = get_post_meta( $post_id, $prefix . 'featured_image', true ); + + if ( ! empty( $_POST[ $prefix . 'featured_image' ] ) && isset( $_POST[ $prefix . 'featured_image' ] ) ) { + foreach( $_POST[ $prefix . 'featured_image' ] as $key => $value ) { + set_post_thumbnail( $post_id, $key ); + } + unset( $_POST[ $prefix . 'featured_image' ] ); + } else { + delete_post_thumbnail( $post_id ); + } + + // remove meta field; + update_post_meta( $post_id, $prefix . 'featured_image', null ); + //redirect + $_SESSION['messages'][] = [ 'success', esc_html__( 'Property has been successfully updated.', 'opalestate-pro' ) ]; + + do_action( "opalestate_process_submission_after", $user_id, $post_id, $edit ); + + if ( $edit ) { + $type = OpalEstate()->session->set( 'submission' , 'edit' ); + $message = esc_html__('The property has updated completed with new information', 'opalestate-pro' ); + do_action( "opalestate_processed_edit_submission", $user_id, $post_id ); + } else { + $type = OpalEstate()->session->get( 'submission' , 'addnew' ); + $message = esc_html__('You have submitted the property successful', 'opalestate-pro' ); + do_action( "opalestate_processed_new_submission", $user_id, $post_id ); + } + + // set ready of attachment for use. + if( $this->new_attachmenet_ids ){ + foreach ( $this->new_attachmenet_ids as $_id ) { + delete_post_meta( $_id, '_pending_to_use_', 1 ); + } + } + + // + + return opalestate_output_msg_json( true, + $message, + array( + 'heading' => esc_html__('Submission Information' ,'opalestate-pro'), + 'redirect' => opalestate_submssion_page( $post_id, array('do' => 'completed') ) + )) ; + } + } else { + return opalestate_output_msg_json( fales, + __('Currently, your account was blocked, please keep contact admin to resolve this!.', 'opalestate-pro' ), + array('heading' => esc_html__('Submission Information' ,'opalestate-pro') ) + ) ; + } + } + + return opalestate_output_msg_json( fales, + __('Sorry! Your submitted datcould not save a at this time', 'opalestate-pro' ), + array('heading' => esc_html__('Submission Information', 'opalestate-pro') ) + ) ; + } + } + + /** + * + * + */ + private function get_field_name( $field ){ + return OPALESTATE_PROPERTY_PREFIX.$field; + } + + /** + * + * + */ + private function process_upload_files ( $post_id ) { + + //upload images for featured and gallery images + if( isset($_FILES) && !empty($_FILES) ){ + + /// + $fields = array( + $this->get_field_name('gallery'), + $this->get_field_name('featured_image'), + ); + + foreach( $_FILES as $key => $value ) { + // allow processing in fixed collection + if( in_array($key, $fields) ){ + $ufile = $_FILES[$key]; + + /// ///// + if( isset( $ufile['name'] ) && is_array( $ufile['name'] ) ){ + $output = array(); + + foreach ( $ufile['name'] as $f_key => $f_value ) { + $loop_file = array( + 'name' => $ufile['name'][$f_key], + 'type' => $ufile['type'][$f_key], + 'tmp_name' => $ufile['tmp_name'][$f_key], + 'error' => $ufile['error'][$f_key], + 'size' => $ufile['size'][$f_key] + ); + $new_atm = $this->upload_image( $loop_file, $post_id ); + if( $new_atm ){ + $_POST[$key] = isset($_POST[$key]) ? $_POST[$key] : array(); + $_POST[$key][$new_atm['attachment_id']] = $new_atm['url']; + $this->new_attachmenet_ids[$new_atm['attachment_id']] = $new_atm['attachment_id']; + } + } + + } + /// + elseif( isset($ufile['name']) ) { + $new_atm = $this->upload_image( $ufile, $post_id ); + if( $new_atm ){ + $_POST[$key][$new_atm['attachment_id']] = $new_atm['url']; + $this->new_attachmenet_ids[$new_atm['attachment_id']] = $new_atm['attachment_id']; + } + } + //// / // + } + } + + // for group files + $fields = array( + $this->get_field_name('public_floor_group') + ); + + + foreach( $_FILES as $key => $value ) { + + if( in_array($key, $fields) ){ + $ufile = $_FILES[$key]; + + if( isset( $ufile['name'] ) && is_array( $ufile['name'] ) ){ + $output = array(); + foreach ( $ufile['name'] as $f_key => $f_value ) { + + foreach( $f_value as $u_key => $u_v ) { + $loop_file = array( + 'name' => $ufile['name'][$f_key][$u_key], + 'type' => $ufile['type'][$f_key][$u_key], + 'tmp_name' => $ufile['tmp_name'][$f_key][$u_key], + 'error' => $ufile['error'][$f_key][$u_key], + 'size' => $ufile['size'][$f_key][$u_key] + ); + + $new_atm = $this->upload_image( $loop_file, $post_id ); + if( $new_atm ){ + + $_POST[$key][$f_key][$u_key] = $new_atm['attachment_id']; + $this->new_attachmenet_ids[$new_atm['attachment_id']] = $new_atm['attachment_id']; + } + } + } + } + } + } + } + } + + + /** + * Process upload images for properties + */ + public function upload_image( $submitted_file, $parent_id=0 ){ + return opalesate_upload_image( $submitted_file, $parent_id ); + } + + /** + * FrontEnd Submission + */ + private function cleanup() { + $user_id = get_current_user_id(); + opalestate_clean_attachments( $user_id ); + } + + /** + * FrontEnd Submission + */ + public function submission_list() { + if ( ! is_user_logged_in() ) { + echo opalestate_load_template_path( 'parts/not-allowed' ); + + return; + } + + if ( isset( $_GET['id'] ) && isset( $_GET['remove'] ) ) { + $is_allowed = Opalestate_Property::is_allowed_remove( get_current_user_id(), intval( $_GET['id'] ) ); + if ( ! $is_allowed ) { + echo opalestate_load_template_path( 'parts/not-allowed' ); + + return; + } + + if ( wp_delete_post( intval( $_GET['id'] ) ) ) { + $_SESSION['messages'][] = [ 'success', esc_html__( 'Property has been successfully removed.', 'opalestate-pro' ) ]; + } else { + $_SESSION['messages'][] = [ 'danger', esc_html__( 'An error occured when removing an item.', 'opalestate-pro' ) ]; + } + + wp_redirect( opalestate_submssion_list_page() ); + } + + + $args = []; + + if ( isset( $_GET['status'] ) && ! empty( $_GET['status'] ) ) { + $args['post_status'] = sanitize_text_field( $_GET['status'] ); + } + + $loop = Opalestate_Query::get_properties_by_user( $args, get_current_user_id() ); + + return opalestate_load_template_path( 'user/my-properties', [ 'loop' => $loop ] ); + } +} + +new OpalEstate_Submission(); diff --git a/inc/submission/function.php b/inc/submission/function.php new file mode 100755 index 00000000..e89f248d --- /dev/null +++ b/inc/submission/function.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/inc/taxonomies/class-taxomony-amenities.php b/inc/taxonomies/class-taxomony-amenities.php new file mode 100755 index 00000000..4ad2c70f --- /dev/null +++ b/inc/taxonomies/class-taxomony-amenities.php @@ -0,0 +1,93 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_Amenities { + + /** + * Opalestate_Taxonomy_Amenities constructor. + */ + public function __construct() { + add_action( 'init', [ $this, 'definition' ] ); + add_action( 'cmb2_admin_init', [ $this, 'taxonomy_metaboxes' ], 999 ); + } + + /** + * + */ + public function definition() { + + $labels = [ + 'name' => esc_html__( 'Amenities', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By Amenity', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Amenities', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Amenities', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Amenity', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Amenity:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Amenity', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Amenity', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Amenity', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Amenity', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Amenities', 'opalestate-pro' ), + ]; + + register_taxonomy( 'opalestate_amenities', 'opalestate_property', [ + 'labels' => apply_filters( 'opalestate_taxomony_amenities_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'amenity', + 'rewrite' => [ 'slug' => _x( 'amenity', 'slug', 'opalestate-pro' ), 'with_front' => false, 'hierarchical' => true ], + 'public' => true, + 'show_ui' => true, + ] ); + } + + public static function get_list() { + return get_terms( 'opalestate_amenities', [ 'hide_empty' => false ] ); + } + + public function taxonomy_metaboxes() { + $prefix = 'opalestate_amt_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'Type Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'opalestate_amenities' ], // Tells CMB2 which taxonomies should have these fields + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Image Icon', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select an image icon (SVG, PNG or JPEG).', 'opalestate-pro' ), + 'id' => $prefix . 'image', + 'type' => 'file', + 'preview_size' => [ 50, 50 ], + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + 'query_args' => [ + 'type' => [ + 'image/gif', + 'image/jpeg', + 'image/png', + ], + ], + ] ); + } +} + +new Opalestate_Taxonomy_Amenities(); diff --git a/inc/taxonomies/class-taxonomy-categories.php b/inc/taxonomies/class-taxonomy-categories.php new file mode 100755 index 00000000..8669975a --- /dev/null +++ b/inc/taxonomies/class-taxonomy-categories.php @@ -0,0 +1,116 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_Categories { + + /** + * + */ + public static function init() { + + add_action( 'init', [ __CLASS__, 'definition' ] ); + add_filter( 'opalestate_taxomony_category_metaboxes', [ __CLASS__, 'metaboxes' ] ); + + add_action( 'cmb2_admin_init', [ __CLASS__, 'taxonomy_metaboxes' ], 999 ); + + } + + public static function metaboxes() { + + } + + + /** + * + */ + public static function definition() { + + register_taxonomy( 'property_category', 'opalestate_property', apply_filters( 'opalestate_taxonomy_args_property_category', [ + 'labels' => [ + 'name' => esc_html__( 'Categories', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Category', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Category', 'opalestate-pro' ), + ], + 'public' => true, + 'hierarchical' => true, + 'show_ui' => true, + 'query_var' => true, + 'rewrite' => [ 'slug' => _x( 'property-category', 'slug', 'opalestate-pro' ), 'with_front' => false, 'hierarchical' => true ], + ] ) ); + } + + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public static function taxonomy_metaboxes() { + + $prefix = 'opalestate_category_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'Category Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'property_category' ], // Tells CMB2 which taxonomies should have these fields + // 'new_term_section' => true, // Will display in the "Add New Category" section + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Image', 'opalestate-pro' ), + 'desc' => esc_html__( 'Category image', 'opalestate-pro' ), + 'id' => $prefix . 'image', + 'type' => 'file', + ] ); + } + + public static function get_list( $args = [] ) { + $default = [ + 'taxonomy' => 'property_category', + 'hide_empty' => true, + ]; + + if ( $args ) { + $default = array_merge( $default, $args ); + } + + return get_terms( $default ); + } + + public static function dropdown_list( $selected = 0 ) { + $id = "opalestate_category" . rand(); + + $args = [ + 'show_option_none' => esc_html__( 'Select category', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'show_count' => 0, + 'hierarchical' => '', + 'name' => 'label', + 'value_field' => 'slug', + 'selected' => $selected, + 'taxonomy' => 'opalestate_category', + ]; + + return wp_dropdown_categories( $args ); + } + +} + +Opalestate_Taxonomy_Categories::init(); diff --git a/inc/taxonomies/class-taxonomy-city.php b/inc/taxonomies/class-taxonomy-city.php new file mode 100755 index 00000000..4c9cc8d6 --- /dev/null +++ b/inc/taxonomies/class-taxonomy-city.php @@ -0,0 +1,152 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_City { + + /** + * + */ + public static function init() { + add_action( 'init', [ __CLASS__, 'definition' ] ); + add_action( 'cmb2_admin_init', [ __CLASS__, 'taxonomy_metaboxes' ] ); + } + + /** + * + */ + public static function definition() { + + $labels = [ + 'name' => esc_html__( 'Cities / Towns', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By City', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Cities / Towns', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Cities / Town', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent City', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent City:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit City', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update City', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New City', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New City', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Cities / Towns', 'opalestate-pro' ), + ]; + + register_taxonomy( 'opalestate_city', 'opalestate_property', [ + 'labels' => apply_filters( 'opalestate_taxomony_city_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'city', + 'rewrite' => [ 'slug' => esc_html__( 'city', 'opalestate-pro' ) ], + 'public' => true, + 'show_ui' => true, + ] ); + } + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public static function taxonomy_metaboxes() { + + $prefix = 'opalestate_city_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'City Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'opalestate_city' ], // Tells CMB2 which taxonomies should have these fields + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Image', 'opalestate-pro' ), + 'desc' => esc_html__( 'City image', 'opalestate-pro' ), + 'id' => $prefix . 'image', + 'type' => 'file', + 'preview_size' => 'small', + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + ] ); + + //// + $cmb_term->add_field( [ + 'name' => esc_html__( 'Country', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in countries of estate panel', 'opalestate-pro' ), + 'id' => $prefix . 'location', + 'taxonomy' => 'opalestate_location', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + ] ); + + /// + $cmb_term->add_field( [ + 'name' => esc_html__( 'State / Province', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in City/Town of estate panel', 'opalestate-pro' ), + 'id' => $prefix . 'state', + 'taxonomy' => 'opalestate_state', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + ] ); + } + + /** + * Gets list. + * + * @param array $args + * @return array|int|\WP_Error + */ + public static function get_list( $args = [] ) { + $default = [ + 'taxonomy' => 'opalestate_city', + 'hide_empty' => true, + ]; + + if ( $args ) { + $default = array_merge( $default, $args ); + } + + return get_terms( $default ); + } + + /** + * Render dopdown list. + * + * @param int $selected + * @return string + */ + public static function dropdown_list( $selected = 0 ) { + $id = 'opalestate_city' . rand(); + $args = [ + 'show_option_none' => esc_html__( 'Select City', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'name' => 'city', + 'show_count' => 0, + 'hierarchical' => '', + 'selected' => $selected, + 'value_field' => 'slug', + 'taxonomy' => 'opalestate_city', + 'orderby' => 'name', + 'order' => 'ASC', + 'echo' => 0, + ]; + + $label = ''; + + echo $label . wp_dropdown_categories( $args ); + } +} + +Opalestate_Taxonomy_City::init(); diff --git a/inc/taxonomies/class-taxonomy-labels.php b/inc/taxonomies/class-taxonomy-labels.php new file mode 100755 index 00000000..735ece67 --- /dev/null +++ b/inc/taxonomies/class-taxonomy-labels.php @@ -0,0 +1,150 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_Label { + + /** + * + */ + public function __construct() { + + add_action( 'init', [ $this, 'definition' ] ); + + add_filter( 'opalestate_taxomony_label_metaboxes', [ $this, 'metaboxes' ] ); + add_action( 'cmb2_admin_init', [ $this, 'taxonomy_metaboxes' ], 999 ); + } + + /** + * + */ + public function definition() { + + $labels = [ + 'name' => esc_html__( 'Label', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By Label', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Label', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Label', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Label', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Label:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Label', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Label', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Label', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Label', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Label', 'opalestate-pro' ), + ]; + + register_taxonomy( 'opalestate_label', 'opalestate_property', [ + 'labels' => apply_filters( 'opalestate_label_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'property-label', + 'rewrite' => [ 'slug' => esc_html__( 'property-label', 'opalestate-pro' ) ], + 'public' => true, + 'show_ui' => true, + ] ); + } + + public function metaboxes() { + + } + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public function taxonomy_metaboxes() { + + $prefix = 'opalestate_label_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'Category Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'opalestate_label' ], // Tells CMB2 which taxonomies should have these fields + // 'new_term_section' => true, // Will display in the "Add New Category" section + ] ); + $cmb_term->add_field( [ + 'name' => esc_html__( 'Background', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set background of label', 'opalestate-pro' ), + 'id' => $prefix . 'lb_bg', + 'type' => 'colorpicker', + ] ); + $cmb_term->add_field( [ + 'name' => esc_html__( 'Color', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set color of text', 'opalestate-pro' ), + 'id' => $prefix . 'lb_color', + 'type' => 'colorpicker', + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Image Logo', 'opalestate-pro' ), + 'desc' => esc_html__( 'Or Using Image Logo without using text', 'opalestate-pro' ), + 'id' => $prefix . 'lb_img', + 'type' => 'file', + 'preview_size' => 'small', + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + ] ); + } + + /** + * Gets list. + * + * @param array $args + * @return array|int|\WP_Error + */ + public static function get_list( $args = [] ) { + $default = [ + 'taxonomy' => 'opalestate_label', + 'hide_empty' => false, + ]; + + if ( $args ) { + $default = array_merge( $default, $args ); + } + + return get_terms( $default ); + } + + /** + * Render dopdown list. + * + * @param int $selected + * @return string + */ + public static function dropdown_list( $selected = 0 ) { + $id = 'opalestate_label' . rand(); + + $args = [ + 'show_option_none' => esc_html__( 'Select Label', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'show_count' => 0, + 'hierarchical' => '', + 'name' => 'label', + 'value_field' => 'slug', + 'selected' => $selected, + 'taxonomy' => 'opalestate_label', + ]; + + return wp_dropdown_categories( $args ); + } +} + +new Opalestate_Taxonomy_Label(); diff --git a/inc/taxonomies/class-taxonomy-locations.php b/inc/taxonomies/class-taxonomy-locations.php new file mode 100755 index 00000000..4837273a --- /dev/null +++ b/inc/taxonomies/class-taxonomy-locations.php @@ -0,0 +1,152 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_Location { + + /** + * + */ + public function __construct() { + add_action( 'init', [ $this, 'definition' ] ); + add_filter( 'opalestate_taxomony_location_metaboxes', [ $this, 'metaboxes' ] ); + add_action( 'cmb2_admin_init', [ $this, 'taxonomy_metaboxes' ] ); + } + + /** + * + */ + public function definition() { + + $labels = [ + 'name' => esc_html__( 'Countries', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By Country', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Countries', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Countries', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Country', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Country:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Country', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Country', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Country', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Country', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Countries', 'opalestate-pro' ), + ]; + + register_taxonomy( 'opalestate_location', 'opalestate_property', [ + 'labels' => apply_filters( 'opalestate_taxomony_location_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'location', + 'rewrite' => [ 'slug' => esc_html__( 'location', 'opalestate-pro' ) ], + 'public' => true, + 'show_ui' => true, + ] ); + } + + /** + * + */ + public function metaboxes() { + + } + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public function taxonomy_metaboxes() { + + $prefix = 'opalestate_location_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'Country Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'opalestate_location' ], // Tells CMB2 which taxonomies should have these fields + // 'new_term_section' => true, // Will display in the "Add New Category" section + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Image', 'opalestate-pro' ), + 'desc' => esc_html__( 'Country image', 'opalestate-pro' ), + 'id' => $prefix . 'image', + 'type' => 'file', + 'preview_size' => 'small', + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + ] ); + } + + /** + * + */ + public static function get_list() { + return get_terms( 'opalestate_location', [ 'hide_empty' => false ] ); + } + + /** + * + */ + public static function dropdown_agents_list( $selected = 0 ) { + $id = "opalestate_location" . rand(); + $args = [ + 'show_option_none' => esc_html__( 'Select Country', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'name' => 'location', + 'show_count' => 0, + 'hierarchical' => '', + 'selected' => $selected, + 'value_field' => 'slug', + 'taxonomy' => 'opalestate_agent_location', + ]; + + return wp_dropdown_categories( $args ); + } + + /** + * + */ + public static function dropdown_list( $selected = 0 ) { + $id = 'opalestate_location' . rand(); + $args = [ + 'show_option_none' => esc_html__( 'Select Country', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'name' => 'location', + 'show_count' => 0, + 'hierarchical' => '', + 'selected' => $selected, + 'value_field' => 'slug', + 'taxonomy' => 'opalestate_location', + 'orderby' => 'name', + 'order' => 'ASC', + 'echo' => 0, + ]; + + $label = ''; + + echo $label . wp_dropdown_categories( $args ); + } + + public static function get_multi_check_list() { + + } +} + +new Opalestate_Taxonomy_Location(); diff --git a/inc/taxonomies/class-taxonomy-neighborhood.php b/inc/taxonomies/class-taxonomy-neighborhood.php new file mode 100755 index 00000000..3913e26b --- /dev/null +++ b/inc/taxonomies/class-taxonomy-neighborhood.php @@ -0,0 +1,114 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +class Opalestate_Taxonomy_Neighborhood{ + + /** + * + */ + public static function init(){ + add_action( 'init', array( $this, 'definition' ), 99 ); + + add_action( 'cmb2_admin_init', array( $this, 'taxonomy_metaboxes' ), 9 ); + + + } + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public function taxonomy_metaboxes() { + + $prefix = 'opalestate_nb_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( array( + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'Type Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => array( 'term' ), // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => array( 'opalestate_neighborhoods' ), // Tells CMB2 which taxonomies should have these fields + // 'new_term_section' => true, // Will display in the "Add New Category" section + ) ); + + $cmb_term->add_field( array( + 'name' => esc_html__( 'Icon', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in google map', 'opalestate-pro' ), + 'id' => $prefix . 'icon', + 'type' => 'file', + 'preview_size' => 'small', + 'options' => array( + 'url' => false, // Hide the text input for the url + ) + ) ); + } + + /** + * + */ + public function definition(){ + + $labels = array( + 'name' => esc_html__( 'Neighborhoods', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By Neighborhood', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Neighborhoods', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Neighborhoods', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Neighborhood', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Neighborhood:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Neighborhood', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Neighborhood', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Neighborhood', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Neighborhood', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Neighborhoods', 'opalestate-pro' ), + ); + + register_taxonomy( 'opalestate_neighborhoods', array( 'opalestate_property' ) , array( + 'labels' => apply_filters( 'opalestate_taxomony_neighborhoods_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'property-neighborhood', + 'rewrite' => array( 'slug' => esc_html__( 'property-neighborhood', 'opalestate-pro' ) ), + 'public' => true, + 'show_ui' => true, + ) ); + } + + public static function metaboxes(){ + + } + + public static function dropdown_list( $selected=0 ){ + + $id = "opalestate_neighborhoods".rand(); + + $args = array( + 'show_option_none' => esc_html__( 'Select Neighborhoods', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'show_count' => 0, + 'hierarchical' => '', + 'name' => 'neighborhoods', + 'selected' => $selected, + 'value_field' => 'slug', + 'taxonomy' => 'opalestate_neighborhoods' + ); + + return wp_dropdown_categories( $args ); + } + +} + +new Opalestate_Taxonomy_Neighborhood(); \ No newline at end of file diff --git a/inc/taxonomies/class-taxonomy-state.php b/inc/taxonomies/class-taxonomy-state.php new file mode 100755 index 00000000..86b7a6e1 --- /dev/null +++ b/inc/taxonomies/class-taxonomy-state.php @@ -0,0 +1,145 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_State { + /** + * Opalestate_Taxonomy_State constructor. + */ + public function __construct() { + add_action( 'init', [ $this, 'definition' ] ); + add_filter( 'opalestate_taxomony_state_metaboxes', [ $this, 'metaboxes' ] ); + add_action( 'cmb2_admin_init', [ $this, 'taxonomy_metaboxes' ] ); + } + + /** + * + */ + public function definition() { + $labels = [ + 'name' => esc_html__( 'States / Provinces', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By State', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search States', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All States / Province', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent State', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent State:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit State', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update State', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New State', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New State', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'States / Provinces', 'opalestate-pro' ), + ]; + + register_taxonomy( 'opalestate_state', 'opalestate_property', [ + 'labels' => apply_filters( 'opalestate_taxomony_state_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'state', + 'rewrite' => [ 'slug' => esc_html__( 'state', 'opalestate-pro' ) ], + 'public' => true, + 'show_ui' => true, + ] ); + } + + + public function metaboxes() { + + } + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public function taxonomy_metaboxes() { + $prefix = 'opalestate_state_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'State Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'opalestate_state' ], // Tells CMB2 which taxonomies should have these fields + // 'new_term_section' => true, // Will display in the "Add New Category" section + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Image', 'opalestate-pro' ), + 'desc' => esc_html__( 'State image', 'opalestate-pro' ), + 'id' => $prefix . 'image', + 'type' => 'file', + 'preview_size' => 'small', + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + ] ); + + //// + $cmb_term->add_field( [ + 'name' => esc_html__( 'Country', 'opalestate-pro' ), + 'desc' => esc_html__( 'Select one, to add new you create in countries of estate panel', 'opalestate-pro' ), + 'id' => $prefix . "location", + 'taxonomy' => 'opalestate_location', //Enter Taxonomy Slug + 'type' => 'taxonomy_select', + ] ); + + /// + } + + public static function get_list() { + return get_terms( 'opalestate_state', [ 'hide_empty' => false ] ); + } + + public static function dropdown_agents_list( $selected = 0 ) { + $id = "opalestate_state" . rand(); + $args = [ + 'show_option_none' => esc_html__( 'Select State', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'name' => 'state', + 'show_count' => 0, + 'hierarchical' => '', + 'selected' => $selected, + 'value_field' => 'slug', + 'taxonomy' => 'opalestate_agent_state', + ]; + + return wp_dropdown_categories( $args ); + } + + public static function dropdown_list( $selected = 0 ) { + $id = "opalestate_state" . rand(); + $args = [ + 'show_option_none' => esc_html__( 'Select State', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'name' => 'state', + 'show_count' => 0, + 'hierarchical' => '', + 'selected' => $selected, + 'value_field' => 'slug', + 'taxonomy' => 'opalestate_state', + 'orderby' => 'name', + 'order' => 'ASC', + 'echo' => 0, + ]; + + $label = ''; + + echo $label . wp_dropdown_categories( $args ); + } +} + +new Opalestate_Taxonomy_State(); diff --git a/inc/taxonomies/class-taxonomy-status.php b/inc/taxonomies/class-taxonomy-status.php new file mode 100755 index 00000000..78feedc7 --- /dev/null +++ b/inc/taxonomies/class-taxonomy-status.php @@ -0,0 +1,159 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_Status { + + /** + * Opalestate_Taxonomy_Status constructor. + */ + public function __construct() { + add_action( 'init', [ $this, 'definition' ] ); + add_filter( 'opalestate_taxomony_status_metaboxes', [ $this, 'metaboxes' ] ); + add_action( 'cmb2_admin_init', [ $this, 'taxonomy_metaboxes' ] ); + } + + /** + * + */ + public function definition() { + $labels = [ + 'name' => esc_html__( 'Status', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By Status', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Status', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Status', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Status', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Status:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Status', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Status', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Status', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Status', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Status', 'opalestate-pro' ), + ]; + register_taxonomy( 'opalestate_status', 'opalestate_property', [ + 'labels' => apply_filters( 'opalestate_status_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'status', + 'rewrite' => [ 'slug' => esc_html__( 'status', 'opalestate-pro' ) ], + 'public' => true, + 'show_ui' => true, + ] ); + } + + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public function taxonomy_metaboxes() { + + $prefix = 'opalestate_status_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'Category Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'opalestate_status' ], // Tells CMB2 which taxonomies should have these fields + // 'new_term_section' => true, // Will display in the "Add New Category" section + ] ); + $cmb_term->add_field( [ + 'name' => esc_html__( 'Background', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set background of label', 'opalestate-pro' ), + 'id' => $prefix . 'lb_bg', + 'type' => 'colorpicker', + ] ); + $cmb_term->add_field( [ + 'name' => esc_html__( 'Color', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set background of text', 'opalestate-pro' ), + 'id' => $prefix . 'lb_color', + 'type' => 'colorpicker', + ] ); + $cmb_term->add_field( [ + 'name' => esc_html__( 'Order', 'opalestate-pro' ), + 'desc' => esc_html__( 'Set a priority to display', 'opalestate-pro' ), + 'id' => $prefix . 'order', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 0, + ] ); + } + + public function metaboxes() { + + } + + /** + * Gets list. + * + * @param array $args + * @return array|int|\WP_Error + */ + public static function get_list( $args = [] ) { + $default = apply_filters( 'opalestate_status_args', [ + 'taxonomy' => 'opalestate_status', + 'hide_empty' => false, + 'hierarchical' => false, + 'parent' => 0, + 'order' => 'ASC', + 'orderby' => 'meta_value_num', + 'meta_query' => [ + [ + 'key' => 'opalestate_status_order', + 'type' => 'NUMERIC', + ], + ], + ] ); + + if ( $args ) { + $default = array_merge( $default, $args ); + } + + return get_terms( $default ); + } + + /** + * Render dopdown list. + * + * @param int $selected + * @return string + */ + public static function dropdown_list( $selected = 0 ) { + $id = 'palestate_status' . rand(); + + $args = [ + 'show_option_none' => esc_html__( 'Select Status', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'show_count' => 0, + 'hierarchical' => '', + 'name' => 'status', + 'value_field' => 'slug', + 'selected' => $selected, + 'taxonomy' => 'opalestate_status', + 'echo' => 0, + ]; + + $label = ''; + + echo $label . wp_dropdown_categories( $args ); + } +} + +new Opalestate_Taxonomy_Status(); diff --git a/inc/taxonomies/class-taxonomy-types.php b/inc/taxonomies/class-taxonomy-types.php new file mode 100755 index 00000000..0983da5c --- /dev/null +++ b/inc/taxonomies/class-taxonomy-types.php @@ -0,0 +1,136 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Taxonomy_Type { + + /** + * + */ + public function __construct() { + add_action( 'init', [ $this, 'definition' ] ); + add_action( 'cmb2_admin_init', [ $this, 'taxonomy_metaboxes' ] ); + } + + /** + * Hook in and add a metabox to add fields to taxonomy terms + */ + public function taxonomy_metaboxes() { + + $prefix = 'opalestate_type_'; + /** + * Metabox to add fields to categories and tags + */ + $cmb_term = new_cmb2_box( [ + 'id' => $prefix . 'edit', + 'title' => esc_html__( 'Type Metabox', 'opalestate-pro' ), // Doesn't output for term boxes + 'object_types' => [ 'term' ], // Tells CMB2 to use term_meta vs post_meta + 'taxonomies' => [ 'opalestate_types' ], // Tells CMB2 which taxonomies should have these fields + // 'new_term_section' => true, // Will display in the "Add New Category" section + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Custom Icon Marker', 'opalestate-pro' ), + 'desc' => esc_html__( 'This image will display in google map', 'opalestate-pro' ), + 'id' => $prefix . 'iconmarker', + 'type' => 'file', + 'preview_size' => 'small', + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + ] ); + + $cmb_term->add_field( [ + 'name' => esc_html__( 'Image', 'opalestate-pro' ), + 'desc' => esc_html__( 'Type image', 'opalestate-pro' ), + 'id' => $prefix . 'image', + 'type' => 'file', + 'preview_size' => 'small', + 'options' => [ + 'url' => false, // Hide the text input for the url + ], + ] ); + } + + /** + * + */ + public function definition() { + + $labels = [ + 'name' => esc_html__( 'Types', 'opalestate-pro' ), + 'singular_name' => esc_html__( 'Properties By Type', 'opalestate-pro' ), + 'search_items' => esc_html__( 'Search Types', 'opalestate-pro' ), + 'all_items' => esc_html__( 'All Types', 'opalestate-pro' ), + 'parent_item' => esc_html__( 'Parent Type', 'opalestate-pro' ), + 'parent_item_colon' => esc_html__( 'Parent Type:', 'opalestate-pro' ), + 'edit_item' => esc_html__( 'Edit Type', 'opalestate-pro' ), + 'update_item' => esc_html__( 'Update Type', 'opalestate-pro' ), + 'add_new_item' => esc_html__( 'Add New Type', 'opalestate-pro' ), + 'new_item_name' => esc_html__( 'New Type', 'opalestate-pro' ), + 'menu_name' => esc_html__( 'Types', 'opalestate-pro' ), + ]; + + register_taxonomy( 'opalestate_types', [ 'opalestate_property' ], [ + 'labels' => apply_filters( 'opalestate_taxomony_types_labels', $labels ), + 'hierarchical' => true, + 'query_var' => 'type', + 'rewrite' => [ 'slug' => esc_html__( 'type', 'opalestate-pro' ) ], + 'public' => true, + 'show_ui' => true, + ] ); + } + + public function metaboxes() { + + } + + public static function get_list() { + return get_terms( 'opalestate_types', [ 'hide_empty' => false ] ); + } + + public static function dropdown_list( $selected = 0 ) { + + $id = "opalestate_types" . rand(); + + $args = [ + 'show_option_none' => esc_html__( 'Select Type', 'opalestate-pro' ), + 'id' => $id, + 'class' => 'form-control', + 'show_count' => 0, + 'hierarchical' => '', + 'name' => 'types', + 'selected' => $selected, + 'value_field' => 'slug', + 'taxonomy' => 'opalestate_types', + 'echo' => 0, + ]; + + $label = ''; + + echo $label . wp_dropdown_categories( $args ); + } + + public static function get_multi_check_list( $stypes ) { + $list = self::get_list(); + + echo opalestate_terms_multi_check( $list, $stypes ); + + } +} + +new Opalestate_Taxonomy_Type(); diff --git a/inc/template-functions.php b/inc/template-functions.php new file mode 100755 index 00000000..7bc077d7 --- /dev/null +++ b/inc/template-functions.php @@ -0,0 +1,1050 @@ + + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +function opalestate_archive_search_block() { + echo opalestate_load_template_path( 'parts/archive-search-block' ); +} + +function opalestate_property_mortgage() { + echo opalestate_load_template_path( 'parts/mortgage-calculator' ); +} + +function opalestate_load_template_path( $tpl, $args = [], $layout = '' ) { + return Opalestate_Template_Loader::get_template_part( $tpl, $args, $layout ); + +} + +function opalestate_get_image_avatar_placehold() { + return OPALESTATE_PLUGIN_URL . 'assets/images/avatar-placeholder.jpg'; +} + +function opalestate_get_admin_view( $file ) { + return OPALESTATE_PLUGIN_DIR . 'inc/admin/views/' . $file; +} + +function opalestate_user_fullname( $user_id = null ) { + $user_info = $user_id ? new WP_User( $user_id ) : wp_get_current_user(); + if ( $user_info->first_name ) { + if ( $user_info->last_name ) { + return $user_info->first_name . ' ' . $user_info->last_name; + } + + return $user_info->first_name; + } + + return $user_info->display_name; +} + +/** + * Hooks Give actions, when present in the $_GET superglobal. Every opalestate_action + * present in $_GET is called using WordPress's do_action function. These + * functions are called on init. + * + * @return void + * + */ +function opalestate_get_actions() { + if ( isset( $_GET['opalestate_action'] ) ) { + do_action( 'opalestate_' . sanitize_text_field( $_GET['opalestate_action'] ), $_GET ); + } +} + +add_action( 'init', 'opalestate_get_actions' ); + +/** + * Hooks Give actions, when present in the $_POST superglobal. Every opalestate_action + * present in $_POST is called using WordPress's do_action function. These + * functions are called on init. + * + * @return void + * + */ +function opalestate_post_actions() { + if ( isset( $_POST['opalestate_action'] ) ) { + do_action( 'opalestate_' . sanitize_text_field( $_POST['opalestate_action'] ), $_POST ); + } +} + +add_action( 'init', 'opalestate_post_actions' ); + +/** + * + */ +function opalestate_template_init() { + if ( isset( $_GET['display'] ) && ( $_GET['display'] == 'list' || $_GET['display'] == 'grid' || $_GET['display'] == 'map' ) ) { + setcookie( 'opalestate_displaymode', trim( $_GET['display'] ), time() + 3600 * 24 * 100, '/' ); + $_COOKIE['opalestate_displaymode'] = trim( $_GET['display'] ); + } +} + +add_action( 'init', 'opalestate_template_init' ); + + +function opalestate_get_read_message_uri( $message_id ) { + $args['message_id'] = $message_id; + + return opalestate_get_current_url( $args ); +} + + +function opalestate_terms_multi_check( $terms ) { + $html = '

            '; + + foreach ( $terms as $term ) { + + $id = time() . '-' . $term->slug; + $html .= '
            '; + $html .= ''; + $html .= ' '; + $html .= '
            '; + + } + + $html .= '
            '; + + return $html; +} + +function opalestate_get_image_by_id( $id ) { + if ( $id ) { + $url = wp_get_attachment_url( $id ); + + return ''; + } + + return ''; +} + + +/** + * + */ +function opalestate_get_loop_thumbnail( $size = 'property-thumbnail' ) { ?> + + + + + + esc_html__( 'Featured Desending', 'opalestate-pro' ), + 'price_asc' => esc_html__( 'Price Ascending', 'opalestate-pro' ), + 'price_desc' => esc_html__( 'Price Desending', 'opalestate-pro' ), + 'areasize_asc' => esc_html__( 'Area Ascending', 'opalestate-pro' ), + 'areasize_desc' => esc_html__( 'Area Desending', 'opalestate-pro' ), + ]; + $modes = apply_filters( 'opalestate_sortable_modes', $modes ); + + $modes = array_merge( [ '' => esc_html__( 'Sort By', 'opalestate-pro' ) ], $modes ); + $output = '
            '; + + return $output; +} + + +/** + * + */ +function opalestate_show_display_modes( $default = 'list' ) { + $op_display = opalestate_get_display_mode( $default ); + + $modes = apply_filters( 'opalestate_listing_display_mode', [ + 'grid' => [ + 'icon' => 'fa fa-th', + 'title' => esc_html__( 'Grid', 'opalestate-pro' ), + ], + 'list' => [ + 'icon' => 'fa fa-th-list', + 'title' => esc_html__( 'List', 'opalestate-pro' ), + ], + /* 'map' => array( + 'icon' => 'fa fa-map-marker', + 'title' => esc_html__('Map','opalestate-pro') + ), */ + ] ); + + + echo '
            '; + foreach ( $modes as $key => $mode ) { + echo ''; + } + + echo '
            '; + +} + +if ( ! function_exists( 'opalestate_pagination' ) ) { + /** + * Opalestate pagination. + * + * @param string $pages + * @param int $range + */ + function opalestate_pagination( $pages = '', $range = 2 ) { + global $wp_query; + + $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1; + $paged = isset( $wp_query->query['paged'] ) ? $wp_query->query['paged'] : $paged; + $paged = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : $paged; + + // if(empty($paged))$paged = 1; + + $prev = $paged - 1; + $next = $paged + 1; + $showitems = ( $range * 2 ) + 1; + $range = 2; // change it to show more links + + if ( $pages == '' ) { + global $wp_query; + + $pages = $wp_query->max_num_pages; + if ( ! $pages ) { + $pages = 1; + } + } + + if ( 1 != $pages ) { + + echo '
            '; + echo '
              '; + echo ( $paged > 2 && $paged > $range + 1 && $showitems < $pages ) ? '
            • ' : ''; + echo ( $paged > 1 ) ? '
            • ' : '
            • '; + for ( $i = 1; $i <= $pages; $i++ ) { + if ( 1 != $pages && ( ! ( $i >= $paged + $range + 1 || $i <= $paged - $range - 1 ) || $pages <= $showitems ) ) { + if ( $paged == $i ) { + echo '
            • ' . $i . '
            • '; + } else { + echo '
            • ' . $i . '
            • '; + } + } + } + echo ( $paged < $pages ) ? '
            • ' : ''; + echo ( $paged < $pages - 1 && $paged + $range - 1 < $pages && $showitems < $pages ) ? '
            • ' : ''; + echo '
            '; + echo '
            '; + } + } +} + +function opalestate_show_display_status() { + global $wp; + $current_url = add_query_arg( $wp->query_string, '', preg_replace( '#page\/\d+#', '', home_url( $wp->request ) ) ); + $current_url = remove_query_arg( [ 'paged', 'page' ], $current_url ); + $gstatus = isset( $_GET['status'] ) ? sanitize_text_field( $_GET['status'] ) : ''; + + // echo $current_url;die; + ?> +
            + + '; + + echo ''; + echo ''; + ?> +
              +
            • active" data-id="all"> + +
            • + + +
            • + name; ?> +
            • + +
            + +
            + '_wp_page_template', + 'meta_value' => 'page-templates/page-property-search-results.php', + ] ); + + if ( $pages ) { + $pages = reset( $pages ); + $search_submit = get_permalink( $pages->ID ); + } else { + $search_submit = isset( $opalestate_options['search_map_properties_page'] ) ? get_permalink( absint( $opalestate_options['search_map_properties_page'] ) ) : get_bloginfo( 'url' ); + } + + return apply_filters( 'opalestate_get_search_link', $search_submit ); +} + +function opalestate_get_user_properties_uri( $args = [] ) { + + global $opalestate_options; + + $uri = isset( $opalestate_options['submission_list_page'] ) ? get_permalink( absint( $opalestate_options['submission_list_page'] ) ) : get_bloginfo( 'url' ); + + if ( ! empty( $args ) ) { + // Check for backward compatibility + if ( is_string( $args ) ) { + $args = str_replace( '?', '', $args ); + } + $args = wp_parse_args( $args ); + $uri = add_query_arg( $args, $uri ); + } + + $scheme = defined( 'FORCE_SSL_ADMIN' ) && FORCE_SSL_ADMIN ? 'https' : 'admin'; + + $ajax_url = admin_url( 'admin-ajax.php', $scheme ); + + if ( ( ! preg_match( '/^https/', $uri ) && preg_match( '/^https/', $ajax_url ) ) ) { + $uri = preg_replace( '/^http:/', 'https:', $uri ); + } + + return apply_filters( 'opalestate_get_user_properties_uri', $uri ); +} + +function opalestate_get_favorite_page_uri() { + + global $opalestate_options; + + $favorite_page = isset( $opalestate_options['favorite_page'] ) ? get_permalink( absint( $opalestate_options['favorite_page'] ) ) : get_bloginfo( 'url' ); + + return apply_filters( 'opalestate_get_favorite_page_uri', $favorite_page ); +} + +function opalestate_single_layout_templates( $layout ) { + + $layout['v2'] = esc_html__( 'Vesion 2', 'opalestate-pro' ); + $layout['v3'] = esc_html__( 'Vesion 3', 'opalestate-pro' ); + $layout['v4'] = esc_html__( 'Vesion 4', 'opalestate-pro' ); + $layout['v5'] = esc_html__( 'Vesion 5', 'opalestate-pro' ); + + return $layout; +} + +add_filter( 'opalestate_single_layout_templates', 'opalestate_single_layout_templates' ); + +function opalestate_single_the_property_layout() { + + global $opalestate_options; + + $layout = get_post_meta( get_the_ID(), OPALESTATE_PROPERTY_PREFIX . 'layout', true ); + if ( ! $layout ) { + $layout = isset( $opalestate_options['layout'] ) ? $opalestate_options['layout'] : ''; + } + + return $layout; +} + + +function opalestate_single_layout_prieview() { + $layout = [ + '' => esc_html__( 'Inherit', 'opalestate-pro' ), + 'gallery-thumbnail' => esc_html__( 'Gallery Thumb Nav', 'opalestate-pro' ), + 'gallery-slider' => esc_html__( 'Gallery Slider', 'opalestate-pro' ), + 'map' => esc_html__( 'Maps', 'opalestate-pro' ), + 'tabs-gallery' => esc_html__( 'Tabs - Gallery Active', 'opalestate-pro' ), + 'tabs-map' => esc_html__( 'Tabs - Map Active', 'opalestate-pro' ), + 'tabs-street' => esc_html__( 'Tabs - Street Map Active', 'opalestate-pro' ), + 'tour360' => esc_html__( 'Tour 360', 'opalestate-pro' ), + 'gallery-metro' => esc_html__( 'Gallery Metro', 'opalestate-pro' ), + 'mark-picture' => esc_html__( 'Mark Picture', 'opalestate-pro' ), + ]; + + return $layout; +} + + +function opalestate_property_loop_price() { + echo opalestate_load_template_path( 'parts/property-loop-price' ); +} + +function opalestate_property_featured_label() { + echo opalestate_load_template_path( 'parts/featured-label' ); +} + +function opalestate_property_label() { + echo opalestate_load_template_path( 'parts/property-label' ); +} + +function opalestate_property_status() { + echo opalestate_load_template_path( 'parts/property-status' ); +} + +/** + * Single property logic functions + */ + +/** + * Single property logic functions + */ +function opalestate_property_meta() { + echo opalestate_load_template_path( 'single-property/meta' ); +} + +function opalestate_single_show_map() { + return false; +} + +/** + * Single property logic functions + */ +function opalestate_property_preview() { + global $property; + $preview = $property->get_preview_template(); + if ( isset( $_GET['preview'] ) && $_GET['preview'] ) { + $preview = sanitize_text_field( $_GET['preview'] ); + } + switch ( $preview ) { + case 'tour360': + echo opalestate_load_template_path( 'single-property/preview/virtualtour' ); + break; + case 'gallery-slider': + echo opalestate_load_template_path( 'single-property/preview/gallery-slider' ); + break; + + case 'tabs-gallery': + echo opalestate_load_template_path( 'single-property/preview/tabs', [ 'tab_active' => 'gallery-slider' ] ); + remove_action( 'opalestate_after_single_property_summary', 'opalestate_property_map', 30 ); + add_filter( 'opalestate_single_show_map', 'opalestate_single_show_map' ); + break; + case 'tabs-map': + echo opalestate_load_template_path( 'single-property/preview/tabs', [ 'tab_active' => 'google-map' ] ); + remove_action( 'opalestate_after_single_property_summary', 'opalestate_property_map', 30 ); + add_filter( 'opalestate_single_show_map', 'opalestate_single_show_map' ); + break; + case 'tabs-street': + echo opalestate_load_template_path( 'single-property/preview/tabs', [ 'tab_active' => 'street-view-map' ] ); + remove_action( 'opalestate_after_single_property_summary', 'opalestate_property_map', 30 ); + add_filter( 'opalestate_single_show_map', 'opalestate_single_show_map' ); + break; + case 'map': + echo opalestate_load_template_path( 'single-property/preview/map', [ 'tab_active' => 'street-view-map' ] ); + remove_action( 'opalestate_after_single_property_summary', 'opalestate_property_map', 30 ); + break; + case 'mark-picture': + echo opalestate_load_template_path( 'single-property/preview/mark-picture' ); + break; + case 'gallery-metro': + echo opalestate_load_template_path( 'single-property/preview/gallery-metro' ); + break; + default: + echo opalestate_load_template_path( 'single-property/preview' ); + break; + } +} + +/** + * + */ +function opalestate_property_content() { + echo opalestate_load_template_path( 'single-property/content' ); +} + +/** + * + */ +function opalestate_property_information() { + echo opalestate_load_template_path( 'single-property/information' ); +} + +/** + * + */ +function opalestate_property_amenities() { + echo opalestate_load_template_path( 'single-property/amenities' ); +} + +function opalestate_property_facilities() { + echo opalestate_load_template_path( 'single-property/facilities' ); +} + + +function opalestate_property_attachments() { + echo opalestate_load_template_path( 'single-property/attachments' ); +} + +function opalestate_property_tags() { + return the_tags( '
            ', '', '
            ' ); +} + +function opalestate_property_map() { + echo opalestate_load_template_path( 'single-property/map' ); +} + +function opalestate_property_map_v2() { + echo opalestate_load_template_path( 'single-property/map-v2' ); +} + +function opalestate_property_nearby() { + echo opalestate_load_template_path( 'single-property/nearby' ); +} + +function opalestate_property_walkscore() { + echo opalestate_load_template_path( 'single-property/walkscore' ); +} + +function opalestate_property_apartments() { + echo opalestate_load_template_path( 'single-property/apartments' ); +} + +function opalestate_property_floor_plans() { + echo opalestate_load_template_path( 'single-property/floor-plans' ); +} + +function opalestate_property_views_statistics() { + echo opalestate_load_template_path( 'single-property/views-statistics' ); +} + +function opalestate_property_author() { + echo opalestate_load_template_path( 'single-property/author' ); +} + + +function opalestate_property_author_v2() { + echo opalestate_load_template_path( 'single-property/author-v2' ); +} + +function opalestate_property_author_v3() { + echo opalestate_load_template_path( 'single-property/author-v3' ); +} + + +function opalestate_property_video() { + echo opalestate_load_template_path( 'single-property/video' ); +} + +function opalestate_property_virtual_tour() { + echo opalestate_load_template_path( 'single-property/virtualtour' ); +} + +function opalestate_properties_same_agent() { + echo opalestate_load_template_path( 'single-property/sameagent' ); +} + +function opalestate_property_location() { + echo opalestate_load_template_path( 'single-property/location' ); +} + +/** + * + */ +add_action( 'opalestate_single_property_sameagent', 'opalestate_properties_same_agent', 5 ); + +function opalestate_agent_summary() { + echo opalestate_load_template_path( 'single-agent/summary' ); +} + +function opalestate_agent_properties() { + echo opalestate_load_template_path( 'single-agent/properties' ); +} + +function opalestate_agent_featured_properties() { + echo opalestate_load_template_path( 'single-agent/featured-properties' ); +} + +function opalestate_agent_contactform() { + global $post; + $args = [ 'post_id' => $post->ID ]; + echo opalestate_load_template_path( 'single-agent/form', $args ); +} + +add_action( 'opalestate_single_agent_summary', 'opalestate_agent_summary', 5 ); +add_action( 'opalestate_single_content_agent_after', 'opalestate_agent_properties', 15 ); +add_action( 'opalestate_single_content_agent_sidebar', 'opalestate_agent_featured_properties', 16 ); + +/** + * + */ +function opalestate_agent_navbar() { + +} + +add_action( 'opalestate_single_agent_summary', 'opalestate_agent_navbar', 5 ); + +/** + * Search page: + */ + +function opalestate_show_contact_share_search_link() { + $args = []; + echo opalestate_load_template_path( 'user/share-search-form', $args ); +} + +add_action( 'opalestate_before_render_search_properties_result', 'opalestate_show_contact_share_search_link' ); + +function opalestate_calculate_distance_geo( $lat, $long, $start_lat, $start_long, $dist_measure ) { + $angle = $start_long - $long; + $distance = sin( deg2rad( $start_lat ) ) * sin( deg2rad( $lat ) ) + cos( deg2rad( $start_lat ) ) * cos( deg2rad( $lat ) ) * cos( deg2rad( $angle ) ); + $distance = acos( $distance ); + $distance = rad2deg( $distance ); + + if ( $dist_measure == 'miles' ) { + $distance_miles = $distance * 60 * 1.1515; + + return '(' . round( $distance_miles, 2 ) . ' ' . esc_html__( 'miles', 'opalestate-pro' ) . ')'; + } else { + $distance_miles = $distance * 60 * 1.1515 * 1.6; + + return '(' . round( $distance_miles, 2 ) . ' ' . esc_html__( 'km', 'opalestate-pro' ) . ')'; + } +} + + +function opalestate_get_walkscore_results( $latitude, $longitude, $address ) { + $walkscore_api = esc_html( opalestate_get_option( 'walkscore_api_key', '' ) ); + if ( ! $walkscore_api ) { + return null; + } + + if ( ! $latitude || ! $longitude ) { + return null; + } + + $w = new Opalestate_WalkScore( $walkscore_api ); + + $walkscore = $w->WalkScore( [ + 'lat' => $latitude, + 'lon' => $longitude, + 'address' => $address, + 'transit' => 1, + 'bike' => 1, + ] ); + + if ( ! isset( $walkscore->walkscore ) || ! $walkscore->walkscore ) { + return null; + } + + return $walkscore; +} + +function opalestate_get_property_walkscore_results( $property ) { + if ( ! $property instanceof Opalestate_Property ) { + return false; + } + + $map = $property->get_map(); + + $latitude = $map['latitude']; + $longitude = $map['longitude']; + + $key = md5( $latitude . $longitude ); + + if ( ! $latitude || ! $longitude ) { + return false; + } + + $address = $property->get_address() ? $property->get_address() : ''; + + if ( false === ( $results = get_transient( $key ) ) ) { + $results = opalestate_get_walkscore_results( $latitude, $longitude, $address ); + set_transient( $key, $results, 24 * 7 * HOUR_IN_SECONDS ); + } + + return $results; +} + +function opalestate_get_property_walkscore_score( $property ) { + $walkscore = opalestate_get_property_walkscore_results( $property ); + + return $walkscore->walkscore; +} + +/** + * Gets related properties template. + */ +function opalestate_properties_related() { + + $num = apply_filters( 'opalestate_related_properties_number', 6 ); + $args = [ + 'post_type' => 'opalestate_property', + 'posts_per_page' => $num, + 'post__not_in' => [ get_the_ID() ], + ]; + + $terms = wp_get_post_terms( get_the_ID(), 'opalestate_types' ); + + $tax_query = []; + if ( $terms ) { + $tax_query[] = [ + [ + 'taxonomy' => 'opalestate_types', + 'field' => 'slug', + 'terms' => $terms[0]->slug, + ], + ]; + } + + $status = wp_get_post_terms( get_the_ID(), 'opalestate_status' ); + if ( ! is_wp_error( $status ) && $status ) { + $tax_query[] = + [ + 'taxonomy' => 'opalestate_status', + 'field' => 'slug', + 'terms' => $status[0]->slug, + + ]; + } + + + if ( $tax_query ) { + $args['tax_query'] = [ 'relation' => 'AND' ]; + $args['tax_query'] = array_merge( $args['tax_query'], $tax_query ); + } + $query = Opalestate_Query::get_property_query( $args ); + + $args = [ + 'query' => $query, + 'column' => 3, + 'style' => 'content-property-' . opalestate_get_option( 'single_related_properties_layout', 'grid' ), + 'heading' => esc_html__( 'Similar Properties You May Like', 'opalestate-pro' ), + ]; + + echo opalestate_load_template_path( 'parts/modules/carousel', $args ); +} + +/** + * Gets nearby properties template. + */ +function opalestate_properties_nearby() { + global $property; + $maps = $property->get_map(); + + $num = apply_filters( 'opalestate_nearby_properties_number', 6 ); + $post_id = get_the_ID(); + + $args = [ + 'post_type' => 'opalestate_property', + 'posts_per_page' => $num, + ]; + + $geo_lat = $maps['latitude']; + $geo_long = $maps['longitude']; + + if ( empty( $geo_lat ) || empty( $geo_long ) ) { + return; + } + + $radius = 5; + $post_ids = Opalestate_Query::filter_by_location( $geo_lat, $geo_long, $radius ); + + if ( empty( $post_ids ) ) { + return; + } + + $args['post__in'] = $post_ids; + + $query = Opalestate_Query::get_property_query( $args ); + + $args = [ + 'query' => $query, + 'column' => 3, + 'style' => 'content-property-' . opalestate_get_option( 'single_nearby_properties_layout', 'grid' ), + 'heading' => esc_html__( 'New Listings Nearby', 'opalestate-pro' ), + ]; + + echo opalestate_load_template_path( 'parts/modules/carousel', $args ); +} + +/** + * Opalestate Date Format - Allows to change date format for everything Opalestate. + * + * @return string + */ +function opalestate_date_format() { + return apply_filters( 'opalestate_date_format', get_option( 'date_format' ) ); +} + +/** + * Opalestate Time Format - Allows to change time format for everything Opalestate. + * + * @return string + */ +function opalestate_time_format() { + return apply_filters( 'opalestate_time_format', get_option( 'time_format' ) ); +} + +/** + * Get HTML for ratings. + * + * @param float $rating Rating being shown. + * @param int $count Total number of ratings. + * @return string + */ +function opalestate_get_rating_html( $rating, $count = 0 ) { + $html = ''; + + if ( 0 < $rating ) { + /* translators: %s: rating */ + $label = sprintf( esc_html__( 'Rated %s out of 5', 'opalestate-pro' ), $rating ); + $html = ''; + } + + return apply_filters( 'opalestate_property_get_rating_html', $html, $rating, $count ); +} + +/** + * Get HTML for star rating. + * + * @param float $rating Rating being shown. + * @param int $count Total number of ratings. + * @return string + */ +function opalestate_get_star_rating_html( $rating, $count = 0 ) { + $html = ''; + + if ( 0 < $count ) { + /* translators: 1: rating 2: rating count */ + $html .= sprintf( _n( 'Rated %1$s out of 5 based on %2$s customer rating', 'Rated %1$s out of 5 based on %2$s customer ratings', $count, 'opalestate-pro' ), + '' . esc_html( + $rating + ) . '', '' . esc_html( $count ) . '' ); + } else { + /* translators: %s: rating */ + $html .= sprintf( esc_html__( 'Rated %s out of 5', 'opalestate-pro' ), '' . esc_html( $rating ) . '' ); + } + + $html .= ''; + + return apply_filters( 'opalestate_get_star_rating_html', $html, $rating, $count ); +} + +function opalestate_load_yelp_places() { + if ( ! isset( $_POST['property_id'] ) ) { + return; + } + + $property_id = absint( $_POST['property_id'] ); + $property = opalesetate_property( $property_id ); + + if ( ! Opalestate_Yelp::get_client_id() || ! Opalestate_Yelp::get_app_key() ) { + return; + } + + $categories = Opalestate_Yelp::get_categories(); + if ( ! $categories ) { + return; + } + + $map = $property->get_map(); + + $latitude = $map['latitude']; + $longitude = $map['longitude']; + if ( ! $latitude || ! $longitude ) { + return; + } + + $all_categories = Opalestate_Yelp::get_all_categories(); + $yelp_dist_measure = opalestate_get_option( 'yelp_measurement_unit' ); + + ob_start(); + ?> + + + get_results( $category, $latitude, $longitude ); + + if ( ! $results || ! $results->businesses ) { + continue; + } + + $category_name = $all_categories[ $category ]['category']; + $category_icon = $all_categories[ $category ]['category_sign']; + ?> +
            +
            + +
            +
            + + businesses as $result ) : ?> + location->display_address; + $business_address0 = isset( $location[0] ) ? $location[0] : ''; + $business_address1 = isset( $location[1] ) ? $location[1] : ''; + $business_address2 = isset( $location[2] ) ? $location[2] : ''; + $business_address = $business_address0 . ' ' . $business_address1 . ' ' . $business_address2; + + $business_rating = isset( $result->rating ) ? $result->rating : 0; + ?> +
            + image_url ) && $result->image_url ) : ?> +
            + + <?php echo esc_attr( $result->name ); ?> + +
            + + +
            +
            + name ); ?> +
            + coordinates->latitude ) && isset( $result->coordinates->longitude ) ) : ?> +
            + coordinates->latitude, + $result->coordinates->longitude, + $latitude, + $longitude, + $yelp_dist_measure + ); ?> +
            + +
            +
            + +
            +
            + + + + review_count ), + 'review numbers', + 'opalestate-pro' + ), + number_format_i18n( absint( $result->review_count ) ) + ); + ?> + +
            +
            +
            + +
            + absint( $_POST['id'] ) ] ); + get_footer(); + + $output = ob_get_contents(); + ob_end_clean(); + echo $output; + exit(); +} + +add_action( 'wp_ajax_opalestate_ajax_create_property_print', 'opalestate_ajax_create_property_print' ); +add_action( 'wp_ajax_nopriv_opalestate_ajax_create_property_print', 'opalestate_ajax_create_property_print' ); + +if ( ! function_exists( 'opalestate_property_print_button' ) ) { + function opalestate_property_print_button( $id ) { + ?> + + + + + + + ' . esc_html__( 'Request Viewing', 'opalestate-pro' ) . ' + '; +} + +/// +add_action( 'opalestate_single_property_layout', 'opalestate_single_property_layout' ); +function opalestate_single_property_layout( $layout ) { + switch ( $layout ) { + case 'v2': + opalestate_single_property_layout_v2(); + break; + case 'v3': + opalestate_single_property_layout_v3(); + break; + case 'v4': + opalestate_single_property_layout_v4(); + break; + case 'v5': + opalestate_single_property_layout_v5(); + break; + default: + opalestate_single_property_layout_default(); + break; + } +} + + +/** + * Forms + */ +function opalestate_property_request_view_form() { + if ( ! is_single_property() ) { + return; + } + + $object = OpalEstate_User_Message::get_instance(); + $fields = $object->get_request_review_form_fields(); + + $form = OpalEstate()->html->render_form( $fields ); + + $description = esc_html__( 'Physical Arrange viewings is always been attractive to property clients. Fill out the form to arrange visualizations around our properties.', 'opalestate-pro' ); + + $atts = [ + 'heading' => esc_html__( 'Request Viewing', 'opalestate-pro' ), + 'description' => $description, + 'id' => 'property-request-view', + 'form' => $form, + ]; + + echo opalestate_load_template_path( 'messages/request-reviewing-form', $atts ); +} + +add_action( 'wp_footer', 'opalestate_property_request_view_form', 9 ); + +function opalestate_property_equiry_form() { + echo opalestate_load_template_path( 'messages/enquiry-form' ); +} + +if ( ! function_exists( "opalestate_login_register_form_popup" ) ) { + function opalestate_login_register_form_popup() { + echo opalestate_load_template_path( 'user/my-account-popup' ); + } +} +add_action( 'wp_footer', 'opalestate_login_register_form_popup', 9 ); + + +/** + * Add "Custom" template to page attirbute template section. + */ +function opalestate_add_template_to_select( $post_templates, $wp_theme, $post, $post_type ) { + + // Add custom template named template-custom.php to select dropdown + $post_templates['user-management.php'] = esc_html__( 'User Management', 'opalestate-pro' ); + $post_templates['fullwidth-page.php'] = esc_html__( 'Opalestate Fullwidth', 'opalestate-pro' ); + + return $post_templates; +} + +add_filter( 'theme_page_templates', 'opalestate_add_template_to_select', 10, 4 ); + +function opalestate_load_plugin_template( $template ) { + if ( get_page_template_slug() === 'user-management.php' ) { + + if ( $theme_file = locate_template( [ 'page-templates/user-management.php', 'user-management.php' ] ) ) { + $template = $theme_file; + } else { + $template = OPALESTATE_PLUGIN_DIR . '/templates/user-management.php'; + } + } elseif ( get_page_template_slug() === 'fullwidth-page.php' ) { + + if ( $theme_file = locate_template( [ 'page-templates/fullwidth-page.php', 'fullwidth-page.php' ] ) ) { + $template = $theme_file; + } else { + $template = OPALESTATE_PLUGIN_DIR . '/templates/fullwidth-page.php'; + } + + } + + if ( $template == '' ) { + throw new \Exception( 'No template found' ); + } + + return $template; +} + +add_filter( 'template_include', 'opalestate_load_plugin_template' ); + +add_action( 'opalestate_before_property_loop_item', 'opalestate_property_featured_label' ); +add_action( 'opalestate_before_property_loop_item', 'opalestate_property_label' ); diff --git a/inc/user/class-opalestate-user-form-handler.php b/inc/user/class-opalestate-user-form-handler.php new file mode 100755 index 00000000..03f3c033 --- /dev/null +++ b/inc/user/class-opalestate-user-form-handler.php @@ -0,0 +1,327 @@ +get_error_code() ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . $validation->get_error_message() ); + } + + /* validate username */ + if ( ! $username ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . esc_html__( 'Username is required.', 'opalestate-pro' ) ); + } else { + + if ( is_email( $username ) ) { + /* user object */ + $user = get_user_by( 'email', $username ); + if ( $user->user_login ) { + $credentials['user_login'] = $user->user_login; + } else { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . esc_html__( 'A user could not be found with this email address.', + 'opalestate-pro' ) ); + } + } else { + $credentials['user_login'] = $username; + } + + } + + /* validate password if it empty */ + if ( ! $password ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . esc_html__( 'Password is required.', 'opalestate-pro' ) ); + } + $credentials['user_password'] = $password; + /* is rembemer me checkbox */ + $credentials['remember'] = isset( $_POST['remember'] ); + + /* signon user */ + $user = wp_signon( $credentials, is_ssl() ); + if ( is_wp_error( $user ) ) { + throw new Exception( $user->get_error_message() ); + } else { + + /* after signon successfully */ + do_action( 'opalestate_after_signon_successfully', $user ); + $redirect = opalestate_get_dashdoard_page_uri(); + + if ( ! empty( $_POST['redirect'] ) ) { + $redirect = sanitize_text_field( $_POST['redirect'] ); + } elseif ( wp_get_referer() ) { + $redirect = wp_get_referer(); + } + + $redirect = apply_filters( 'opalestate_signon_redirect_url', $redirect ); + + if ( opalestate_is_ajax_request() ) { + + opalestate_add_notice( 'success', esc_html__( 'Logged successfully, welcome back!', 'opalestate-pro' ) ); + ob_start(); + opalestate_print_notices(); + $message = ob_get_clean(); + + + wp_send_json( [ + 'status' => true, + 'message' => $message, + 'redirect' => $redirect, + ] ); + + } else { + wp_safe_redirect( $redirect ); + exit(); + } + } + + do_action( 'opalestate_user_proccessing_login_after' ); + + } catch ( Exception $e ) { + opalestate_add_notice( 'error', $e->getMessage() ); + } + + if ( opalestate_is_ajax_request() ) { + ob_start(); + opalestate_print_notices(); + $message = ob_get_clean(); + wp_send_json( [ + 'status' => false, + 'message' => $message, + ] ); + } + } + + /** + * Register processer + */ + public function process_register() { + if ( ! isset( $_POST['opalestate-register-nonce'] ) ) { + return; + } + + $nonce_value = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( $_POST['_wpnonce'] ) : ''; + $nonce_value = isset( $_POST['opalestate-register-nonce'] ) ? sanitize_text_field( $_POST['opalestate-register-nonce'] ) : $nonce_value; + + /* verify wp nonce */ + if ( ! isset( $_POST['confirmed_register'] ) || ! wp_verify_nonce( $nonce_value, 'opalestate-register' ) ) { + return; + } + + try { + + do_action( 'opalestate_user_proccessing_register_before' ); + + $credentials = []; + $username = isset( $_POST['username'] ) ? sanitize_user( $_POST['username'] ) : ''; + $email = isset( $_POST['email'] ) ? sanitize_email( $_POST['email'] ) : ''; + $password = isset( $_POST['password'] ) ? sanitize_text_field( $_POST['password'] ) : ''; + $password1 = isset( $_POST['password1'] ) ? sanitize_text_field( $_POST['password1'] ) : ''; + + /* sanitize, allow hook process like block somebody =)))) */ + $validation = apply_filters( 'opalestate_validation_process_register_error', new WP_Error(), $username, $email ); + + /* sanitize */ + if ( $validation->get_error_code() ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . $validation->get_error_message() ); + } + + /* validate username */ + if ( ! $username ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . esc_html__( 'Username is required.', 'opalestate-pro' ) ); + } else { + $credentials['user_login'] = $username; + } + + /* validate email */ + if ( ! $email ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . esc_html__( 'Email is required.', 'opalestate-pro' ) ); + } else { + $credentials['user_email'] = $email; + } + + /* validate password */ + if ( ! $password ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . esc_html__( 'Password is required.', 'opalestate-pro' ) ); + } + if ( $password !== $password1 ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . esc_html__( 'Re-Password is not match.', 'opalestate-pro' ) ); + } + $credentials['user_pass'] = $password; + + + /* create new user */ + $user_id = opalestate_create_user( $credentials ); + + if ( is_wp_error( $user_id ) ) { + throw new Exception( '' . esc_html__( 'ERROR', 'opalestate-pro' ) . ': ' . $user_id->get_error_message() ); + } else { + + /* after register successfully */ + do_action( 'opalestate_after_register_successfully', $user_id ); + + $redirect = home_url(); + if ( opalestate_get_option( 'login_user' ) ) { + wp_set_auth_cookie( $user_id ); + $redirect = opalestate_get_dashdoard_page_uri(); + } elseif ( ! empty( $_POST['redirect'] ) ) { + $redirect = sanitize_text_field( $_POST['redirect'] ); + } elseif ( wp_get_referer() ) { + $redirect = wp_get_referer(); + } + + do_action( 'opalestate_user_proccessing_register_after' ); + + $redirect = apply_filters( 'opalestate_register_redirect_url', $redirect ); + + /* is ajax request */ + if ( opalestate_is_ajax_request() ) { + wp_send_json( [ 'status' => true, 'redirect' => $redirect ] ); + } else { + wp_safe_redirect( $redirect ); + exit(); + } + } + + } catch ( Exception $e ) { + opalestate_add_notice( 'error', $e->getMessage() ); + } + + /* is ajax request */ + if ( opalestate_is_ajax_request() ) { + ob_start(); + opalestate_print_notices(); + $message = ob_get_clean(); + wp_send_json( [ + 'status' => false, + 'message' => $message, + ] ); + } + } + + /** + * process user doForgotPassword with username/password + * + * return Json Data with messsage and login status + */ + public function process_forgot_password() { + + // First check the nonce, if it fails the function will break + check_ajax_referer( 'ajax-pbr-lostpassword-nonce', 'security' ); + + global $wpdb; + + $account = sanitize_text_field( $_POST['user_login'] ); + + if ( empty( $account ) ) { + $error = esc_html__( 'Enter an username or e-mail address.', 'opalestate-pro' ); + } else { + if ( is_email( $account ) ) { + if ( email_exists( $account ) ) { + $get_by = 'email'; + } else { + $error = esc_html__( 'There is no user registered with that email address.', 'opalestate-pro' ); + } + } elseif ( validate_username( $account ) ) { + if ( username_exists( $account ) ) { + $get_by = 'login'; + } else { + $error = esc_html__( 'There is no user registered with that username.', 'opalestate-pro' ); + } + } else { + $error = esc_html__( 'Invalid username or e-mail address.', 'opalestate-pro' ); + } + } + + if ( empty ( $error ) ) { + $random_password = wp_generate_password(); + + $user = get_user_by( $get_by, $account ); + + $update_user = wp_update_user( [ 'ID' => $user->ID, 'user_pass' => $random_password ] ); + + if ( $update_user ) { + + $from = get_option( 'admin_email' ); // Set whatever you want like mail@yourdomain.com + + if ( ! ( isset( $from ) && is_email( $from ) ) ) { + $sitename = strtolower( $_SERVER['SERVER_NAME'] ); + if ( substr( $sitename, 0, 4 ) == 'www.' ) { + $sitename = substr( $sitename, 4 ); + } + $from = 'do-not-reply@' . $sitename; + } + + $to = $user->user_email; + $subject = esc_html__( 'Your new password', 'opalestate-pro' ); + $sender = 'From: ' . get_option( 'name' ) . ' <' . $from . '>' . "\r\n"; + + $message = esc_html__( 'Your new password is: ', 'opalestate-pro' ) . $random_password; + + $headers[] = 'MIME-Version: 1.0' . "\r\n"; + $headers[] = 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; + $headers[] = "X-Mailer: PHP \r\n"; + $headers[] = $sender; + + $mail = wp_mail( $to, $subject, $message, $headers ); + if ( $mail ) { + $success = esc_html__( 'Check your email address for you new password.', 'opalestate-pro' ); + } else { + $error = esc_html__( 'System is unable to send you mail containg your new password.', 'opalestate-pro' ); + } + } else { + $error = esc_html__( 'Oops! Something went wrong while updating your account.', 'opalestate-pro' ); + } + } + + if ( ! empty( $error ) ) { + echo wp_send_json( [ 'status' => false, 'message' => ( $error ) ] ); + } + + if ( ! empty( $success ) ) { + echo wp_send_json( [ 'status' => false, 'message' => $success ] ); + } + die(); + } +} + +new Opalestate_User_Form_Handler(); diff --git a/inc/user/class-opalestate-user-search.php b/inc/user/class-opalestate-user-search.php new file mode 100755 index 00000000..406dc1be --- /dev/null +++ b/inc/user/class-opalestate-user-search.php @@ -0,0 +1,222 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class OpalEstate_User_Search { + + /** + * + */ + protected $user_id = 0; + + /** + * + */ + public static function get_instance() { + static $_instance; + if ( ! $_instance ) { + $_instance = new self(); + } + + return $_instance; + } + + /** + * + */ + public function __construct() { + add_action( 'init', [ $this, 'init' ] ); + } + + /** + * Set values when user logined in system + */ + public function init() { + + global $current_user; + wp_get_current_user(); + + $this->user_id = $current_user->ID; + + add_filter( 'opalestate_management_user_menu', [ $this, 'dashboard_menu' ] ); + add_action( 'wp_ajax_opalestate_ajx_save_search', [ $this, 'do_save' ] ); + add_action( 'wp_ajax_nopriv_opalestate_ajx_save_search', [ $this, 'do_save' ] ); + + add_shortcode( 'opalestate_user_saved_search', [ $this, 'savedsearch_page' ] ); + + add_filter( 'opalestate_user_content_saved_search_page', [ $this, 'savedsearch_page' ] ); + } + + /** + * + */ + public function get_search_by_code( $code ) { + + global $wpdb; + + $query = " SELECT * FROM " . $wpdb->prefix . "opalestate_usersearch WHERE code like %s "; + + $items = $wpdb->get_results( $wpdb->prepare( $query, $code ) ); + + if ( isset( $items[0] ) ) { + return $items[0]; + } + + return false; + } + + /** + * + */ + public function has_existed( $params ) { + return $this->get_search_by_code( md5( $params ) ); + } + + /** + * + */ + public function insert( $data ) { + global $wpdb; + + $args = [ + 'name' => '', + 'params' => '', + 'code' => '', + 'user_id' => $this->user_id, + ]; + + $args = array_merge( $args, $data ); + $args['code'] = md5( $data['params'] ); + + $id = $wpdb->insert( $wpdb->prefix . 'opalestate_usersearch', $args ); + + return $id; + } + + /** + * + */ + public static function install() { + try { + if ( ! function_exists( 'dbDelta' ) ) { + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + } + + global $wpdb; + + $charset_collate = $wpdb->get_charset_collate(); + + $sql = 'CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'opalestate_usersearch' . ' ( + id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255), + params VARCHAR(255), + code VARCHAR(255), + user_id INT(11) DEFAULT 0 + ) ' . $charset_collate; + dbDelta( $sql ); + + } catch ( Exception $e ) { + + } + } + + /** + * + */ + public function do_save() { + if ( $this->user_id > 0 && isset( $_POST['params'] ) && isset( $_POST['name'] ) && ! empty( $_POST['name'] ) && ! empty( $_POST['params'] ) ) { + if ( ! $this->has_existed( $_POST['params'] ) ) { + $this->insert( [ 'name' => sanitize_text_field( $_POST['name'] ), 'params' => $_POST['params'] ] ); + $result = [ 'status' => true, 'message' => esc_html__( 'Saved this search successful.', 'opalestate-pro' ) ]; + } else { + $result = [ 'status' => false, 'message' => esc_html__( 'You saved this search', 'opalestate-pro' ) ]; + } + } else { + $result = [ 'status' => false, 'message' => esc_html__( 'Please sign in to save this search.', 'opalestate-pro' ) ]; + } + + echo json_encode( $result ); + + die; + } + + /** + * + */ + public function do_delete( $id ) { + + global $wpdb; + if ( $this->user_id ) { + $wpdb->delete( $wpdb->prefix . "opalestate_usersearch", [ 'id' => $id, 'user_id' => $this->user_id ], [ '%d' ] ); + } + } + + /** + * + */ + public function get_list() { + + global $wpdb; + + $query = " SELECT * FROM " . $wpdb->prefix . "opalestate_usersearch where user_id=" . $this->user_id; + + return $wpdb->get_results( $query ); + } + + /** + * + */ + public function is_saved() { + + } + + /** + * + */ + public function dashboard_menu( $menu ) { + $menu['savedsearch'] = [ + 'icon' => 'fa fa-search', + 'link' => 'saved_search', + 'title' => esc_html__( 'Saved Search', 'opalestate-pro' ), + 'id' => 0, + ]; + + return $menu; + } + + /** + * + */ + public function savedsearch_page() { + if ( isset( $_GET['doaction'] ) && $_GET['doaction'] == 'delete' && isset( $_GET['id'] ) ) { + $this->do_delete( absint( $_GET['id'] ) ); + } + + return opalestate_load_template_path( 'user-search/content-savedsearch' ); + } + + /** + * + */ + public function render_button() { + echo opalestate_load_template_path( 'user-search/render-form' ); + } +} + +if ( opalestate_options( 'enable_saved_usersearch', 'on' ) == 'on' ) { + OpalEstate_User_Search::get_instance(); +} diff --git a/inc/user/class-opalestate-user.php b/inc/user/class-opalestate-user.php new file mode 100755 index 00000000..593120fe --- /dev/null +++ b/inc/user/class-opalestate-user.php @@ -0,0 +1,717 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class OpalEstate_User { + + /** + * @var + */ + public $id; + + /** + * @var + */ + public $current_user_id; + + /** + * @var mixed|void + */ + public $enable_extra_profile; + + /** + * @var + */ + public $roles; + + /** + * @var + */ + public $user_id; + + /** + * @var + */ + public $new_attachmenet_ids; + + /** + * OpalEstate_User constructor. + */ + public function __construct() { + define( "OPALESTATE_USER_PROFILE_PREFIX", 'opalestate_user_' ); + + $shortcodes = [ + 'user_profile' => [ 'code' => 'user_profile', 'label' => esc_html__( 'User Profile', 'opalestate-pro' ) ], + 'myaccount' => [ 'code' => 'myaccount', 'label' => esc_html__( 'My Account', 'opalestate-pro' ) ], + ]; + + foreach ( $shortcodes as $shortcode ) { + add_shortcode( 'opalestate_' . $shortcode['code'], [ $this, $shortcode['code'] ] ); + } + $this->enable_extra_profile = opalestate_options( 'enable_extra_profile', 'on' ); + + + add_action( 'init', [ $this, 'process_frontend_submit' ], 99999 ); + add_action( 'cmb2_render_text_password', [ $this, 'cmb2_render_text_password' ], 10, 5 ); + + /** + * Ajax action + */ + add_action( 'wp_ajax_opalestate_save_changepass', [ $this, 'save_change_password' ] ); + add_action( 'wp_ajax_nopriv_opalestate_save_changepass', [ $this, 'save_change_password' ] ); + + add_action( 'cmb2_after_init', [ $this, 'process_submission' ], 100000 ); + + /** + * Check User Block Submission + */ + add_action( 'opalestate_submission_form_before', [ $this, 'show_message' ], 9 ); + add_action( 'opalestate_before_process_ajax_upload_file', [ $this, 'check_blocked' ] ); + add_action( 'opalestate_before_process_ajax_upload_user_avatar', [ $this, 'check_blocked' ] ); + add_action( 'opalestate_profile_form_process_before', [ $this, 'check_blocked' ] ); + add_action( 'opalestate_toggle_featured_property_before', [ $this, 'check_blocked' ] ); + + add_action( 'user_register', [ $this, 'on_create_user' ], 10, 1 ); + add_action( 'profile_update', [ $this, 'on_create_user' ], 10, 1 ); + add_action( 'opalestate_after_register_successfully', [ $this, 'on_regiser_user' ], 10, 1 ); + + add_action( 'init', [ $this, 'disable' ], 100000 ); + add_action( 'init', [ $this, 'init_user_management' ] ); + + add_action( 'wp_enqueue_scripts', [ $this, 'scripts_styles' ], 99 ); + + add_filter( 'pre_get_posts', [ $this, 'show_current_user_attachments' ] ); + } + + /** + * FrontEnd Submission + */ + public function show_current_user_attachments( $wp_query_obj ) { + + global $current_user, $pagenow; + + if ( ! is_a( $current_user, 'WP_User' ) ) { + return; + } + + if ( ! in_array( $pagenow, [ 'upload.php', 'admin-ajax.php' ] ) ) { + return; + } + + if ( ! empty( $current_user->roles ) ) { + if ( in_array( 'opalestate_agent', $current_user->roles ) || in_array( 'opalestate_agency', $current_user->roles ) ) { + $wp_query_obj->set( 'author', $current_user->ID ); + } + } + + return; + } + + + public function scripts_styles() { + if ( isset( $_GET['tab'] ) ) { + wp_register_style( 'opalesate-cmb2-front', OPALESTATE_PLUGIN_URL . 'assets/cmb2-front.css' ); + wp_enqueue_style( 'opalesate-cmb2-front' ); + wp_register_script( + 'opalestate-dashboard', + OPALESTATE_PLUGIN_URL . 'assets/js/frontend/dashboard.js', + [ + 'jquery', + ], + '1.0', + true + ); + wp_enqueue_script( 'opalestate-dashboard' ); + } + } + + public function disable() { + if ( ! current_user_can( 'manage_options' ) ) { + add_action( 'wp_before_admin_bar_render', [ $this, 'disable_profile_page' ] ); + add_action( 'admin_init', [ $this, 'disable_profile_page' ] ); + add_filter( 'show_admin_bar', '__return_false' ); + } + } + + public function init_user_management() { + add_action( 'opalestate_user_content_profile_page', [ $this, 'user_profile' ] ); + } + + /** + * + */ + public function show_message_user_profile() { + $user_id = isset( $_GET['user_id'] ) ? intval( $_GET['user_id'] ) : 0; + $roles = opalestate_user_roles_by_user_id( $user_id ); + if ( $roles ): + if ( in_array( 'opalestate_agency', $roles ) ): + $agency_id = get_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', true ); + if ( ! $agency_id ) { + return; + } + $link = get_edit_post_link( $agency_id ); + ?> +
            +

            Opal Estate Agency and click here to update Agency profile', + 'opalestate-pro' ), $link ); ?>

            +
            + +
            +

            Opal Estate Agent and click here to update Agent profile', + 'opalestate-pro' ), $link ); ?>

            +
            + + remove_role( 'subscriber' ); + // Replace the current role with 'editor' role + $u->set_role( sanitize_text_field( $_POST['role'] ) ); + + if ( $roles && in_array( $_POST['role'], $roles ) ) { + $role = str_replace( 'opalestate_', '', sanitize_text_field( $_POST['role'] ) ); + do_action( 'opalestate_on_set_role_' . $role, $user_id ); + } + } + } + + /** + * + */ + public function on_create_user( $user_id ) { + if ( isset( $_POST['role'] ) ) { + $roles = opalestate_user_roles_by_user_id( $user_id ); + + if ( $roles && in_array( $_POST['role'], $roles ) ) { + $role = sanitize_text_field( str_replace( 'opalestate_', '', $_POST['role'] ) ); + do_action( 'opalestate_on_set_role_' . $role, $user_id ); + } + } + } + + /** + * + */ + public function disable_profile_page() { + + // Remove AdminBar Link + if ( + 'wp_before_admin_bar_render' === current_filter() + && ! current_user_can( 'manage_options' ) + ) { + return $GLOBALS['wp_admin_bar']->remove_menu( 'edit-profile', 'user-actions' ); + } + + // Remove (sub)menu items + // remove_menu_page( 'profile.php' ); + if ( function_exists( "remove_submenu_page" ) ) { + remove_submenu_page( 'users.php', 'profile.php' ); + } + // Deny access to the profile page and redirect upon try + if ( + defined( 'IS_PROFILE_PAGE' ) + && IS_PROFILE_PAGE + && ! current_user_can( 'manage_options' ) + ) { + // wp_redirect( admin_url() ); + exit; + } + } + + /** + * + */ + public function show_message() { + if ( $this->is_blocked() ) { + + echo apply_filters( 'opalestate_user_block_submission_message', + '
            ' . __( 'Your account was blocked to use the submission form, so you could not submit any property.', 'opalestate-pro' ) . '
            ' ); + } + } + + /** + * + */ + public function check_blocked() { + $check = $this->is_blocked(); + if ( $check ) { + $std = new stdClass(); + $std->status = false; + $std->message = esc_html__( 'Your account is blocked, you could not complete this action', 'opalestate-pro' ); + $std->msg = $std->message; + echo json_encode( $std ); + wp_die(); + } + } + + /** + * + */ + public static function get_user_types() { + + return apply_filters( 'opalestate_usertypes', [ + 'none' => esc_html__( 'Subscriber', 'opalestate-pro' ), + 'opalestate_agent' => esc_html__( 'Agent', 'opalestate-pro' ), + 'opalestate_agency' => esc_html__( 'Agency', 'opalestate-pro' ), + ] ); + } + + /** + * + */ + public function process_submission() { + + global $current_user; + // Verify Nonce + $user_id = get_current_user_id(); + $check = $this->is_blocked(); + + $key = 'nonce_CMB2phpopalestate_user_front'; + + if ( ! isset( $_POST[ $key ] ) || empty( $_POST[ $key ] ) || ! is_user_logged_in() || $check ) { + return; + } + + $this->process_upload_files( 0 ); + + $prefix = OPALESTATE_USER_PROFILE_PREFIX; + $post_id = $user_id; + + $metaboxes = apply_filters( 'cmb2_meta_boxes', $this->front_edit_fields( [] ) ); + cmb2_get_metabox_form( $metaboxes[ $prefix . 'front' ], $post_id ); + $cmb = cmb2_get_metabox( $prefix . 'front', $post_id ); + + $sanitized_values = $cmb->get_sanitized_values( $_POST ); + $cmb->save_fields( $user_id, 'user', $sanitized_values ); + + $posts = [ + 'first_name', + 'last_name', + 'description', + ]; + + foreach ( $posts as $post ) { + if ( isset( $_POST[ $post ] ) ) { + update_user_meta( $current_user->ID, $post, esc_attr( $_POST[ $post ] ) ); + } + } + + if ( $this->new_attachmenet_ids ) { + foreach ( $this->new_attachmenet_ids as $_id ) { + delete_post_meta( $_id, '_pending_to_use_', 1 ); + } + } + + $this->remove_dirty_images( $user_id ); + + return opalestate_output_msg_json( true, + __( 'The data updated successful, please wait for redirecting', 'opalestate-pro' ), + [ + 'heading' => esc_html__( 'Update Information', 'opalestate-pro' ), + 'redirect' => opalestate_get_user_management_page_uri( [ 'tab' => 'profile' ] ), + ] + ); + } + + /** + * Remove dirty images of current user + */ + public function remove_dirty_images( $user_id ) { + + if ( isset( $_POST['remove_image_id'] ) && is_array( $_POST['remove_image_id'] ) && $_POST['remove_image_id'] ) { + foreach ( $_POST['remove_image_id'] as $key => $value ) { + $post = get_post( $value ); + if ( $post->post_author == $user_id ) { + wp_delete_attachment( $value ); + } + } + } + } + + + /** + * + * + */ + private function get_field_name( $field ) { + return OPALESTATE_USER_PROFILE_PREFIX . $field; + } + + /** + * Process upload images for properties + */ + public function upload_image( $submitted_file, $parent_id = 0 ) { + return opalesate_upload_image( $submitted_file, $parent_id ); + } + + + private function process_upload_files( $post_id ) { + + //upload images for featured and gallery images + if ( isset( $_FILES ) && ! empty( $_FILES ) ) { + + /// + $fields = [ + $this->get_field_name( 'avatar_id' ), + ]; + + foreach ( $_FILES as $key => $value ) { + // allow processing in fixed collection + if ( in_array( $key, $fields ) ) { + $ufile = $_FILES[ $key ]; + + /// ///// + if ( isset( $ufile['name'] ) && is_array( $ufile['name'] ) ) { + $output = []; + + foreach ( $ufile['name'] as $f_key => $f_value ) { + $loop_file = [ + 'name' => $ufile['name'][ $f_key ], + 'type' => $ufile['type'][ $f_key ], + 'tmp_name' => $ufile['tmp_name'][ $f_key ], + 'error' => $ufile['error'][ $f_key ], + 'size' => $ufile['size'][ $f_key ], + ]; + $new_atm = $this->upload_image( $loop_file, $post_id ); + if ( $new_atm ) { + $_POST[ $key ] = isset( $_POST[ $key ] ) ? $_POST[ $key ] : []; + $_POST[ $key ][ $new_atm['attachment_id'] ] = $new_atm['url']; + $this->new_attachmenet_ids[ $new_atm['attachment_id'] ] = $new_atm['attachment_id']; + } + } + + } /// + elseif ( isset( $ufile['name'] ) ) { + $new_atm = $this->upload_image( $ufile, $post_id ); + if ( $new_atm ) { + $_POST[ $key ] = $new_atm['attachment_id']; + + if ( preg_match( "#id#", $key ) ) { + $_key = str_replace( "_id", "", $key ); + $_POST[ $_key ] = $new_atm['url']; + } + $this->new_attachmenet_ids[ $new_atm['attachment_id'] ] = $new_atm['attachment_id']; + } + } + //// / // + } + } + } + } + + /** + * + */ + public static function is_blocked() { + + global $current_user; + // Verify Nonce + $user_id = get_current_user_id(); + if ( $user_id <= 0 ) { + return true; + } + $blocked = get_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'block_submission', true ); + + return $blocked; + } + + /** + * + */ + public function get_avatar_url( $user_id ) { + + return get_avatar_url( $user_id ); + } + + /** + * + */ + public static function get_author_picture( $user_id ) { + $avatar = get_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'avatar', true ); + + if ( ! $avatar ) { + $avatar = opalestate_get_image_avatar_placehold(); + } + + return $avatar; + } + + /** + * + */ + public function shortcode_button() { + + } + + /** + * + */ + public function save_change_password() { + global $current_user; + + $nonce = 'nonce_CMB2phpopalestate_user_frontchangepass'; + if ( ! isset( $_POST[ $nonce ], $_POST['oldpassword'], $_POST['new_password'], $_POST['confirm_password'] ) || ! wp_verify_nonce( $_POST[ $nonce ], $nonce ) ) { + return false; + } + + do_action( 'opalestate_profile_form_process_before' ); + $output = new stdClass(); + $output->status = false; + $output->message = esc_html__( 'Found a problem while updating', 'opalestate-pro' ); + + wp_get_current_user(); + + $userID = $current_user->ID; + + $oldpassword = sanitize_text_field( $_POST['oldpassword'] ); + $new_password = sanitize_text_field( $_POST['new_password'] ); + $confirm_password = sanitize_text_field( $_POST['confirm_password'] ); + + if ( empty( $oldpassword ) || empty( $new_password ) || empty( $confirm_password ) ) { + $output->message = esc_html__( 'Passwords fields are not empty', 'opalestate-pro' ); + echo json_encode( $output ); + exit; + } + + if ( $new_password != $confirm_password ) { + $output->message = esc_html__( 'New password is not same confirm password', 'opalestate-pro' ); + echo json_encode( $output ); + exit; + } + + + $user = get_user_by( 'id', $userID ); + if ( $user && wp_check_password( $oldpassword, $user->data->user_pass, $userID ) ) { + wp_set_password( $new_password, $userID ); + $output->status = true; + $output->message = esc_html__( 'Password Updated', 'opalestate-pro' ); + } else { + $output->message = esc_html__( 'Old password is not correct', 'opalestate-pro' ); + } + + echo json_encode( $output ); + die(); + } + + /** + * Defines custom front end fields + * + * @access public + * @param array $metaboxes + * @return array + */ + public function front_edit_fields( array $metaboxes ) { + $post_id = 0; + $prefix = OPALESTATE_USER_PROFILE_PREFIX; + global $current_user; + + $default = []; + + $user_roles = $current_user->roles; + $user_role = array_shift( $user_roles ); + + $metabox = new Opalestate_User_MetaBox(); + + /// + if ( $this->get_member_id() ) { + $fields = array_merge_recursive( $default, + $metabox->get_front_base_field( $prefix ) + ); + } else { + $fields = array_merge_recursive( $default, + $metabox->get_front_base_field( $prefix ), + $metabox->get_job_fields( $prefix ), + $metabox->get_base_front_fields( $prefix ), + $metabox->get_address_fields( $prefix ) + ); + } + + + $metaboxes[ $prefix . 'front' ] = [ + 'id' => $prefix . 'front', + 'title' => esc_html__( 'Name and Description', 'opalestate-pro' ), + 'object_types' => [ 'opalestate_property' ], + 'context' => 'normal', + 'object_types' => [ 'user' ], // Tells CMB2 to use user_meta vs post_meta + 'priority' => 'high', + 'show_names' => true, + 'cmb_styles' => false, + 'fields' => $fields, + ]; + + + $metaboxes[ $prefix . 'frontchangepass' ] = [ + 'id' => $prefix . 'frontchangepass', + 'title' => esc_html__( 'Name and Description', 'opalestate-pro' ), + 'object_types' => [ 'opalestate_property' ], + 'context' => 'normal', + 'object_types' => [ 'user' ], // Tells CMB2 to use user_meta vs post_meta + 'priority' => 'high', + 'show_names' => true, + 'fields' => [ + [ + 'id' => "oldpassword", + 'name' => esc_html__( 'Old Password', 'opalestate-pro' ), + 'type' => 'text_password', + 'attributes' => [ + 'required' => 'required', + ], + 'description' => esc_html__( 'Please enter your old password', 'opalestate-pro' ), + ], + [ + 'id' => "new_password", + 'name' => esc_html__( 'New Password', 'opalestate-pro' ), + 'type' => 'text_password', + 'attributes' => [ + 'required' => 'required', + ], + 'description' => esc_html__( 'Please enter your new password.', 'opalestate-pro' ), + ], + [ + 'id' => "confirm_password", + 'name' => esc_html__( 'Confirm Password', 'opalestate-pro' ), + 'type' => 'text_password', + 'attributes' => [ + 'required' => 'required', + ], + 'description' => esc_html__( 'Please enter your confirm password.', 'opalestate-pro' ), + ], + ], + ]; + + + return $metaboxes; + } + + public function cmb2_render_text_password( $field_args, $escaped_value, $object_id, $object_type, $field_type_object ) { + echo $field_type_object->input( [ 'type' => 'password', 'class' => 'form-control' ] ); + } + + + public function myaccount() { + return opalestate_load_template_path( 'user/my-account' ); + } + + /** + * FrontEnd Submission + */ + public function user_profile() { + + global $current_user; + + if ( ! is_user_logged_in() ) { + echo opalestate_load_template_path( 'parts/not-allowed' ); + + return; + } + + $user_id = get_current_user_id(); + + + $metaboxes = apply_filters( 'cmb2_meta_boxes', $this->front_edit_fields( [] ) ); + + return opalestate_load_template_path( 'user/profile', [ 'metaboxes' => $metaboxes, 'user_id' => $user_id ] ); + + } + + public function process_frontend_submit() { + + if ( opalestate_options( 'enable_extra_profile', 'on' ) != 'on' ) { + return; + } + + global $current_user; + } + + /** + * + */ + private function update_data_agent_or_agency( $prefix ) { + + global $current_user; + + + $post_id = isset( $_POST['object_id'] ) && absint( $_POST['object_id'] ) ? absint( $_POST['object_id'] ) : 0; + $user_id = get_current_user_id(); + $metaboxes = apply_filters( 'opalestate_before_render_profile_' . $_GET['tab'] . '_form', [], $post_id ); + $metaboxes = apply_filters( 'cmb2_meta_boxes', $metaboxes ); + + if ( isset( $metaboxes[ $prefix . 'front' ] ) ) { + if ( ! empty( $post_id ) ) { + $old_post = get_post( $post_id ); + $post_date = $old_post->post_date; + } else { + $post_date = ''; + } + + $data = [ + 'ID' => $post_id, + 'post_title' => $current_user->display_name, + 'post_author' => $user_id, + 'post_status' => 'publish', + 'post_type' => 'opalestate_agent', + 'post_date' => $post_date, + 'post_content' => wp_kses( $_POST[ $prefix . 'text' ], '

            ' ), + ]; + unset( $_POST[ $prefix . 'text' ] ); + + + if ( $post_id > 0 ) { + $post_id = wp_update_post( $data, true ); + } else { + $post_id = wp_insert_post( $data, true ); + } + + $post = get_post( $post_id ); + + if ( empty( $post->post_content ) || empty( $post->post_title ) || ! has_post_thumbnail( $post_id ) ) { + + $data['post_status'] = 'pending'; + $post_id = wp_update_post( $data, true ); + } + update_user_meta( $user_id, $prefix . 'related_id', $post_id ); + cmb2_get_metabox_form( $metaboxes[ $prefix . 'front' ], $post_id ); + + return $post_id; + } + + return false; + } + + public static function get_member_id() { + $user_id = get_current_user_id(); + + return get_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'related_id', true ); + } +} + +new OpalEstate_User(); diff --git a/inc/user/class-user-statistics.php b/inc/user/class-user-statistics.php new file mode 100755 index 00000000..cea527da --- /dev/null +++ b/inc/user/class-user-statistics.php @@ -0,0 +1,29 @@ +user_id = get_current_user_id(); + } + + public function get_count_properties() { + $query = Opalestate_Query::get_properties_by_user( array(), $this->user_id ); + return $query->found_posts; + } + + public function get_count_featured() { + $query = Opalestate_Query::get_properties_by_user( array( + 'featured' => 1 + ), $this->user_id ); + return $query->found_posts; + } + + public function get_count_pending_properties() { + $query = Opalestate_Query::get_properties_by_user( array( + 'post_status' => 'pending' + ), $this->user_id ); + return $query->found_posts; + } + + } +?> \ No newline at end of file diff --git a/inc/user/functions.php b/inc/user/functions.php new file mode 100755 index 00000000..b25eeecc --- /dev/null +++ b/inc/user/functions.php @@ -0,0 +1,261 @@ + 'submission_list') ); +} + +function opalestate_get_user_management_page_uri( $args = [] ) { + + global $opalestate_options; + + $uri = isset( $opalestate_options['user_management_page'] ) ? get_permalink( absint( $opalestate_options['user_management_page'] ) ) : get_bloginfo( 'url' ); + + if ( ! empty( $args ) ) { + // Check for backward compatibility + if ( is_string( $args ) ) { + $args = str_replace( '?', '', $args ); + } + $args = wp_parse_args( $args ); + $uri = add_query_arg( $args, $uri ); + } + + return apply_filters( 'opalestate_user_management_page_uri', $uri ); +} + +function opalestate_get_current_url( $args = [] ) { + global $wp; + if( isset($_GET['tab']) && $_GET['tab'] ) { + $args['tab'] = $_GET['tab']; + } + $current_url = home_url( add_query_arg( $args, $wp->request ) ); + return $current_url; +} + + +function opalestate_get_user_tab_uri( $tab ) { + $args['tab'] = $tab ; + return opalestate_get_current_url( $args ); +} + + + +function opalestate_management_show_content_page_tab() { + + $tab = isset($_GET['tab']) && $_GET['tab'] ? sanitize_text_field( $_GET['tab'] ): 'dashboard'; + + $fnc = 'opalestate_user_content_'.$tab.'_page'; + + $content = apply_filters( $fnc, '' ); + + if( $content ) { + echo $content; + } else { + if( function_exists( $fnc ) ) { + $fnc(); + } else { + opalestate_user_content_dashboard_page(); + } + } +} + +function opalestate_user_savedsearch_page( $args = [] ) { + + $uri = get_permalink( opalestate_get_option( 'saved_link_page', '/' ) ); + + if ( ! empty( $args ) ) { + // Check for backward compatibility + if ( is_string( $args ) ) { + $args = str_replace( '?', '', $args ); + } + $args = wp_parse_args( $args ); + $uri = add_query_arg( $args, $uri ); + } + + return $uri; +} + + +function opalestate_my_account_page( $id = false, $args = array() ) { + + $page = get_permalink( opalestate_get_option( 'user_myaccount_page', '/' ) ); + if ( $id ) { + $edit_page_id = opalestate_get_option( 'user_myaccount_page' ); + $page = $edit_page_id ? get_permalink( $edit_page_id ) : $page; + $page = add_query_arg( 'id', $id, $page ); + } + if( $args ){ + foreach( $args as $key => $value ) { + $page = add_query_arg( $key, $value, $page ); + } + } + return $page; +} + +function opalestate_submssion_page( $id = false, $args = array() ) { + + + $page = get_permalink( opalestate_get_option( 'submission_page', '/' ) ); + if ( $id ) { + $edit_page_id = opalestate_get_option( 'submission_edit_page' ); + $page = $edit_page_id ? get_permalink( $edit_page_id ) : $page; + $page = add_query_arg( 'id', $id, $page ); + } + if( $args ){ + foreach( $args as $key => $value ) { + $page = add_query_arg( $key, $value, $page ); + } + } + return $page; +} + +function opalestate_management_user_menu() { +} + + +function opalestate_management_user_menu_tabs() { + + global $opalestate_options; + $menu = []; + + $menu['dashboard'] = [ + 'icon' => 'fa fa-user', + 'link' => 'dashboard', + 'title' => esc_html__( 'Dashboard', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['profile_page'] ) ? $opalestate_options['profile_page'] : 0, + ]; + + $menu['profile'] = [ + 'icon' => 'fa fa-user', + 'link' => 'profile', + 'title' => esc_html__( 'Personal Information', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['profile_page'] ) ? $opalestate_options['profile_page'] : 0, + ]; + + $menu['favorite'] = [ + 'icon' => 'fa fa-heart', + 'link' => 'favorite', + 'title' => esc_html__( 'Favorite', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['favorite_page'] ) ? $opalestate_options['favorite_page'] : 0, + ]; + + $menu['reviews'] = [ + 'icon' => 'fa fa-star', + 'link' => 'reviews', + 'title' => esc_html__( 'Reviews', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['reviews_page'] ) ? $opalestate_options['reviews_page'] : 0, + ]; + + $menu['reviews'] = [ + 'icon' => 'fa fa-star', + 'link' => 'reviews', + 'title' => esc_html__( 'Reviews', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['reviews_page'] ) ? $opalestate_options['reviews_page'] : 0, + ]; + + if( opalestate_get_option('message_log') ) { + $menu['messages'] = [ + 'icon' => 'fa fa-envelope', + 'link' => 'messages', + 'title' => esc_html__( 'Messages', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['reviews_page'] ) ? $opalestate_options['reviews_page'] : 0, + ]; + } + + $menu['submission'] = [ + 'icon' => 'fa fa-upload', + 'link' => 'submission', + 'title' => esc_html__( 'Submit Property', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['submission_page'] ) ? $opalestate_options['submission_page'] : 0, + ]; + + $menu['myproperties'] = [ + 'icon' => 'fa fa-building', + 'link' => 'submission_list', + 'title' => esc_html__( 'My Properties', 'opalestate-pro' ), + 'id' => isset( $opalestate_options['submission_list_page'] ) ? $opalestate_options['submission_list_page'] : 0, + ]; + + $menu = apply_filters( 'opalestate_management_user_menu', $menu ); + + $output = '

            '; + + echo $output; +} + +function opalestate_user_content_dashboard_page(){ + echo opalestate_load_template_path( 'user/dashboard' ); +} + +if ( ! function_exists( 'opalestate_create_user' ) ) { + /** + * create new wp user + */ + function opalestate_create_user( $credentials = [] ) { + $cred = wp_parse_args( $credentials, [ + 'user_login' => '', + 'user_email' => '', + 'user_pass' => '', + 'first_name' => '', + 'last_name' => '', + ] ); + + /* sanitize user email */ + $user_email = sanitize_email( $cred['user_email'] ); + if ( email_exists( $user_email ) ) { + return new WP_Error( 'email-exists', esc_html__( 'An account is already registered with your email address. Please login.', 'opalestate-pro' ) ); + } + + $username = sanitize_user( $cred['user_login'] ); + if ( ! $username || ! validate_username( $username ) ) { + return new WP_Error( 'username-invalid', esc_html__( 'Please enter a valid account username.', 'opalestate-pro' ) ); + } + /* if username exists */ + if ( username_exists( $username ) ) { + return new WP_Error( 'username-exists', esc_html__( 'Username is already exists.', 'opalestate-pro' ) ); + } + + /* password empty */ + if ( ! $cred['user_pass'] ) { + return new WP_Error( 'password-empty', esc_html__( 'Password is requried.', 'opalestate-pro' ) ); + } else { + $password = $cred['user_pass']; + } + + $user_data = apply_filters( 'opalestate_create_user_data', [ + 'user_login' => $username, + 'user_pass' => $password, + 'user_email' => $user_email, + ] ); + + /* insert new wp user */ + $user_id = wp_insert_user( $user_data ); + if ( is_wp_error( $user_id ) ) { + return new WP_Error( 'user-create-failed', $user_id->get_error_message() ); + } + + /* allow hook like insert user meta. create new post type agent in opalmembership */ + do_action( 'opalmembership_create_new_user_successfully', $user_id, $user_data, $cred ); + + return $user_id; + } +} + +?> \ No newline at end of file diff --git a/inc/vendors/.DS_Store b/inc/vendors/.DS_Store new file mode 100644 index 00000000..077103fc Binary files /dev/null and b/inc/vendors/.DS_Store differ diff --git a/inc/vendors/cmb2-plugins/.DS_Store b/inc/vendors/cmb2-plugins/.DS_Store new file mode 100644 index 00000000..4c51aaa1 Binary files /dev/null and b/inc/vendors/cmb2-plugins/.DS_Store differ diff --git a/inc/vendors/cmb2-plugins/CMB2-Switch-Button/README.md b/inc/vendors/cmb2-plugins/CMB2-Switch-Button/README.md new file mode 100755 index 00000000..ebb9756c --- /dev/null +++ b/inc/vendors/cmb2-plugins/CMB2-Switch-Button/README.md @@ -0,0 +1,52 @@ +# CMB2 Switch Button Field Type +Custom Switch Button field type for CMB2 Metabox for WordPress. + +## Installation +You can install it as a plugin, or include the main file into your theme or plugin folder. + +## Usage: + +```php +add_action( 'cmb2_admin_init', 'create_your_metabox' ); +if(!function_exists('create_your_metabox')){ + function create_your_metabox(){ + $prefix = '_slug_'; + + $cmb2_metabox = new_cmb2_box( array( + 'id' => $prefix . 'test_metabox', + 'title' => esc_html__( 'Test Metabox', 'tmv' ), + 'object_types' => array( 'page'), // Post type + 'priority' => 'high', + 'context' => 'normal', + ) ); + + $cmb2_metabox->add_field( array( + 'name' => esc_html__( 'Dynamically Load', 'text-domain' ), + 'id' => $prefix . 'metabox_id', + 'desc' => esc_html__('','text-domain'), + 'type' => 'switch', + 'default' => 'on' //If it's checked by default + ) ); + } +} +``` + +* The usage in the template as same as CMB2 checkbox field type: + +```php +$test_meta = get_post_meta($post->ID, '_slug_metabox_id', true); + +if($test_meta){ + //Do something when it's checked; +} +``` + + +## Screenshot: + + + +## Follow us: +- Website: https://www.themevan.com +- Facebook: https://facebook.com/ThemeVan +- Twitter: https://twitter.com/ThemeVan diff --git a/inc/vendors/cmb2-plugins/CMB2-Switch-Button/cmb2-switch-button.php b/inc/vendors/cmb2-plugins/CMB2-Switch-Button/cmb2-switch-button.php new file mode 100755 index 00000000..d327b7f6 --- /dev/null +++ b/inc/vendors/cmb2-plugins/CMB2-Switch-Button/cmb2-switch-button.php @@ -0,0 +1,105 @@ +_name(); + + $args = array( + 'type' => 'checkbox', + 'id' => $field_name, + 'name' => $field_name, + 'desc' => '', + 'value' => 'on', + ); + if( $escaped_value == 'on' || $escaped_value == 1 ){ + $args['checked'] = 'checked'; + } + + echo ''; + $field_type_object->_desc( true, true ); + } + + public function admin_head() { + ?> + + .arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px} +/*# sourceMappingURL=popover-dee30a8acd.css.map */ diff --git a/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/cmb2-fixes.css b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/cmb2-fixes.css new file mode 100755 index 00000000..becfc731 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/cmb2-fixes.css @@ -0,0 +1,3 @@ +.cmb2-wrap .iconpicker * { + box-sizing: content-box !important; +} diff --git a/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/font-awesome.min.css b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/font-awesome.min.css new file mode 100755 index 00000000..540440ce --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/fontawesome-iconpicker.min.css b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/fontawesome-iconpicker.min.css new file mode 100755 index 00000000..833fddba --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/css/fontawesome-iconpicker.min.css @@ -0,0 +1,9 @@ +/*! + * Font Awesome Icon Picker + * https://itsjavi.com/fontawesome-iconpicker/ + * + * Originally written by (c) 2016 Javi Aguilar + * Licensed under the MIT License + * https://github.com/itsjavi/fontawesome-iconpicker/blob/master/LICENSE + * + */.iconpicker-popover.popover{position:absolute;top:0;left:0;display:none;max-width:none;padding:1px;text-align:left;width:216px;background:#f7f7f7}.iconpicker-popover.popover.top,.iconpicker-popover.popover.topLeftCorner,.iconpicker-popover.popover.topLeft,.iconpicker-popover.popover.topRight,.iconpicker-popover.popover.topRightCorner{margin-top:-10px}.iconpicker-popover.popover.right,.iconpicker-popover.popover.rightTop,.iconpicker-popover.popover.rightBottom{margin-left:10px}.iconpicker-popover.popover.bottom,.iconpicker-popover.popover.bottomRightCorner,.iconpicker-popover.popover.bottomRight,.iconpicker-popover.popover.bottomLeft,.iconpicker-popover.popover.bottomLeftCorner{margin-top:10px}.iconpicker-popover.popover.left,.iconpicker-popover.popover.leftBottom,.iconpicker-popover.popover.leftTop{margin-left:-10px}.iconpicker-popover.popover.inline{margin:0 0 12px 0;position:relative;display:inline-block;opacity:1;top:auto;left:auto;bottom:auto;right:auto;max-width:100%;box-shadow:none;z-index:auto;vertical-align:top}.iconpicker-popover.popover.inline>.arrow{display:none}.dropdown-menu .iconpicker-popover.inline{margin:0;border:none}.dropdown-menu.iconpicker-container{padding:0}.iconpicker-popover.popover .popover-title{padding:12px;font-size:13px;line-height:15px;border-bottom:1px solid #ebebeb;background-color:#f7f7f7}.iconpicker-popover.popover .popover-title input[type=search].iconpicker-search{margin:0 0 2px 0}.iconpicker-popover.popover .popover-title-text~input[type=search].iconpicker-search{margin-top:12px}.iconpicker-popover.popover .popover-content{padding:0px;text-align:center}.iconpicker-popover .popover-footer{float:none;clear:both;padding:12px;text-align:right;margin:0;border-top:1px solid #ebebeb;background-color:#f7f7f7}.iconpicker-popover .popover-footer:before,.iconpicker-popover .popover-footer:after{content:" ";display:table}.iconpicker-popover .popover-footer:after{clear:both}.iconpicker-popover .popover-footer .iconpicker-btn{margin-left:10px}.iconpicker-popover .popover-footer input[type=search].iconpicker-search{margin-bottom:12px}.iconpicker-popover.popover>.arrow,.iconpicker-popover.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.iconpicker-popover.popover>.arrow{border-width:11px}.iconpicker-popover.popover>.arrow:after{border-width:10px;content:""}.iconpicker-popover.popover.top>.arrow,.iconpicker-popover.popover.topLeft>.arrow,.iconpicker-popover.popover.topRight>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.iconpicker-popover.popover.top>.arrow:after,.iconpicker-popover.popover.topLeft>.arrow:after,.iconpicker-popover.popover.topRight>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.iconpicker-popover.popover.topLeft>.arrow{left:8px;margin-left:0}.iconpicker-popover.popover.topRight>.arrow{left:auto;right:8px;margin-left:0}.iconpicker-popover.popover.right>.arrow,.iconpicker-popover.popover.rightTop>.arrow,.iconpicker-popover.popover.rightBottom>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.iconpicker-popover.popover.right>.arrow:after,.iconpicker-popover.popover.rightTop>.arrow:after,.iconpicker-popover.popover.rightBottom>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.iconpicker-popover.popover.rightTop>.arrow{top:auto;bottom:8px;margin-top:0}.iconpicker-popover.popover.rightBottom>.arrow{top:8px;margin-top:0}.iconpicker-popover.popover.bottom>.arrow,.iconpicker-popover.popover.bottomRight>.arrow,.iconpicker-popover.popover.bottomLeft>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.iconpicker-popover.popover.bottom>.arrow:after,.iconpicker-popover.popover.bottomRight>.arrow:after,.iconpicker-popover.popover.bottomLeft>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.iconpicker-popover.popover.bottomLeft>.arrow{left:8px;margin-left:0}.iconpicker-popover.popover.bottomRight>.arrow{left:auto;right:8px;margin-left:0}.iconpicker-popover.popover.left>.arrow,.iconpicker-popover.popover.leftBottom>.arrow,.iconpicker-popover.popover.leftTop>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.iconpicker-popover.popover.left>.arrow:after,.iconpicker-popover.popover.leftBottom>.arrow:after,.iconpicker-popover.popover.leftTop>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.iconpicker-popover.popover.leftBottom>.arrow{top:8px;margin-top:0}.iconpicker-popover.popover.leftTop>.arrow{top:auto;bottom:8px;margin-top:0}.iconpicker{position:relative;text-align:left;text-shadow:none;line-height:0;display:block;margin:0;overflow:hidden}.iconpicker *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;position:relative}.iconpicker:before,.iconpicker:after{content:" ";display:table}.iconpicker:after{clear:both}.iconpicker .iconpicker-items{position:relative;clear:both;float:none;padding:12px 0 0 12px;background:#fff;margin:0;overflow:hidden;overflow-y:auto;min-height:49px;max-height:246px}.iconpicker .iconpicker-items:before,.iconpicker .iconpicker-items:after{content:" ";display:table}.iconpicker .iconpicker-items:after{clear:both}.iconpicker .iconpicker-item{float:left;width:14px;height:14px;padding:12px;margin:0 12px 12px 0;text-align:center;cursor:pointer;border-radius:3px;font-size:14px;box-shadow:0 0 0 1px #ddd;color:inherit}.iconpicker .iconpicker-item:hover:not(.iconpicker-selected){background-color:#eee}.iconpicker .iconpicker-item.iconpicker-selected{box-shadow:none;color:#fff}.iconpicker-component{cursor:pointer} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/js/fontawesome-iconpicker.min.js b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/js/fontawesome-iconpicker.min.js new file mode 100755 index 00000000..2d3eb89d --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/js/fontawesome-iconpicker.min.js @@ -0,0 +1 @@ +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){a.ui=a.ui||{};a.ui.version="1.12.1";!function(){function b(a,b,c){return[parseFloat(a[0])*(l.test(a[0])?b/100:1),parseFloat(a[1])*(l.test(a[1])?c/100:1)]}function c(b,c){return parseInt(a.css(b,c),10)||0}function d(b){var c=b[0];return 9===c.nodeType?{width:b.width(),height:b.height(),offset:{top:0,left:0}}:a.isWindow(c)?{width:b.width(),height:b.height(),offset:{top:b.scrollTop(),left:b.scrollLeft()}}:c.preventDefault?{width:0,height:0,offset:{top:c.pageY,left:c.pageX}}:{width:b.outerWidth(),height:b.outerHeight(),offset:b.offset()}}var e,f=Math.max,g=Math.abs,h=/left|center|right/,i=/top|center|bottom/,j=/[\+\-]\d+(\.[\d]+)?%?/,k=/^\w+/,l=/%$/,m=a.fn.pos;a.pos={scrollbarWidth:function(){if(void 0!==e)return e;var b,c,d=a("
            "),f=d.children()[0];return a("body").append(d),b=f.offsetWidth,d.css("overflow","scroll"),c=f.offsetWidth,b===c&&(c=d[0].clientWidth),d.remove(),e=b-c},getScrollInfo:function(b){var c=b.isWindow||b.isDocument?"":b.element.css("overflow-x"),d=b.isWindow||b.isDocument?"":b.element.css("overflow-y"),e="scroll"===c||"auto"===c&&b.width0?"right":"center",vertical:h<0?"top":d>0?"bottom":"middle"};nf(g(d),g(h))?l.important="horizontal":l.important="vertical",e.using.call(this,a,l)}),i.offset(a.extend(z,{using:h}))})},a.ui.pos={_trigger:function(a,b,c,d){b.elem&&b.elem.trigger({type:c,position:a,positionData:b,triggered:d})},fit:{left:function(b,c){a.ui.pos._trigger(b,c,"posCollide","fitLeft");var d,e=c.within,g=e.isWindow?e.scrollLeft:e.offset.left,h=e.width,i=b.left-c.collisionPosition.marginLeft,j=g-i,k=i+c.collisionWidth-h-g;c.collisionWidth>h?j>0&&k<=0?(d=b.left+j+c.collisionWidth-h-g,b.left+=j-d):b.left=k>0&&j<=0?g:j>k?g+h-c.collisionWidth:g:j>0?b.left+=j:k>0?b.left-=k:b.left=f(b.left-i,b.left),a.ui.pos._trigger(b,c,"posCollided","fitLeft")},top:function(b,c){a.ui.pos._trigger(b,c,"posCollide","fitTop");var d,e=c.within,g=e.isWindow?e.scrollTop:e.offset.top,h=c.within.height,i=b.top-c.collisionPosition.marginTop,j=g-i,k=i+c.collisionHeight-h-g;c.collisionHeight>h?j>0&&k<=0?(d=b.top+j+c.collisionHeight-h-g,b.top+=j-d):b.top=k>0&&j<=0?g:j>k?g+h-c.collisionHeight:g:j>0?b.top+=j:k>0?b.top-=k:b.top=f(b.top-i,b.top),a.ui.pos._trigger(b,c,"posCollided","fitTop")}},flip:{left:function(b,c){a.ui.pos._trigger(b,c,"posCollide","flipLeft");var d,e,f=c.within,h=f.offset.left+f.scrollLeft,i=f.width,j=f.isWindow?f.scrollLeft:f.offset.left,k=b.left-c.collisionPosition.marginLeft,l=k-j,m=k+c.collisionWidth-i-j,n="left"===c.my[0]?-c.elemWidth:"right"===c.my[0]?c.elemWidth:0,o="left"===c.at[0]?c.targetWidth:"right"===c.at[0]?-c.targetWidth:0,p=-2*c.offset[0];l<0?((d=b.left+n+o+p+c.collisionWidth-i-h)<0||d0&&((e=b.left-c.collisionPosition.marginLeft+n+o+p-j)>0||g(e)0&&((d=b.top-c.collisionPosition.marginTop+o+p+q-j)>0||g(d)10&&e<11,b.innerHTML="",c.removeChild(b)}()}();a.ui.position}),function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):window.jQuery&&!window.jQuery.fn.iconpicker&&a(window.jQuery)}(function(a){"use strict";var b={isEmpty:function(a){return!1===a||""===a||null===a||void 0===a},isEmptyObject:function(a){return!0===this.isEmpty(a)||0===a.length},isElement:function(b){return a(b).length>0},isString:function(a){return"string"==typeof a||a instanceof String},isArray:function(b){return a.isArray(b)},inArray:function(b,c){return-1!==a.inArray(b,c)},throwError:function(a){throw"Font Awesome Icon Picker Exception: "+a}},c=function(d,e){this._id=c._idCounter++,this.element=a(d).addClass("iconpicker-element"),this._trigger("iconpickerCreate"),this.options=a.extend({},c.defaultOptions,this.element.data(),e),this.options.templates=a.extend({},c.defaultOptions.templates,this.options.templates),this.options.originalPlacement=this.options.placement,this.container=!!b.isElement(this.options.container)&&a(this.options.container),!1===this.container&&(this.element.is(".dropdown-toggle")?this.container=a("~ .dropdown-menu:first",this.element):this.container=this.element.is("input,textarea,button,.btn")?this.element.parent():this.element),this.container.addClass("iconpicker-container"),this.isDropdownMenu()&&(this.options.templates.search=!1,this.options.templates.buttons=!1,this.options.placement="inline"),this.input=!!this.element.is("input,textarea")&&this.element.addClass("iconpicker-input"),!1===this.input&&(this.input=this.container.find(this.options.input),this.input.is("input,textarea")||(this.input=!1)),this.component=this.isDropdownMenu()?this.container.parent().find(this.options.component):this.container.find(this.options.component),0===this.component.length?this.component=!1:this.component.find("i").addClass("iconpicker-component"),this._createPopover(),this._createIconpicker(),0===this.getAcceptButton().length&&(this.options.mustAccept=!1),this.isInputGroup()?this.container.parent().append(this.popover):this.container.append(this.popover),this._bindElementEvents(),this._bindWindowEvents(),this.update(this.options.selected),this.isInline()&&this.show(),this._trigger("iconpickerCreated")};c._idCounter=0,c.defaultOptions={title:!1,selected:!1,defaultValue:!1,placement:"bottom",collision:"none",animation:!0,hideOnSelect:!1,showFooter:!1,searchInFooter:!1,mustAccept:!1,selectedCustomClass:"bg-primary",icons:[],fullClassFormatter:function(a){return"fa "+a},input:"input,.iconpicker-input",inputSearch:!1,container:!1,component:".input-group-addon,.iconpicker-component",templates:{popover:'
            ',footer:'',buttons:' ',search:'',iconpicker:'
            ',iconpickerItem:''}},c.batch=function(b,c){var d=Array.prototype.slice.call(arguments,2);return a(b).each(function(){var b=a(this).data("iconpicker");b&&b[c].apply(b,d)})},c.prototype={constructor:c,options:{},_id:0,_trigger:function(b,c){c=c||{},this.element.trigger(a.extend({type:b,iconpickerInstance:this},c))},_createPopover:function(){this.popover=a(this.options.templates.popover);var c=this.popover.find(".popover-title");if(this.options.title&&c.append(a('
            '+this.options.title+"
            ")),this.hasSeparatedSearchInput()&&!this.options.searchInFooter?c.append(this.options.templates.search):this.options.title||c.remove(),this.options.showFooter&&!b.isEmpty(this.options.templates.footer)){var d=a(this.options.templates.footer);this.hasSeparatedSearchInput()&&this.options.searchInFooter&&d.append(a(this.options.templates.search)),b.isEmpty(this.options.templates.buttons)||d.append(a(this.options.templates.buttons)),this.popover.append(d)}return!0===this.options.animation&&this.popover.addClass("fade"),this.popover},_createIconpicker:function(){var b=this;this.iconpicker=a(this.options.templates.iconpicker);var c=function(c){var d=a(this);return d.is("i")&&(d=d.parent()),b._trigger("iconpickerSelect",{iconpickerItem:d,iconpickerValue:b.iconpickerValue}),!1===b.options.mustAccept?(b.update(d.data("iconpickerValue")),b._trigger("iconpickerSelected",{iconpickerItem:this,iconpickerValue:b.iconpickerValue})):b.update(d.data("iconpickerValue"),!0),b.options.hideOnSelect&&!1===b.options.mustAccept&&b.hide(),c.preventDefault(),!1};for(var d in this.options.icons)if("string"==typeof this.options.icons[d]){var e=a(this.options.templates.iconpickerItem);e.find("i").addClass(this.options.fullClassFormatter(this.options.icons[d])),e.data("iconpickerValue",this.options.icons[d]).on("click.iconpicker",c),this.iconpicker.find(".iconpicker-items").append(e.attr("title","."+this.options.icons[d]))}return this.popover.find(".popover-content").append(this.iconpicker),this.iconpicker},_isEventInsideIconpicker:function(b){var c=a(b.target);return!((!c.hasClass("iconpicker-element")||c.hasClass("iconpicker-element")&&!c.is(this.element))&&0===c.parents(".iconpicker-popover").length)},_bindElementEvents:function(){var c=this;this.getSearchInput().on("keyup.iconpicker",function(){c.filter(a(this).val().toLowerCase())}),this.getAcceptButton().on("click.iconpicker",function(){var a=c.iconpicker.find(".iconpicker-selected").get(0);c.update(c.iconpickerValue),c._trigger("iconpickerSelected",{iconpickerItem:a,iconpickerValue:c.iconpickerValue}),c.isInline()||c.hide()}),this.getCancelButton().on("click.iconpicker",function(){c.isInline()||c.hide()}),this.element.on("focus.iconpicker",function(a){c.show(),a.stopPropagation()}),this.hasComponent()&&this.component.on("click.iconpicker",function(){c.toggle()}),this.hasInput()&&this.input.on("keyup.iconpicker",function(d){b.inArray(d.keyCode,[38,40,37,39,16,17,18,9,8,91,93,20,46,186,190,46,78,188,44,86])?c._updateFormGroupStatus(!1!==c.getValid(this.value)):c.update(),!0===c.options.inputSearch&&c.filter(a(this).val().toLowerCase())})},_bindWindowEvents:function(){var b=a(window.document),c=this,d=".iconpicker.inst"+this._id;return a(window).on("resize.iconpicker"+d+" orientationchange.iconpicker"+d,function(a){c.popover.hasClass("in")&&c.updatePlacement()}),c.isInline()||b.on("mouseup"+d,function(a){return c._isEventInsideIconpicker(a)||c.isInline()||c.hide(),a.stopPropagation(),a.preventDefault(),!1}),!1},_unbindElementEvents:function(){this.popover.off(".iconpicker"),this.element.off(".iconpicker"),this.hasInput()&&this.input.off(".iconpicker"),this.hasComponent()&&this.component.off(".iconpicker"),this.hasContainer()&&this.container.off(".iconpicker")},_unbindWindowEvents:function(){a(window).off(".iconpicker.inst"+this._id),a(window.document).off(".iconpicker.inst"+this._id)},updatePlacement:function(b,c){b=b||this.options.placement,this.options.placement=b,c=c||this.options.collision,c=!0===c?"flip":c;var d={at:"right bottom",my:"right top",of:this.hasInput()&&!this.isInputGroup()?this.input:this.container,collision:!0===c?"flip":c,within:window};if(this.popover.removeClass("inline topLeftCorner topLeft top topRight topRightCorner rightTop right rightBottom bottomRight bottomRightCorner bottom bottomLeft bottomLeftCorner leftBottom left leftTop"),"object"==typeof b)return this.popover.pos(a.extend({},d,b));switch(b){case"inline":d=!1;break;case"topLeftCorner":d.my="right bottom",d.at="left top";break;case"topLeft":d.my="left bottom",d.at="left top";break;case"top":d.my="center bottom",d.at="center top";break;case"topRight":d.my="right bottom",d.at="right top";break;case"topRightCorner":d.my="left bottom",d.at="right top";break;case"rightTop":d.my="left bottom",d.at="right center";break;case"right":d.my="left center",d.at="right center";break;case"rightBottom":d.my="left top",d.at="right center";break;case"bottomRightCorner":d.my="left top",d.at="right bottom";break;case"bottomRight":d.my="right top",d.at="right bottom";break;case"bottom":d.my="center top",d.at="center bottom";break;case"bottomLeft":d.my="left top",d.at="left bottom";break;case"bottomLeftCorner":d.my="right top",d.at="left bottom";break;case"leftBottom":d.my="right top",d.at="left center";break;case"left":d.my="right center",d.at="left center";break;case"leftTop":d.my="right bottom",d.at="left center";break;default:return!1}return this.popover.css({display:"inline"===this.options.placement?"":"block"}),!1!==d?this.popover.pos(d).css("maxWidth",a(window).width()-this.container.offset().left-5):this.popover.css({top:"auto",right:"auto",bottom:"auto",left:"auto",maxWidth:"none"}),this.popover.addClass(this.options.placement),!0},_updateComponents:function(){if(this.iconpicker.find(".iconpicker-item.iconpicker-selected").removeClass("iconpicker-selected "+this.options.selectedCustomClass),this.iconpickerValue&&this.iconpicker.find("."+this.options.fullClassFormatter(this.iconpickerValue).replace(/ /g,".")).parent().addClass("iconpicker-selected "+this.options.selectedCustomClass),this.hasComponent()){var a=this.component.find("i");a.length>0?a.attr("class",this.options.fullClassFormatter(this.iconpickerValue)):this.component.html(this.getHtml())}},_updateFormGroupStatus:function(a){return!!this.hasInput()&&(!1!==a?this.input.parents(".form-group:first").removeClass("has-error"):this.input.parents(".form-group:first").addClass("has-error"),!0)},getValid:function(c){b.isString(c)||(c="");var d=""===c;return c=a.trim(c),!(!b.inArray(c,this.options.icons)&&!d)&&c},setValue:function(a){var b=this.getValid(a);return!1!==b?(this.iconpickerValue=b,this._trigger("iconpickerSetValue",{iconpickerValue:b}),this.iconpickerValue):(this._trigger("iconpickerInvalid",{iconpickerValue:a}),!1)},getHtml:function(){return''},setSourceValue:function(a){return a=this.setValue(a),!1!==a&&""!==a&&(this.hasInput()?this.input.val(this.iconpickerValue):this.element.data("iconpickerValue",this.iconpickerValue),this._trigger("iconpickerSetSourceValue",{iconpickerValue:a})),a},getSourceValue:function(a){a=a||this.options.defaultValue;var b=a;return b=this.hasInput()?this.input.val():this.element.data("iconpickerValue"),void 0!==b&&""!==b&&null!==b&&!1!==b||(b=a),b},hasInput:function(){return!1!==this.input},isInputSearch:function(){return this.hasInput()&&!0===this.options.inputSearch},isInputGroup:function(){return this.container.is(".input-group")},isDropdownMenu:function(){return this.container.is(".dropdown-menu")},hasSeparatedSearchInput:function(){return!1!==this.options.templates.search&&!this.isInputSearch()},hasComponent:function(){return!1!==this.component},hasContainer:function(){return!1!==this.container},getAcceptButton:function(){return this.popover.find(".iconpicker-btn-accept")},getCancelButton:function(){return this.popover.find(".iconpicker-btn-cancel")},getSearchInput:function(){return this.popover.find(".iconpicker-search")},filter:function(c){if(b.isEmpty(c))return this.iconpicker.find(".iconpicker-item").show(),a(!1);var d=[];return this.iconpicker.find(".iconpicker-item").each(function(){var b=a(this),e=b.attr("title").toLowerCase(),f=!1;try{f=new RegExp(c,"g")}catch(a){f=!1}!1!==f&&e.match(f)?(d.push(b),b.show()):b.hide()}),d},show:function(){if(this.popover.hasClass("in"))return!1;a.iconpicker.batch(a(".iconpicker-popover.in:not(.inline)").not(this.popover),"hide"),this._trigger("iconpickerShow"),this.updatePlacement(),this.popover.addClass("in"),setTimeout(a.proxy(function(){this.popover.css("display",this.isInline()?"":"block"),this._trigger("iconpickerShown")},this),this.options.animation?300:1)},hide:function(){if(!this.popover.hasClass("in"))return!1;this._trigger("iconpickerHide"),this.popover.removeClass("in"),setTimeout(a.proxy(function(){this.popover.css("display","none"),this.getSearchInput().val(""),this.filter(""),this._trigger("iconpickerHidden")},this),this.options.animation?300:1)},toggle:function(){this.popover.is(":visible")?this.hide():this.show(!0)},update:function(a,b){return a=a||this.getSourceValue(this.iconpickerValue),this._trigger("iconpickerUpdate"),!0===b?a=this.setValue(a):(a=this.setSourceValue(a),this._updateFormGroupStatus(!1!==a)),!1!==a&&this._updateComponents(),this._trigger("iconpickerUpdated"),a},destroy:function(){this._trigger("iconpickerDestroy"),this.element.removeData("iconpicker").removeData("iconpickerValue").removeClass("iconpicker-element"),this._unbindElementEvents(),this._unbindWindowEvents(),a(this.popover).remove(),this._trigger("iconpickerDestroyed")},disable:function(){return!!this.hasInput()&&(this.input.prop("disabled",!0),!0)},enable:function(){return!!this.hasInput()&&(this.input.prop("disabled",!1),!0)},isDisabled:function(){return!!this.hasInput()&&!0===this.input.prop("disabled")},isInline:function(){return"inline"===this.options.placement||this.popover.hasClass("inline")}},a.iconpicker=c,a.fn.iconpicker=function(b){return this.each(function(){var d=a(this);d.data("iconpicker")||d.data("iconpicker",new c(this,"object"==typeof b?b:{}))})},c.defaultOptions.icons=["fa-500px","fa-address-book","fa-address-book-o","fa-address-card","fa-address-card-o","fa-adjust","fa-adn","fa-align-center","fa-align-justify","fa-align-left","fa-align-right","fa-amazon","fa-ambulance","fa-american-sign-language-interpreting","fa-anchor","fa-android","fa-angellist","fa-angle-double-down","fa-angle-double-left","fa-angle-double-right","fa-angle-double-up","fa-angle-down","fa-angle-left","fa-angle-right","fa-angle-up","fa-apple","fa-archive","fa-area-chart","fa-arrow-circle-down","fa-arrow-circle-left","fa-arrow-circle-o-down","fa-arrow-circle-o-left","fa-arrow-circle-o-right","fa-arrow-circle-o-up","fa-arrow-circle-right","fa-arrow-circle-up","fa-arrow-down","fa-arrow-left","fa-arrow-right","fa-arrow-up","fa-arrows","fa-arrows-alt","fa-arrows-h","fa-arrows-v","fa-asl-interpreting","fa-assistive-listening-systems","fa-asterisk","fa-at","fa-audio-description","fa-automobile","fa-backward","fa-balance-scale","fa-ban","fa-bandcamp","fa-bank","fa-bar-chart","fa-bar-chart-o","fa-barcode","fa-bars","fa-bath","fa-bathtub","fa-battery","fa-battery-0","fa-battery-1","fa-battery-2","fa-battery-3","fa-battery-4","fa-battery-empty","fa-battery-full","fa-battery-half","fa-battery-quarter","fa-battery-three-quarters","fa-bed","fa-beer","fa-behance","fa-behance-square","fa-bell","fa-bell-o","fa-bell-slash","fa-bell-slash-o","fa-bicycle","fa-binoculars","fa-birthday-cake","fa-bitbucket","fa-bitbucket-square","fa-bitcoin","fa-black-tie","fa-blind","fa-bluetooth","fa-bluetooth-b","fa-bold","fa-bolt","fa-bomb","fa-book","fa-bookmark","fa-bookmark-o","fa-braille","fa-briefcase","fa-btc","fa-bug","fa-building","fa-building-o","fa-bullhorn","fa-bullseye","fa-bus","fa-buysellads","fa-cab","fa-calculator","fa-calendar","fa-calendar-check-o","fa-calendar-minus-o","fa-calendar-o","fa-calendar-plus-o","fa-calendar-times-o","fa-camera","fa-camera-retro","fa-car","fa-caret-down","fa-caret-left","fa-caret-right","fa-caret-square-o-down","fa-caret-square-o-left","fa-caret-square-o-right","fa-caret-square-o-up","fa-caret-up","fa-cart-arrow-down","fa-cart-plus","fa-cc","fa-cc-amex","fa-cc-diners-club","fa-cc-discover","fa-cc-jcb","fa-cc-mastercard","fa-cc-paypal","fa-cc-stripe","fa-cc-visa","fa-certificate","fa-chain","fa-chain-broken","fa-check","fa-check-circle","fa-check-circle-o","fa-check-square","fa-check-square-o","fa-chevron-circle-down","fa-chevron-circle-left","fa-chevron-circle-right","fa-chevron-circle-up","fa-chevron-down","fa-chevron-left","fa-chevron-right","fa-chevron-up","fa-child","fa-chrome","fa-circle","fa-circle-o","fa-circle-o-notch","fa-circle-thin","fa-clipboard","fa-clock-o","fa-clone","fa-close","fa-cloud","fa-cloud-download","fa-cloud-upload","fa-cny","fa-code","fa-code-fork","fa-codepen","fa-codiepie","fa-coffee","fa-cog","fa-cogs","fa-columns","fa-comment","fa-comment-o","fa-commenting","fa-commenting-o","fa-comments","fa-comments-o","fa-compass","fa-compress","fa-connectdevelop","fa-contao","fa-copy","fa-copyright","fa-creative-commons","fa-credit-card","fa-credit-card-alt","fa-crop","fa-crosshairs","fa-css3","fa-cube","fa-cubes","fa-cut","fa-cutlery","fa-dashboard","fa-dashcube","fa-database","fa-deaf","fa-deafness","fa-dedent","fa-delicious","fa-desktop","fa-deviantart","fa-diamond","fa-digg","fa-dollar","fa-dot-circle-o","fa-download","fa-dribbble","fa-drivers-license","fa-drivers-license-o","fa-dropbox","fa-drupal","fa-edge","fa-edit","fa-eercast","fa-eject","fa-ellipsis-h","fa-ellipsis-v","fa-empire","fa-envelope","fa-envelope-o","fa-envelope-open","fa-envelope-open-o","fa-envelope-square","fa-envira","fa-eraser","fa-etsy","fa-eur","fa-euro","fa-exchange","fa-exclamation","fa-exclamation-circle","fa-exclamation-triangle","fa-expand","fa-expeditedssl","fa-external-link","fa-external-link-square","fa-eye","fa-eye-slash","fa-eyedropper","fa-fa","fa-facebook","fa-facebook-f","fa-facebook-official","fa-facebook-square","fa-fast-backward","fa-fast-forward","fa-fax","fa-feed","fa-female","fa-fighter-jet","fa-file","fa-file-archive-o","fa-file-audio-o","fa-file-code-o","fa-file-excel-o","fa-file-image-o","fa-file-movie-o","fa-file-o","fa-file-pdf-o","fa-file-photo-o","fa-file-picture-o","fa-file-powerpoint-o","fa-file-sound-o","fa-file-text","fa-file-text-o","fa-file-video-o","fa-file-word-o","fa-file-zip-o","fa-files-o","fa-film","fa-filter","fa-fire","fa-fire-extinguisher","fa-firefox","fa-first-order","fa-flag","fa-flag-checkered","fa-flag-o","fa-flash","fa-flask","fa-flickr","fa-floppy-o","fa-folder","fa-folder-o","fa-folder-open","fa-folder-open-o","fa-font","fa-font-awesome","fa-fonticons","fa-fort-awesome","fa-forumbee","fa-forward","fa-foursquare","fa-free-code-camp","fa-frown-o","fa-futbol-o","fa-gamepad","fa-gavel","fa-gbp","fa-ge","fa-gear","fa-gears","fa-genderless","fa-get-pocket","fa-gg","fa-gg-circle","fa-gift","fa-git","fa-git-square","fa-github","fa-github-alt","fa-github-square","fa-gitlab","fa-gittip","fa-glass","fa-glide","fa-glide-g","fa-globe","fa-google","fa-google-plus","fa-google-plus-circle","fa-google-plus-official","fa-google-plus-square","fa-google-wallet","fa-graduation-cap","fa-gratipay","fa-grav","fa-group","fa-h-square","fa-hacker-news","fa-hand-grab-o","fa-hand-lizard-o","fa-hand-o-down","fa-hand-o-left","fa-hand-o-right","fa-hand-o-up","fa-hand-paper-o","fa-hand-peace-o","fa-hand-pointer-o","fa-hand-rock-o","fa-hand-scissors-o","fa-hand-spock-o","fa-hand-stop-o","fa-handshake-o","fa-hard-of-hearing","fa-hashtag","fa-hdd-o","fa-header","fa-headphones","fa-heart","fa-heart-o","fa-heartbeat","fa-history","fa-home","fa-hospital-o","fa-hotel","fa-hourglass","fa-hourglass-1","fa-hourglass-2","fa-hourglass-3","fa-hourglass-end","fa-hourglass-half","fa-hourglass-o","fa-hourglass-start","fa-houzz","fa-html5","fa-i-cursor","fa-id-badge","fa-id-card","fa-id-card-o","fa-ils","fa-image","fa-imdb","fa-inbox","fa-indent","fa-industry","fa-info","fa-info-circle","fa-inr","fa-instagram","fa-institution","fa-internet-explorer","fa-intersex","fa-ioxhost","fa-italic","fa-joomla","fa-jpy","fa-jsfiddle","fa-key","fa-keyboard-o","fa-krw","fa-language","fa-laptop","fa-lastfm","fa-lastfm-square","fa-leaf","fa-leanpub","fa-legal","fa-lemon-o","fa-level-down","fa-level-up","fa-life-bouy","fa-life-buoy","fa-life-ring","fa-life-saver","fa-lightbulb-o","fa-line-chart","fa-link","fa-linkedin","fa-linkedin-square","fa-linode","fa-linux","fa-list","fa-list-alt","fa-list-ol","fa-list-ul","fa-location-arrow","fa-lock","fa-long-arrow-down","fa-long-arrow-left","fa-long-arrow-right","fa-long-arrow-up","fa-low-vision","fa-magic","fa-magnet","fa-mail-forward","fa-mail-reply","fa-mail-reply-all","fa-male","fa-map","fa-map-marker","fa-map-o","fa-map-pin","fa-map-signs","fa-mars","fa-mars-double","fa-mars-stroke","fa-mars-stroke-h","fa-mars-stroke-v","fa-maxcdn","fa-meanpath","fa-medium","fa-medkit","fa-meetup","fa-meh-o","fa-mercury","fa-microchip","fa-microphone","fa-microphone-slash","fa-minus","fa-minus-circle","fa-minus-square","fa-minus-square-o","fa-mixcloud","fa-mobile","fa-mobile-phone","fa-modx","fa-money","fa-moon-o","fa-mortar-board","fa-motorcycle","fa-mouse-pointer","fa-music","fa-navicon","fa-neuter","fa-newspaper-o","fa-object-group","fa-object-ungroup","fa-odnoklassniki","fa-odnoklassniki-square","fa-opencart","fa-openid","fa-opera","fa-optin-monster","fa-outdent","fa-pagelines","fa-paint-brush","fa-paper-plane","fa-paper-plane-o","fa-paperclip","fa-paragraph","fa-paste","fa-pause","fa-pause-circle","fa-pause-circle-o","fa-paw","fa-paypal","fa-pencil","fa-pencil-square","fa-pencil-square-o","fa-percent","fa-phone","fa-phone-square","fa-photo","fa-picture-o","fa-pie-chart","fa-pied-piper","fa-pied-piper-alt","fa-pied-piper-pp","fa-pinterest","fa-pinterest-p","fa-pinterest-square","fa-plane","fa-play","fa-play-circle","fa-play-circle-o","fa-plug","fa-plus","fa-plus-circle","fa-plus-square","fa-plus-square-o","fa-podcast","fa-power-off","fa-print","fa-product-hunt","fa-puzzle-piece","fa-qq","fa-qrcode","fa-question","fa-question-circle","fa-question-circle-o","fa-quora","fa-quote-left","fa-quote-right","fa-ra","fa-random","fa-ravelry","fa-rebel","fa-recycle","fa-reddit","fa-reddit-alien","fa-reddit-square","fa-refresh","fa-registered","fa-remove","fa-renren","fa-reorder","fa-repeat","fa-reply","fa-reply-all","fa-resistance","fa-retweet","fa-rmb","fa-road","fa-rocket","fa-rotate-left","fa-rotate-right","fa-rouble","fa-rss","fa-rss-square","fa-rub","fa-ruble","fa-rupee","fa-s15","fa-safari","fa-save","fa-scissors","fa-scribd","fa-search","fa-search-minus","fa-search-plus","fa-sellsy","fa-send","fa-send-o","fa-server","fa-share","fa-share-alt","fa-share-alt-square","fa-share-square","fa-share-square-o","fa-shekel","fa-sheqel","fa-shield","fa-ship","fa-shirtsinbulk","fa-shopping-bag","fa-shopping-basket","fa-shopping-cart","fa-shower","fa-sign-in","fa-sign-language","fa-sign-out","fa-signal","fa-signing","fa-simplybuilt","fa-sitemap","fa-skyatlas","fa-skype","fa-slack","fa-sliders","fa-slideshare","fa-smile-o","fa-snapchat","fa-snapchat-ghost","fa-snapchat-square","fa-snowflake-o","fa-soccer-ball-o","fa-sort","fa-sort-alpha-asc","fa-sort-alpha-desc","fa-sort-amount-asc","fa-sort-amount-desc","fa-sort-asc","fa-sort-desc","fa-sort-down","fa-sort-numeric-asc","fa-sort-numeric-desc","fa-sort-up","fa-soundcloud","fa-space-shuttle","fa-spinner","fa-spoon","fa-spotify","fa-square","fa-square-o","fa-stack-exchange","fa-stack-overflow","fa-star","fa-star-half","fa-star-half-empty","fa-star-half-full","fa-star-half-o","fa-star-o","fa-steam","fa-steam-square","fa-step-backward","fa-step-forward","fa-stethoscope","fa-sticky-note","fa-sticky-note-o","fa-stop","fa-stop-circle","fa-stop-circle-o","fa-street-view","fa-strikethrough","fa-stumbleupon","fa-stumbleupon-circle","fa-subscript","fa-subway","fa-suitcase","fa-sun-o","fa-superpowers","fa-superscript","fa-support","fa-table","fa-tablet","fa-tachometer","fa-tag","fa-tags","fa-tasks","fa-taxi","fa-telegram","fa-television","fa-tencent-weibo","fa-terminal","fa-text-height","fa-text-width","fa-th","fa-th-large","fa-th-list","fa-themeisle","fa-thermometer","fa-thermometer-0","fa-thermometer-1","fa-thermometer-2","fa-thermometer-3","fa-thermometer-4","fa-thermometer-empty","fa-thermometer-full","fa-thermometer-half","fa-thermometer-quarter","fa-thermometer-three-quarters","fa-thumb-tack","fa-thumbs-down","fa-thumbs-o-down","fa-thumbs-o-up","fa-thumbs-up","fa-ticket","fa-times","fa-times-circle","fa-times-circle-o","fa-times-rectangle","fa-times-rectangle-o","fa-tint","fa-toggle-down","fa-toggle-left","fa-toggle-off","fa-toggle-on","fa-toggle-right","fa-toggle-up","fa-trademark","fa-train","fa-transgender","fa-transgender-alt","fa-trash","fa-trash-o","fa-tree","fa-trello","fa-tripadvisor","fa-trophy","fa-truck","fa-try","fa-tty","fa-tumblr","fa-tumblr-square","fa-turkish-lira","fa-tv","fa-twitch","fa-twitter","fa-twitter-square","fa-umbrella","fa-underline","fa-undo","fa-universal-access","fa-university","fa-unlink","fa-unlock","fa-unlock-alt","fa-unsorted","fa-upload","fa-usb","fa-usd","fa-user","fa-user-circle","fa-user-circle-o","fa-user-md","fa-user-o","fa-user-plus","fa-user-secret","fa-user-times","fa-users","fa-vcard","fa-vcard-o","fa-venus","fa-venus-double","fa-venus-mars","fa-viacoin","fa-viadeo","fa-viadeo-square","fa-video-camera","fa-vimeo","fa-vimeo-square","fa-vine","fa-vk","fa-volume-control-phone","fa-volume-down","fa-volume-off","fa-volume-up","fa-warning","fa-wechat","fa-weibo","fa-weixin","fa-whatsapp","fa-wheelchair","fa-wheelchair-alt","fa-wifi","fa-wikipedia-w","fa-window-close","fa-window-close-o","fa-window-maximize","fa-window-minimize","fa-window-restore","fa-windows","fa-won","fa-wordpress","fa-wpbeginner","fa-wpexplorer","fa-wpforms","fa-wrench","fa-xing","fa-xing-square","fa-y-combinator","fa-y-combinator-square","fa-yahoo","fa-yc","fa-yc-square","fa-yelp","fa-yen","fa-yoast","fa-youtube","fa-youtube-play","fa-youtube-square"]}); \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/js/fontawesome-picker-init.js b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/js/fontawesome-picker-init.js new file mode 100755 index 00000000..cfb97e89 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/assets/js/fontawesome-picker-init.js @@ -0,0 +1,7 @@ + +jQuery(document).ready(function($) { + 'use strict'; + $('.fontawesome-icon-select').iconpicker({ + hideOnSelect: true + }); +}); // End Ready diff --git a/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/cmb2-fontawesome-picker.php b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/cmb2-fontawesome-picker.php new file mode 100755 index 00000000..12fc96ce --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/cmb2-fontawesome-picker.php @@ -0,0 +1,73 @@ +setup_admin_scripts(); + + echo $field_type->input( array( 'type' => 'text', 'class' => 'fontawesome-icon-select regular-text' ) ); + } + + /** + * Sanitize icon class name + */ + public function sanitize( $sanitized_val, $val ) { + if ( ! empty( $val ) ) { + return sanitize_html_class( $val ); + } + return $sanitized_val; + } + + /** + * Enqueue admin scripts for our font-awesome picker field type + */ + protected function setup_admin_scripts() { + $dir = trailingslashit( dirname( __FILE__ ) ); + + if ( 'WIN' === strtoupper( substr( PHP_OS, 0, 3 ) ) ) { + // Windows + $content_dir = str_replace( '/', DIRECTORY_SEPARATOR, WP_CONTENT_DIR ); + $content_url = str_replace( $content_dir, WP_CONTENT_URL, $dir ); + $url = str_replace( DIRECTORY_SEPARATOR, '/', $content_url ); + } + else { + $url = str_replace( + array( WP_CONTENT_DIR, WP_PLUGIN_DIR ), + array( WP_CONTENT_URL, WP_PLUGIN_URL ), + $dir + ); + } + + $url = set_url_scheme( $url ); + + $requirements = array( + 'jquery', + ); + + wp_enqueue_script( 'cmb2-fontawesome-picker', $url . 'assets/js/fontawesome-iconpicker.min.js', array('jquery'), self::VERSION, true ); + wp_enqueue_script( 'cmb2-fontawesome-picker-init', $url . 'assets/js/fontawesome-picker-init.js', array('cmb2-fontawesome-picker'), self::VERSION, true ); + + wp_enqueue_style( 'bootstrap-popovers', $url . 'assets/css/bootstrap-popovers.css', array('cmb2-fontawesome-css'), self::VERSION ); + wp_enqueue_style( 'cmb2-fontawesome-picker', $url . 'assets/css/fontawesome-iconpicker.min.css', array('bootstrap-popovers'), self::VERSION ); + wp_enqueue_style( 'cmb2-fontawesome-picker-fixes', $url . 'assets/css/cmb2-fixes.css', array('cmb2-fontawesome-picker'), self::VERSION ); + } +} +new KS_FontAwesome_IconPicker(); diff --git a/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/resources/bootstrap-popovers.scss b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/resources/bootstrap-popovers.scss new file mode 100755 index 00000000..159ae939 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-fontawesome-icon-picker/resources/bootstrap-popovers.scss @@ -0,0 +1,18 @@ +@import '../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/_variables.scss'; +@import '../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/_mixins.scss'; + +// Contextual backgrounds +// For now we'll leave these alongside the text classes until v4 when we can +// safely shift things around (per SemVer rules). +.bg-primary { + // Given the contrast here, this is the only class to have its color inverted + // automatically. + color: #fff; +} +@include bg-variant('.bg-primary', $brand-primary); +@include bg-variant('.bg-success', $state-success-bg); +@include bg-variant('.bg-info', $state-info-bg); +@include bg-variant('.bg-warning', $state-warning-bg); +@include bg-variant('.bg-danger', $state-danger-bg); + +@import '../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/_popovers.scss'; diff --git a/inc/vendors/cmb2-plugins/cmb2-tabs/assets/css/cmb2-tabs.css b/inc/vendors/cmb2-plugins/cmb2-tabs/assets/css/cmb2-tabs.css new file mode 100755 index 00000000..0fd2f1c4 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-tabs/assets/css/cmb2-tabs.css @@ -0,0 +1,207 @@ +.ui-tabs .inside:after, .ui-tabs .ui-tabs-nav:after, .ui-tabs:after { + clear: both +} + +.ui-tabs .inside:after, .ui-tabs .ui-tabs-nav:after, .ui-tabs-vertical .cmb2-wrap .cmb-row:after, .ui-tabs:after { + content: ' '; + display: block +} + +div.cmb-type-tabs { + padding: 0 !important; + margin: -6px -12px -12px !important +} + +.ui-tabs { + position: relative; + background-color: #FFF; + padding-top: 10px; + padding-bottom: 20px; +} + +.cmb2-options-page div.cmb-type-tabs { + padding: 0 !important; + margin: 0 !important +} + +.cmb2-options-page .ui-tabs { + margin: 0 -10px; + border: 1px solid #e5e5e5; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .04); + box-shadow: 0 1px 1px rgba(0, 0, 0, .04) +} + +.ui-tabs h2.hndle { + background: #fff +} + +.ui-tabs .ui-tabs-nav { + margin: 6px 0 0 10px +} + +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap +} + +.ui-tabs .ui-tabs-nav li a { + display: block; + text-decoration: none; + font-size: 14px; + line-height: 18px; + padding: 10px 20px !important; + margin: 0 0 -1px; + border: 1px solid transparent; + border-top: 2px solid #f7f7f7; +} + +.ui-tabs .ui-tabs-nav li a:focus { + -webkit-box-shadow: none; + box-shadow: none +} + +.ui-tabs.ui-tabs-vertical .ui-tabs-nav .ui-tabs-anchor { + float: left; + /*padding: .5em 1em;*/ + text-decoration: none; + width: 153px; + padding: 10px 0 10px 10px !important; +} + +.ui-tabs.ui-tabs-horizontal .ui-tabs-nav .ui-tabs-anchor { + float: left; + padding: .5em 1em; + text-decoration: none; +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; + border-bottom-width: 1px +} + +.ui-tabs .ui-tabs-nav li.ui-tabs-active a { + z-index: 50 !important; + background-color: #FFF; + border: 1px solid #E1E1E1; + border-bottom-color: #FFF; + border-top: 2px solid #2EA2CC; + margin: 0 0 -1px +} + +.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { + cursor: default; +} + +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { + cursor: pointer +} + +.ui-tabs .ui-tabs-panel { + display: block; + border: none; + border-top: 1px solid #E1E1E1; + margin: 0; + padding: 20px; + background: #fff +} + +.ui-tabs .ui-tabs-panel h3 { + border-bottom: 1px solid #e9e9e9; + /*padding-bottom: 20px;*/ + /*margin-bottom: 20px*/ +} + +.ui-tabs .inside { + margin: 0 !important; + padding: 0 +} + +.ui-tabs-vertical { + padding-top: 0 +} + +.ui-tabs-vertical .ui-tabs-nav { + float: left; + width: 165px; + margin: 10px 0 0; + position: relative; + z-index: 10; + border-right: 1px solid #E1E1E1 +} + +.ui-tabs-vertical .ui-tabs-nav li { + clear: left; + width: 100%; + border-bottom-width: 1px !important; + border-right-width: 0 !important; + margin: 0 -1px .2em 0 +} + +.ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active { + padding-bottom: 0; + padding-right: .1em; + border-right-width: 1px +} + +.ui-tabs-vertical .ui-tabs-nav li a { + padding: 10px 0 10px 10px !important; + border-top: none; + font-weight: bold; + color: #000; + font-size: 93% +} + +.ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active a { + z-index: 50 !important; + background-color: #FFF; + border: 1px solid #E1E1E1; + border-right-color: #FFF; + border-left: 2px solid #2EA2CC; + margin: 0 -1px 0 0; + width: 153px; + padding: 10px 0 10px 10px !important +} + +.ui-tabs-vertical .ui-tabs-panel { + min-height: 200px; + border: none; + float: left; + width: calc(100% - 207px) +} + +.ui-tabs-vertical .cmb2-wrap .cmb-row { + margin: 6px 0 +} + +.ui-tabs-vertical .cmb2-wrap .cmb-row:after { + clear: both +} + +.ui-tabs-vertical .cmb2-wrap .cmb-th { + float: left; + width: 14%; + min-height: 32px; + line-height: 32px; + margin-right: 1% +} + +.ui-tabs-vertical .cmb2-wrap .cmb-td { + float: left; + width: 85% +} + +.ui-tabs-vertical .cmb2-wrap .cmb-td span.after_field { + display: inline-block; + width: 90px; + font-size: 13px; + padding: 0 5px +} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2-tabs/assets/js/cmb2-tabs.js b/inc/vendors/cmb2-plugins/cmb2-tabs/assets/js/cmb2-tabs.js new file mode 100755 index 00000000..9f12b2e9 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-tabs/assets/js/cmb2-tabs.js @@ -0,0 +1,10 @@ +(function ($) { + $(document).ready(function () { + // init jQuery UI Tabs + setTimeout(function () { + $( ".dtheme-cmb2-tabs" ).tabs(); + }); + }); +})(jQuery); + +jQuery.noConflict(); \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2-tabs/autoloader.php b/inc/vendors/cmb2-plugins/cmb2-tabs/autoloader.php new file mode 100755 index 00000000..20715641 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-tabs/autoloader.php @@ -0,0 +1,11 @@ +setting = $field_object->args( 'tabs' ); + $this->object_id = $object_id; + + // Set layout + $layout = empty( $this->setting['layout'] ) ? 'ui-tabs-horizontal' : "ui-tabs-{$this->setting['layout']}"; + $default_data = version_compare( CMB2_VERSION, '2.2.2', '>=' ) ? array( + 'class' => "dtheme-cmb2-tabs $layout", + ) : $field_type_object->parse_args( $field_object->data_args(), 'tabs', array( + 'class' => "dtheme-cmb2-tabs $layout", + ) ); + + // Render field + echo sprintf( '
            %s
            ', $field_type_object->concat_attrs( $default_data, array( + 'value', + 'name', + 'type' + ) ), $this->get_tabs() ); + } + + + /** + * Render tabs + * + * @return string + */ + public function get_tabs() { + ob_start(); + ?> + +
              + setting['tabs'] as $key => $tab ): ?> +
            • + + + +
            • + +
            + + setting['tabs'] as $key => $tab ): ?> +
            + render_fields( $this->setting['config'], $tab['fields'], $this->object_id ); + ?> +
            + $fields ) ); + $CMB2 = new \CMB2( $setting_fields, $object_id ); + + foreach ( $fields as $key_field => $field ) { + if ( $CMB2->is_options_page_mb() ) { + $CMB2->object_type( $args['object_type'] ); + } + // Cmb2 render field + $CMB2->render_field( $field ); + } + } + + + /** + * Hook: Save field values + * + * @param $override_value + * @param $value + * @param $post_id + * @param $data + */ + public static function save( $override_value, $value, $post_id, $data ) { + foreach ( $data['tabs']['tabs'] as $tab ) { + $setting_fields = array_merge( $data['tabs']['config'], array( 'fields' => $tab['fields'] ) ); + $CMB2 = new \CMB2( $setting_fields, $post_id ); + + if ( $CMB2->is_options_page_mb() ) { + $cmb2_options = cmb2_options( $post_id ); + $id_fields = array_map( function( $field ) { + return $field['id']; + }, $tab['fields'] ); + + foreach ( $_POST as $key => $value ) { + if ( array_search( $key, $id_fields ) !== false ) { + $cmb2_options->update( $key, $value ); + } + } + } else { + $CMB2->save_fields(); + } + } + } + +} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2-tabs/plugin.php b/inc/vendors/cmb2-plugins/cmb2-tabs/plugin.php new file mode 100755 index 00000000..9e336f41 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2-tabs/plugin.php @@ -0,0 +1,22 @@ +cmb_id, is the box id. + * + * @since 2.2.6 + * + * @param array $cmb The CMB2 object to hookup. + */ + do_action( "cmb2_init_hookup_{$cmb->cmb_id}", $cmb ); + } + + /** + * Fires after CMB2 initiation process has been completed + */ + do_action( 'cmb2_after_init' ); +} + +/* End. That's it, folks! */ diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display-rtl.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display-rtl.css new file mode 100755 index 00000000..52882879 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display-rtl.css @@ -0,0 +1,45 @@ +/*! + * CMB2 - v2.6.0 - 2019-01-18 + * https://cmb2.io + * Copyright (c) 2019 + * Licensed GPLv2+ + */ + +/*-------------------------------------------------------------- + * CMB2 Display Styling +--------------------------------------------------------------*/ +/* line 6, sass/partials/_display.scss */ +.cmb2-colorpicker-swatch span { + display: inline-block; + width: 1em; + height: 1em; + border-radius: 1em; + float: right; + margin-top: 3px; + margin-left: 2px; +} + +/* line 17, sass/partials/_display.scss */ +.cmb2-code { + overflow: scroll; +} + +/* line 21, sass/partials/_display.scss */ +.cmb-image-display { + max-width: 100%; + height: auto; +} + +/* line 26, sass/partials/_display.scss */ +.cmb2-display-file-list li { + display: inline; + margin: 0 0 .5em .5em; +} + +/* line 31, sass/partials/_display.scss */ +.cmb2-oembed * { + max-width: 100%; + height: auto; +} + +/*# sourceMappingURL=cmb2-display.css.map */ diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display-rtl.min.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display-rtl.min.css new file mode 100755 index 00000000..145926e6 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display-rtl.min.css @@ -0,0 +1,2 @@ +/*! CMB2 - v2.6.0 - 2019-01-18 | https://cmb2.io | Copyright (c) 2019 CMB2 team | Licensed GPLv2 */ +.cmb2-colorpicker-swatch span{display:inline-block;width:1em;height:1em;border-radius:1em;float:right;margin-top:3px;margin-left:2px}.cmb2-code{overflow:scroll}.cmb-image-display{max-width:100%;height:auto}.cmb2-display-file-list li{display:inline;margin:0 0 .5em .5em}.cmb2-oembed *{max-width:100%;height:auto} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.css new file mode 100755 index 00000000..b44058b6 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.css @@ -0,0 +1,45 @@ +/*! + * CMB2 - v2.6.0 - 2019-01-18 + * https://cmb2.io + * Copyright (c) 2019 + * Licensed GPLv2+ + */ + +/*-------------------------------------------------------------- + * CMB2 Display Styling +--------------------------------------------------------------*/ +/* line 6, sass/partials/_display.scss */ +.cmb2-colorpicker-swatch span { + display: inline-block; + width: 1em; + height: 1em; + border-radius: 1em; + float: left; + margin-top: 3px; + margin-right: 2px; +} + +/* line 17, sass/partials/_display.scss */ +.cmb2-code { + overflow: scroll; +} + +/* line 21, sass/partials/_display.scss */ +.cmb-image-display { + max-width: 100%; + height: auto; +} + +/* line 26, sass/partials/_display.scss */ +.cmb2-display-file-list li { + display: inline; + margin: 0 .5em .5em 0; +} + +/* line 31, sass/partials/_display.scss */ +.cmb2-oembed * { + max-width: 100%; + height: auto; +} + +/*# sourceMappingURL=cmb2-display.css.map */ diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.css.map b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.css.map new file mode 100755 index 00000000..d7100806 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAAA;;gEAEgE;;AAG/D,6BAAK;EACJ,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,GAAG;EACX,aAAa,EAAE,GAAG;EAClB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,GAAG;EACf,YAAY,EAAE,GAAG;;;;AAInB,UAAW;EACV,QAAQ,EAAE,MAAM;;;;AAGjB,kBAAmB;EAClB,SAAS,EAAE,IAAI;EACf,MAAM,EAAE,IAAI;;;;AAGb,0BAA2B;EAC1B,OAAO,EAAE,MAAM;EACf,MAAM,EAAE,aAAa;;;;AAGtB,cAAe;EACd,SAAS,EAAE,IAAI;EACf,MAAM,EAAE,IAAI", +"sources": ["sass/partials/_display.scss"], +"names": [], +"file": "cmb2-display.css" +} diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.min.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.min.css new file mode 100755 index 00000000..83b21690 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-display.min.css @@ -0,0 +1,2 @@ +/*! CMB2 - v2.6.0 - 2019-01-18 | https://cmb2.io | Copyright (c) 2019 CMB2 team | Licensed GPLv2 */ +.cmb2-colorpicker-swatch span{display:inline-block;width:1em;height:1em;border-radius:1em;float:left;margin-top:3px;margin-right:2px}.cmb2-code{overflow:scroll}.cmb-image-display{max-width:100%;height:auto}.cmb2-display-file-list li{display:inline;margin:0 .5em .5em 0}.cmb2-oembed *{max-width:100%;height:auto} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front-rtl.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front-rtl.css new file mode 100755 index 00000000..286ed3d9 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front-rtl.css @@ -0,0 +1,1331 @@ +/*! + * CMB2 - v2.6.0 - 2019-01-18 + * https://cmb2.io + * Copyright (c) 2019 + * Licensed GPLv2+ + */ + +@charset "UTF-8"; +/*-------------------------------------------------------------- + * Main Wrap +--------------------------------------------------------------*/ +/* line 5, sass/partials/_main_wrap.scss */ +.cmb2-wrap { + margin: 0; +} +/* line 8, sass/partials/_main_wrap.scss */ +.cmb2-wrap input, +.cmb2-wrap textarea { + font-size: 14px; + max-width: 100%; + padding: 5px; +} +/* line 18, sass/partials/_main_wrap.scss */ +.cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +/* line 23, sass/partials/_main_wrap.scss */ +.cmb2-wrap textarea { + width: 500px; +} +/* line 26, sass/partials/_main_wrap.scss */ +.cmb2-wrap textarea.cmb2-textarea-code { + font-family: "Courier 10 Pitch", Courier, monospace; + line-height: 16px; +} +/* line 34, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-text-small, .cmb2-wrap input.cmb2-timepicker { + width: 100px; +} +/* line 40, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-text-money { + width: 90px; +} +/* line 45, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-text-medium { + width: 230px; +} +/* line 50, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-upload-file { + width: 65%; +} +/* line 54, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.ed_button { + padding: 2px 4px; +} +/* line 59, sass/partials/_main_wrap.scss */ +.cmb2-wrap input:not([type="hidden"]) + input, +.cmb2-wrap input:not([type="hidden"]) + .button-secondary, +.cmb2-wrap input:not([type="hidden"]) + select { + margin-right: 20px; +} +/* line 67, sass/partials/_main_wrap.scss */ +.cmb2-wrap ul { + margin: 0; +} +/* line 71, sass/partials/_main_wrap.scss */ +.cmb2-wrap li { + font-size: 14px; + line-height: 16px; + margin: 1px 0 5px 0; +} +/* line 82, sass/partials/_main_wrap.scss */ +.cmb2-wrap select { + font-size: 14px; + margin-top: 3px; +} +/* line 87, sass/partials/_main_wrap.scss */ +.cmb2-wrap input:focus, +.cmb2-wrap textarea:focus { + background: #fffff8; +} +/* line 92, sass/partials/_main_wrap.scss */ +.cmb2-wrap input[type="radio"] { + margin: 0 0 0 5px; + padding: 0; +} +/* line 97, sass/partials/_main_wrap.scss */ +.cmb2-wrap input[type="checkbox"] { + margin: 0 0 0 5px; + padding: 0; +} +/* line 102, sass/partials/_main_wrap.scss */ +.cmb2-wrap button, +.cmb2-wrap .button-secondary { + white-space: nowrap; +} +/* line 107, sass/partials/_main_wrap.scss */ +.cmb2-wrap .mceLayout { + border: 1px solid #e9e9e9 !important; +} +/* line 111, sass/partials/_main_wrap.scss */ +.cmb2-wrap .mceIframeContainer { + background: #ffffff; +} +/* line 115, sass/partials/_main_wrap.scss */ +.cmb2-wrap .meta_mce { + width: 97%; +} +/* line 118, sass/partials/_main_wrap.scss */ +.cmb2-wrap .meta_mce textarea { + width: 100%; +} +/* line 124, sass/partials/_main_wrap.scss */ +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-input-wrap { + vertical-align: middle; +} +/* line 129, sass/partials/_main_wrap.scss */ +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-container { + margin: 0 0 0 10px; +} +/* line 134, sass/partials/_main_wrap.scss */ +.cmb2-wrap .cmb-row { + margin: 0; +} +/* line 137, sass/partials/_main_wrap.scss */ +.cmb2-wrap .cmb-row:after { + content: ''; + clear: both; + display: block; + width: 100%; +} +/* line 144, sass/partials/_main_wrap.scss */ +.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description { + padding-top: 0; + padding-bottom: 1em; +} + +/* line 152, sass/partials/_main_wrap.scss */ +.cmb2-metabox { + clear: both; + margin: 0; +} +/* line 158, sass/partials/_main_wrap.scss */ +.cmb2-metabox > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox > .cmb-row:first-of-type > .cmb-th, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-th { + border: 0; +} + +/* line 165, sass/partials/_main_wrap.scss */ +.cmb-add-row { + margin: 1.8em 0 0; +} + +/* line 169, sass/partials/_main_wrap.scss */ +.cmb-nested .cmb-td, +.cmb-repeatable-group .cmb-th, +.cmb-repeatable-group:first-of-type { + border: 0; +} + +/* line 175, sass/partials/_main_wrap.scss */ +.cmb-row:last-of-type, +.cmb2-wrap .cmb-row:last-of-type, +.cmb-repeatable-group:last-of-type { + border-bottom: 0; +} + +/* line 181, sass/partials/_main_wrap.scss */ +.cmb-repeatable-grouping { + border: 1px solid #e9e9e9; + padding: 0 1em; +} +/* line 185, sass/partials/_main_wrap.scss */ +.cmb-repeatable-grouping.cmb-row { + margin: 0 0 0.8em; +} + +/* line 193, sass/partials/_main_wrap.scss */ +.cmb-th { + color: #222222; + float: right; + font-weight: 600; + line-height: 1.3; + padding: 20px 0 20px 10px; + vertical-align: top; + width: 200px; +} +@media (max-width: 450px) { + /* line 193, sass/partials/_main_wrap.scss */ + .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: right; + width: 100%; + } + /* line 27, sass/partials/_mixins.scss */ + .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; + } +} + +/* line 207, sass/partials/_main_wrap.scss */ +.cmb-td { + line-height: 1.3; + max-width: 100%; + padding: 15px 10px; + vertical-align: middle; +} + +/* line 216, sass/partials/_main_wrap.scss */ +.cmb-type-title .cmb-td { + padding: 0; +} + +/* line 221, sass/partials/_main_wrap.scss */ +.cmb-th label { + display: block; + padding: 5px 0; +} + +/* line 226, sass/partials/_main_wrap.scss */ +.cmb-th + .cmb-td { + float: right; +} + +/* line 230, sass/partials/_main_wrap.scss */ +.cmb-td .cmb-td { + padding-bottom: 1em; +} + +/* line 234, sass/partials/_main_wrap.scss */ +.cmb-remove-row { + text-align: left; +} + +/* line 238, sass/partials/_main_wrap.scss */ +.empty-row.hidden { + display: none; +} + +/* line 243, sass/partials/_main_wrap.scss */ +.cmb-repeat-table { + background-color: #fafafa; + border: 1px solid #e1e1e1; +} +/* line 247, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row { + position: relative; + counter-increment: el; + margin: 0; + padding: 10px 50px 10px 10px; + border-bottom: none !important; +} +/* line 255, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row + .cmb-repeat-row { + border-top: solid 1px #e9e9e9; +} +/* line 259, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper { + outline: dashed 2px #e9e9e9 !important; +} +/* line 263, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row:before { + content: counter(el); + display: block; + top: 0; + right: 0; + position: absolute; + width: 35px; + height: 100%; + line-height: 35px; + cursor: move; + color: #757575; + text-align: center; + border-left: solid 1px #e9e9e9; +} +/* line 280, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td { + margin: 0; + padding: 0; +} +/* line 287, sass/partials/_main_wrap.scss */ +.cmb-repeat-table + .cmb-add-row { + margin: 0; +} +/* line 290, sass/partials/_main_wrap.scss */ +.cmb-repeat-table + .cmb-add-row:before { + content: ''; + width: 1px; + height: 1.6em; + display: block; + margin-right: 17px; + background-color: gainsboro; +} +/* line 300, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-remove-row { + top: 7px; + left: 7px; + position: absolute; + width: auto; + margin-right: 0; + padding: 0 !important; + display: none; +} +/* line 311, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button { + font-size: 20px; + text-indent: -1000px; + overflow: hidden; + position: relative; + height: auto; + line-height: 1; + padding: 0 10px 0; +} +/* line 322, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button:before { + content: ""; + font-family: 'Dashicons'; + speak: none; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + margin: 0; + text-indent: 0; + position: absolute; + top: 0; + right: 0; + width: 100%; + height: 100%; + text-align: center; +} +/* line 328, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row { + display: block; +} + +/* line 336, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-th { + padding: 5px; +} +/* line 340, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-title { + background-color: #e9e9e9; + padding: 8px 2.2em 8px 12px; + margin: 0 -1em; + min-height: 1.5em; + font-size: 14px; + line-height: 1.4; +} +/* line 348, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-title h4 { + border: 0; + margin: 0; + font-size: 1.2em; + font-weight: 500; + padding: 0.5em 0.75em; +} +/* line 356, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-title .cmb-th { + display: block; + width: 100%; +} +/* line 362, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-description .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: right; + width: 100%; +} +/* line 27, sass/partials/_mixins.scss */ +.cmb-repeatable-group .cmb-group-description .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} +/* line 366, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-shift-rows { + font-size: 1em; + margin-left: 1em; + text-decoration: none; +} +/* line 371, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-shift-rows .dashicons { + font-size: 1.5em; + height: 1.5em; + line-height: 1.2em; + width: 1em; +} +/* line 377, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2 { + line-height: 1.3em; +} +/* line 384, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb2-upload-button { + float: left; +} + +/* line 390, sass/partials/_main_wrap.scss */ +p.cmb2-metabox-description { + color: #757575; + font-style: italic; + margin: 0; + padding-top: .5em; +} + +/* line 397, sass/partials/_main_wrap.scss */ +span.cmb2-metabox-description { + color: #757575; + font-style: italic; +} + +/* line 402, sass/partials/_main_wrap.scss */ +.cmb2-metabox-title { + margin: 0 0 5px 0; + padding: 5px 0 0 0; + font-size: 14px; +} + +/* line 408, sass/partials/_main_wrap.scss */ +.cmb-inline ul { + padding: 4px 0 0 0; +} + +/* line 412, sass/partials/_main_wrap.scss */ +.cmb-inline li { + display: inline-block; + padding-left: 18px; +} + +/* line 417, sass/partials/_main_wrap.scss */ +.cmb-type-textarea-code pre { + margin: 0; +} + +/* line 423, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status { + clear: none; + display: inline-block; + vertical-align: middle; + margin-left: 10px; + width: auto; +} +/* line 430, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status img { + max-width: 350px; + height: auto; +} +/* line 436, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status img, +.cmb2-media-status .embed-status { + background: #eee; + border: 5px solid #ffffff; + outline: 1px solid #e9e9e9; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.05); + background-image: linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0), linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; + border-radius: 2px; + -moz-border-radius: 2px; + margin: 15px 0 0 0; +} +/* line 450, sass/partials/_main_wrap.scss */ +.cmb2-media-status .embed-status { + float: right; + max-width: 800px; +} +/* line 455, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status, .cmb2-media-status .embed-status { + position: relative; +} +/* line 458, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status .cmb2-remove-file-button, .cmb2-media-status .embed-status .cmb2-remove-file-button { + background: url(../images/ico-delete.png); + height: 16px; + right: -5px; + position: absolute; + text-indent: -9999px; + top: -5px; + width: 16px; +} +/* line 472, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status .cmb2-remove-file-button { + top: 10px; +} +/* line 477, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status img, .cmb2-media-status .file-status > span { + cursor: pointer; +} +/* line 482, sass/partials/_main_wrap.scss */ +.cmb2-media-status.cmb-attach-list .img-status img, .cmb2-media-status.cmb-attach-list .file-status > span { + cursor: move; +} + +/* line 489, sass/partials/_main_wrap.scss */ +.cmb-type-file-list .cmb2-media-status .img-status { + clear: none; + vertical-align: middle; + width: auto; + margin-left: 10px; + margin-bottom: 10px; + margin-top: 0; +} + +/* line 498, sass/partials/_main_wrap.scss */ +.cmb-attach-list li { + clear: both; + display: inline-block; + width: 100%; + margin-top: 5px; + margin-bottom: 10px; +} +/* line 504, sass/partials/_main_wrap.scss */ +.cmb-attach-list li img { + float: right; + margin-left: 10px; +} + +/* line 510, sass/partials/_main_wrap.scss */ +.cmb2-remove-wrapper { + margin: 0; +} + +/* line 514, sass/partials/_main_wrap.scss */ +.child-cmb2 .cmb-th { + text-align: right; +} + +/* line 518, sass/partials/_main_wrap.scss */ +.cmb2-indented-hierarchy { + padding-right: 1.5em; +} + +@media (max-width: 450px) { + /* line 523, sass/partials/_main_wrap.scss */ + .cmb-th, + .cmb-td, + .cmb-th + .cmb-td { + display: block; + float: none; + width: 100%; + } +} +/*-------------------------------------------------------------- + * Post Metaboxes +--------------------------------------------------------------*/ +/* line 5, sass/partials/_post_metaboxes.scss */ +#poststuff .cmb-group-title { + margin-right: -1em; + margin-left: -1em; + min-height: 1.5em; +} + +/* line 11, sass/partials/_post_metaboxes.scss */ +#poststuff .repeatable .cmb-group-title { + padding-right: 2.2em; +} + +/* line 17, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb2-wrap, .cmb-type-group .cmb2-wrap { + margin: 0; +} +/* line 20, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb2-wrap > .cmb-field-list > .cmb-row, .cmb-type-group .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.8em 0; +} +/* line 26, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed, .cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +/* line 32, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-row, .cmb-type-group .cmb-row { + padding: 0 0 1.8em; + margin: 0 0 0.8em; +} +/* line 36, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-row .cmbhandle, .cmb-type-group .cmb-row .cmbhandle { + left: -1em; + position: relative; + color: #222222; +} +/* line 43, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-repeatable-grouping, .cmb-type-group .cmb-repeatable-grouping { + padding: 0 1em; + max-width: 100%; + min-width: 1px !important; +} +/* line 49, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-repeatable-group > .cmb-row, .cmb-type-group .cmb-repeatable-group > .cmb-row { + padding-bottom: 0; +} +/* line 53, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-th, .cmb-type-group .cmb-th { + width: 18%; + padding: 0 0 0 2%; +} +/* line 59, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-td, .cmb-type-group .cmb-td { + margin-bottom: 0; + padding: 0; + line-height: 1.3; +} +/* line 65, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-th + .cmb-td, .cmb-type-group .cmb-th + .cmb-td { + width: 80%; + float: left; +} +/* line 70, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 1px solid #e9e9e9; +} +@media (max-width: 450px) { + /* line 70, sass/partials/_post_metaboxes.scss */ + .cmb2-postbox .cmb-row:not(:last-of-type), + .cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), + .cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 0; + } +} +/* line 79, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-repeat-group-field, +.cmb2-postbox .cmb-remove-field-row, .cmb-type-group .cmb-repeat-group-field, +.cmb-type-group .cmb-remove-field-row { + padding-top: 1.8em; +} + +/*-------------------------------------------------------------- + * Context Metaboxes +--------------------------------------------------------------*/ +/* Metabox collapse arrow indicators */ +/* line 9, sass/partials/_context_metaboxes.scss */ +.js .cmb2-postbox.context-box .toggle-indicator:before { + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +/* line 22, sass/partials/_context_metaboxes.scss */ +.js .cmb2-postbox.context-box.closed .toggle-indicator:before { + content: "\f140"; +} + +/* line 30, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box { + margin-bottom: 10px; +} +/* line 34, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-before_permalink-box { + margin-top: 10px; +} +/* line 38, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-after_title-box { + margin-top: 10px; +} +/* line 42, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-after_editor-box { + margin-top: 20px; + margin-bottom: 0; +} +/* line 47, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-form_top-box { + margin-top: 10px; +} +/* line 51, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-form_top-box .hndle { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} +/* line 59, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box .hndle { + cursor: auto; +} + +/* line 64, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap { + margin-top: 10px; +} +/* line 68, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-left: 300px; + width: auto; +} +/* line 75, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox { + padding: 10px; +} +/* line 80, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-th { + padding: 0 0 0 2%; + width: 18%; +} +/* line 85, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-td { + width: 80%; + padding: 0; +} +/* line 90, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-row { + margin-bottom: 10px; +} +/* line 93, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-row:last-of-type { + margin-bottom: 0; +} + +/* one column on the post write/edit screen */ +@media only screen and (max-width: 850px) { + /* line 103, sass/partials/_context_metaboxes.scss */ + .cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-left: 0; + } +} +/*-------------------------------------------------------------- + * Misc. +--------------------------------------------------------------*/ +/* line 5, sass/partials/_misc.scss */ +#poststuff .cmb-repeatable-group h2 { + margin: 0; +} + +/* line 12, sass/partials/_misc.scss */ +.edit-tags-php .cmb2-metabox-title, +.profile-php .cmb2-metabox-title, +.user-edit-php .cmb2-metabox-title { + font-size: 1.4em; +} + +/* line 18, sass/partials/_misc.scss */ +.cmb2-postbox .cmb-spinner, .cmb2-no-box-wrap .cmb-spinner { + float: right; + display: none; +} + +/* line 24, sass/partials/_misc.scss */ +.cmb-spinner { + display: none; +} +/* line 26, sass/partials/_misc.scss */ +.cmb-spinner.is-active { + display: block; +} + +/*-------------------------------------------------------------- + * Collapsible UI +--------------------------------------------------------------*/ +/* line 6, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox .cmbhandle { + color: #757575; + float: left; + width: 27px; + height: 30px; + cursor: pointer; + left: -1em; + position: relative; +} +/* line 14, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox .cmbhandle:before { + content: '\f142'; + left: 12px; + font: normal 20px/1 'dashicons'; + speak: none; + display: inline-block; + padding: 8px 10px; + top: 0; + position: relative; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +/* line 31, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox .postbox.closed .cmbhandle:before { + content: '\f140'; +} +/* line 37, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + -webkit-appearance: none !important; + background: none !important; + border: none !important; + position: absolute; + right: 0; + top: .5em; + line-height: 1em; + padding: 2px 6px 3px; + opacity: .5; +} +/* line 47, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]) { + cursor: pointer; + color: #a00; + opacity: 1; +} +/* line 51, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover { + color: #f00; +} + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress" + * https://github.com/stuttter/wp-datepicker-styling + * + */ +/* line 15, sass/partials/_jquery_ui.scss */ +* html .cmb2-element.ui-helper-clearfix { + height: 1%; +} + +/* line 24, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + width: auto; + /* Default Color Scheme */ +} +/* line 38, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker *, .cmb2-element .ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +/* line 46, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker table, .cmb2-element .ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} +/* line 53, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} +/* line 61, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} +/* line 67, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-title, .cmb2-element .ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} +/* line 75, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-title select, .cmb2-element .ui-datepicker .ui-datepicker-title select { + margin-top: -8px; + margin-bottom: -8px; +} +/* line 81, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-next { + position: relative; + top: 0; + height: 34px; + width: 34px; +} +/* line 89, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next, .cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} +/* line 94, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover { + right: 0; +} +/* line 99, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover, .cmb2-element .ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover { + left: 0; +} +/* line 104, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next span, +.cmb2-element.ui-datepicker .ui-datepicker-prev span, .cmb2-element .ui-datepicker .ui-datepicker-next span, +.cmb2-element .ui-datepicker .ui-datepicker-prev span { + display: none; +} +/* line 109, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev, .cmb2-element .ui-datepicker .ui-datepicker-prev { + float: right; +} +/* line 113, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-next { + float: left; +} +/* line 117, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-right: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} +/* line 129, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} +/* line 133, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} +/* line 137, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before, .cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} +/* line 142, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker select.ui-datepicker-month, +.cmb2-element.ui-datepicker select.ui-datepicker-year, .cmb2-element .ui-datepicker select.ui-datepicker-month, +.cmb2-element .ui-datepicker select.ui-datepicker-year { + width: 33%; + background: transparent; + border-color: transparent; + box-shadow: none; + color: #fff; +} +/* line 149, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker select.ui-datepicker-month option, +.cmb2-element.ui-datepicker select.ui-datepicker-year option, .cmb2-element .ui-datepicker select.ui-datepicker-month option, +.cmb2-element .ui-datepicker select.ui-datepicker-year option { + color: #333; +} +/* line 154, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + color: #fff; + font-weight: 600; +} +/* line 157, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker thead th, .cmb2-element .ui-datepicker thead th { + font-weight: normal; +} +/* line 162, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker th, .cmb2-element .ui-datepicker th { + padding: 10px; +} +/* line 166, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td, .cmb2-element .ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} +/* line 171, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-other-month, .cmb2-element .ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} +/* line 175, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-week-end, .cmb2-element .ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} +/* line 178, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today { + -webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); +} +/* line 185, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} +/* line 189, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-current-day, .cmb2-element .ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} +/* line 193, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td .ui-state-default, .cmb2-element .ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} +/* line 205, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default, .cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} +/* line 210, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +/* line 215, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + background: #32373c; +} +/* line 219, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td .ui-state-hover, .cmb2-element.ui-datepicker td .ui-state-active, .cmb2-element .ui-datepicker td .ui-state-hover, .cmb2-element .ui-datepicker td .ui-state-active { + background: #0073aa; + color: #fff; +} +/* line 224, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div, .cmb2-element .ui-datepicker .ui-timepicker-div { + font-size: 14px; +} +/* line 226, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl, .cmb2-element .ui-datepicker .ui-timepicker-div dl { + text-align: right; + padding: 0 .6em; +} +/* line 229, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl dt, .cmb2-element .ui-datepicker .ui-timepicker-div dl dt { + float: right; + clear: right; + padding: 0 5px 0 0; +} +/* line 234, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd { + margin: 0 40% 10px 10px; +} +/* line 236, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd select { + width: 100%; +} +/* line 242, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane { + padding: .6em; + text-align: right; +} +/* line 246, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary { + padding: 0 10px 1px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + margin: 0 .4em .4em .6em; +} + +/* line 260, sass/partials/_jquery_ui.scss */ +.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +/* line 265, sass/partials/_jquery_ui.scss */ +.admin-color-fresh .cmb2-element.ui-datepicker thead, .admin-color-fresh .cmb2-element .ui-datepicker thead { + background: #32373c; +} +/* line 269, sass/partials/_jquery_ui.scss */ +.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* line 277, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #52accc; +} +/* line 282, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker thead, .admin-color-blue .cmb2-element .ui-datepicker thead { + background: #4796b3; +} +/* line 291, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active { + background: #096484; + color: #fff; +} +/* line 296, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 305, sass/partials/_jquery_ui.scss */ +.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #59524c; +} +/* line 310, sass/partials/_jquery_ui.scss */ +.admin-color-coffee .cmb2-element.ui-datepicker thead, .admin-color-coffee .cmb2-element .ui-datepicker thead { + background: #46403c; +} +/* line 314, sass/partials/_jquery_ui.scss */ +.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +/* line 322, sass/partials/_jquery_ui.scss */ +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} +/* line 327, sass/partials/_jquery_ui.scss */ +.admin-color-ectoplasm .cmb2-element.ui-datepicker thead, .admin-color-ectoplasm .cmb2-element .ui-datepicker thead { + background: #413256; +} +/* line 331, sass/partials/_jquery_ui.scss */ +.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +/* line 339, sass/partials/_jquery_ui.scss */ +.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} +/* line 344, sass/partials/_jquery_ui.scss */ +.admin-color-midnight .cmb2-element.ui-datepicker thead, .admin-color-midnight .cmb2-element .ui-datepicker thead { + background: #26292c; +} +/* line 348, sass/partials/_jquery_ui.scss */ +.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +/* line 356, sass/partials/_jquery_ui.scss */ +.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #738e96; +} +/* line 361, sass/partials/_jquery_ui.scss */ +.admin-color-ocean .cmb2-element.ui-datepicker thead, .admin-color-ocean .cmb2-element .ui-datepicker thead { + background: #627c83; +} +/* line 365, sass/partials/_jquery_ui.scss */ +.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +/* line 373, sass/partials/_jquery_ui.scss */ +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} +/* line 379, sass/partials/_jquery_ui.scss */ +.admin-color-sunrise .cmb2-element.ui-datepicker th, .admin-color-sunrise .cmb2-element .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} +/* line 384, sass/partials/_jquery_ui.scss */ +.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +/* line 392, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-light .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} +/* line 397, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year, .admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year { + color: #555; +} +/* line 402, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker thead, .admin-color-light .cmb2-element .ui-datepicker thead { + background: #888; +} +/* line 406, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before, .admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before { + color: #555; +} +/* line 414, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-active { + background: #ccc; +} +/* line 418, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 426, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #56b274; +} +/* line 431, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead { + background: #36533f; +} +/* line 435, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +/* line 443, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} +/* line 448, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-mint .cmb2-element.ui-datepicker thead, .admin-color-bbp-mint .cmb2-element .ui-datepicker thead { + background: #4f6d59; +} +/* line 452, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} + +/** + * CMB2 Frontend + */ +/*-------------------------------------------------------------- + * CMB2 Frontend +--------------------------------------------------------------*/ +/* line 5, sass/partials/_front.scss */ +.closed .inside { + display: none; +} + +/* line 9, sass/partials/_front.scss */ +.cmb-repeatable-grouping { + position: relative; +} +/* line 12, sass/partials/_front.scss */ +.cmb-repeatable-grouping .cmb-group-title { + margin-right: -1em; + margin-left: -1em; + min-height: 1.5em; +} +/* line 18, sass/partials/_front.scss */ +.cmb-repeatable-grouping h3 { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} + +/* line 29, sass/partials/_front.scss */ +.cmb-repeatable-group.repeatable .cmb-group-title { + padding-right: 2.2em; +} +/* line 33, sass/partials/_front.scss */ +.cmb-repeatable-group.non-repeatable .cmb-group-title { + padding-right: 12px; +} + +/* line 39, sass/partials/_front.scss */ +.cmb-type-group .cmb-row .cmbhandle { + left: 0; + position: absolute; +} + +/* line 44, sass/partials/_front.scss */ +.cmb-spinner { + background: url(/wp-admin/images/spinner.gif) no-repeat; + -webkit-background-size: 20px 20px; + background-size: 20px 20px; + display: none; + float: left; + vertical-align: middle; + opacity: 0.7; + filter: alpha(opacity=70); + width: 20px; + height: 20px; + margin: 4px 10px 0; +} + +/*# sourceMappingURL=cmb2-front.css.map */ diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front-rtl.min.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front-rtl.min.css new file mode 100755 index 00000000..6bd8b69a --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front-rtl.min.css @@ -0,0 +1,2 @@ +/*! CMB2 - v2.6.0 - 2019-01-18 | https://cmb2.io | Copyright (c) 2019 CMB2 team | Licensed GPLv2 */ +@charset "UTF-8";.cmb2-wrap{margin:0}.cmb2-wrap input,.cmb2-wrap textarea{font-size:14px;max-width:100%;padding:5px}.cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb2-wrap textarea{width:500px}.cmb2-wrap textarea.cmb2-textarea-code{font-family:"Courier 10 Pitch",Courier,monospace;line-height:16px}.cmb2-wrap input.cmb2-text-small,.cmb2-wrap input.cmb2-timepicker{width:100px}.cmb2-wrap input.cmb2-text-money{width:90px}.cmb2-wrap input.cmb2-text-medium{width:230px}.cmb2-wrap input.cmb2-upload-file{width:65%}.cmb2-wrap input.ed_button{padding:2px 4px}.cmb2-wrap input:not([type=hidden])+.button-secondary,.cmb2-wrap input:not([type=hidden])+input,.cmb2-wrap input:not([type=hidden])+select{margin-right:20px}.cmb2-wrap ul{margin:0}.cmb2-wrap li{font-size:14px;line-height:16px;margin:1px 0 5px}.cmb2-wrap select{font-size:14px;margin-top:3px}.cmb2-wrap input:focus,.cmb2-wrap textarea:focus{background:#fffff8}.cmb2-wrap input[type=checkbox],.cmb2-wrap input[type=radio]{margin:0 0 0 5px;padding:0}.cmb2-wrap .button-secondary,.cmb2-wrap button{white-space:nowrap}.cmb2-wrap .mceLayout{border:1px solid #e9e9e9!important}.cmb2-wrap .mceIframeContainer{background:#fff}.cmb2-wrap .meta_mce{width:97%}.cmb2-wrap .meta_mce textarea{width:100%}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-input-wrap{vertical-align:middle}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-container{margin:0 0 0 10px}.cmb2-wrap .cmb-row{margin:0}.cmb2-wrap .cmb-row:after{content:'';clear:both;display:block;width:100%}.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description{padding-top:0;padding-bottom:1em}.cmb2-metabox{clear:both;margin:0}.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-th,.cmb2-metabox>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox>.cmb-row:first-of-type>.cmb-th{border:0}.cmb-add-row{margin:1.8em 0 0}.cmb-nested .cmb-td,.cmb-repeatable-group .cmb-th,.cmb-repeatable-group:first-of-type{border:0}.cmb-repeatable-group:last-of-type,.cmb-row:last-of-type,.cmb2-wrap .cmb-row:last-of-type{border-bottom:0}.cmb-repeatable-grouping{border:1px solid #e9e9e9;padding:0 1em}.cmb-repeatable-grouping.cmb-row{margin:0 0 .8em}.cmb-th{color:#222;float:right;font-weight:600;line-height:1.3;padding:20px 0 20px 10px;vertical-align:top;width:200px}@media (max-width:450px){.cmb-th{font-size:1.2em;display:block;float:none;padding-bottom:1em;text-align:right;width:100%}.cmb-th label{display:block;margin-top:0;margin-bottom:.5em}}.cmb-td{line-height:1.3;max-width:100%;padding:15px 10px;vertical-align:middle}.cmb-type-title .cmb-td{padding:0}.cmb-th label{display:block;padding:5px 0}.cmb-th+.cmb-td{float:right}.cmb-td .cmb-td{padding-bottom:1em}.cmb-remove-row{text-align:left}.empty-row.hidden{display:none}.cmb-repeat-table{background-color:#fafafa;border:1px solid #e1e1e1}.cmb-repeat-table .cmb-row.cmb-repeat-row{position:relative;counter-increment:el;margin:0;padding:10px 50px 10px 10px;border-bottom:none!important}.cmb-repeat-table .cmb-row.cmb-repeat-row+.cmb-repeat-row{border-top:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper{outline:dashed 2px #e9e9e9!important}.cmb-repeat-table .cmb-row.cmb-repeat-row:before{content:counter(el);display:block;top:0;right:0;position:absolute;width:35px;height:100%;line-height:35px;cursor:move;color:#757575;text-align:center;border-left:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td{margin:0;padding:0}.cmb-repeat-table+.cmb-add-row{margin:0}.cmb-repeat-table+.cmb-add-row:before{content:'';width:1px;height:1.6em;display:block;margin-right:17px;background-color:#dcdcdc}.cmb-repeat-table .cmb-remove-row{top:7px;left:7px;position:absolute;width:auto;margin-right:0;padding:0!important;display:none}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button{font-size:20px;text-indent:-1000px;overflow:hidden;position:relative;height:auto;line-height:1;padding:0 10px}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button:before{content:"";font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;right:0;width:100%;height:100%;text-align:center}.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row{display:block}.cmb-repeatable-group .cmb-th{padding:5px}.cmb-repeatable-group .cmb-group-title{background-color:#e9e9e9;padding:8px 2.2em 8px 12px;margin:0 -1em;min-height:1.5em;font-size:14px;line-height:1.4}.cmb-repeatable-group .cmb-group-title h4{border:0;margin:0;font-size:1.2em;font-weight:500;padding:.5em .75em}.cmb-repeatable-group .cmb-group-title .cmb-th{display:block;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th{font-size:1.2em;display:block;float:none;padding-bottom:1em;text-align:right;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th label{display:block;margin-top:0;margin-bottom:.5em}.cmb-repeatable-group .cmb-shift-rows{font-size:1em;margin-left:1em;text-decoration:none}.cmb-repeatable-group .cmb-shift-rows .dashicons{font-size:1.5em;height:1.5em;line-height:1.2em;width:1em}.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2{line-height:1.3em}.cmb-repeatable-group .cmb2-upload-button{float:left}p.cmb2-metabox-description{color:#757575;font-style:italic;margin:0;padding-top:.5em}span.cmb2-metabox-description{color:#757575;font-style:italic}.cmb2-metabox-title{margin:0 0 5px;padding:5px 0 0;font-size:14px}.cmb-inline ul{padding:4px 0 0}.cmb-inline li{display:inline-block;padding-left:18px}.cmb-type-textarea-code pre{margin:0}.cmb2-media-status .img-status{clear:none;display:inline-block;vertical-align:middle;margin-left:10px;width:auto}.cmb2-media-status .img-status img{max-width:350px;height:auto}.cmb2-media-status .embed-status,.cmb2-media-status .img-status img{background:#eee;border:5px solid #fff;outline:1px solid #e9e9e9;box-shadow:inset 0 0 15px rgba(0,0,0,.3),inset 0 0 0 1px rgba(0,0,0,.05);background-image:linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0),linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0);background-position:0 0,10px 10px;background-size:20px 20px;border-radius:2px;-moz-border-radius:2px;margin:15px 0 0}.cmb2-media-status .embed-status{float:right;max-width:800px}.cmb2-media-status .embed-status,.cmb2-media-status .img-status{position:relative}.cmb2-media-status .embed-status .cmb2-remove-file-button,.cmb2-media-status .img-status .cmb2-remove-file-button{background:url(../images/ico-delete.png);height:16px;right:-5px;position:absolute;text-indent:-9999px;top:-5px;width:16px}.cmb2-media-status .img-status .cmb2-remove-file-button{top:10px}.cmb2-media-status .file-status>span,.cmb2-media-status .img-status img{cursor:pointer}.cmb2-media-status.cmb-attach-list .file-status>span,.cmb2-media-status.cmb-attach-list .img-status img{cursor:move}.cmb-type-file-list .cmb2-media-status .img-status{clear:none;vertical-align:middle;width:auto;margin-left:10px;margin-bottom:10px;margin-top:0}.cmb-attach-list li{clear:both;display:inline-block;width:100%;margin-top:5px;margin-bottom:10px}.cmb-attach-list li img{float:right;margin-left:10px}.cmb2-remove-wrapper{margin:0}.child-cmb2 .cmb-th{text-align:right}.cmb2-indented-hierarchy{padding-right:1.5em}@media (max-width:450px){.cmb-td,.cmb-th,.cmb-th+.cmb-td{display:block;float:none;width:100%}}#poststuff .cmb-group-title{margin-right:-1em;margin-left:-1em;min-height:1.5em}#poststuff .repeatable .cmb-group-title{padding-right:2.2em}.cmb-type-group .cmb2-wrap,.cmb2-postbox .cmb2-wrap{margin:0}.cmb-type-group .cmb2-wrap>.cmb-field-list>.cmb-row,.cmb2-postbox .cmb2-wrap>.cmb-field-list>.cmb-row{padding:1.8em 0}.cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed,.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb-type-group .cmb-row,.cmb2-postbox .cmb-row{padding:0 0 1.8em;margin:0 0 .8em}.cmb-type-group .cmb-row .cmbhandle,.cmb2-postbox .cmb-row .cmbhandle{left:-1em;position:relative;color:#222}.cmb-type-group .cmb-repeatable-grouping,.cmb2-postbox .cmb-repeatable-grouping{padding:0 1em;max-width:100%;min-width:1px!important}.cmb-type-group .cmb-repeatable-group>.cmb-row,.cmb2-postbox .cmb-repeatable-group>.cmb-row{padding-bottom:0}.cmb-type-group .cmb-th,.cmb2-postbox .cmb-th{width:18%;padding:0 0 0 2%}.cmb-type-group .cmb-td,.cmb2-postbox .cmb-td{margin-bottom:0;padding:0;line-height:1.3}.cmb-type-group .cmb-th+.cmb-td,.cmb2-postbox .cmb-th+.cmb-td{width:80%;float:left}.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:1px solid #e9e9e9}@media (max-width:450px){.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:0}}.cmb-type-group .cmb-remove-field-row,.cmb-type-group .cmb-repeat-group-field,.cmb2-postbox .cmb-remove-field-row,.cmb2-postbox .cmb-repeat-group-field{padding-top:1.8em}.js .cmb2-postbox.context-box .toggle-indicator:before{content:"\f142";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.js .cmb2-postbox.context-box.closed .toggle-indicator:before{content:"\f140"}.cmb2-postbox.context-box{margin-bottom:10px}.cmb2-postbox.context-box.context-after_title-box,.cmb2-postbox.context-box.context-before_permalink-box{margin-top:10px}.cmb2-postbox.context-box.context-after_editor-box{margin-top:20px;margin-bottom:0}.cmb2-postbox.context-box.context-form_top-box{margin-top:10px}.cmb2-postbox.context-box.context-form_top-box .hndle{font-size:14px;padding:8px 12px;margin:0;line-height:1.4}.cmb2-postbox.context-box .hndle{cursor:auto}.cmb2-context-wrap{margin-top:10px}.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-left:300px;width:auto}.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox{padding:10px}.cmb2-context-wrap .cmb-th{padding:0 0 0 2%;width:18%}.cmb2-context-wrap .cmb-td{width:80%;padding:0}.cmb2-context-wrap .cmb-row{margin-bottom:10px}.cmb2-context-wrap .cmb-row:last-of-type{margin-bottom:0}@media only screen and (max-width:850px){.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-left:0}}#poststuff .cmb-repeatable-group h2{margin:0}.edit-tags-php .cmb2-metabox-title,.profile-php .cmb2-metabox-title,.user-edit-php .cmb2-metabox-title{font-size:1.4em}.cmb2-no-box-wrap .cmb-spinner,.cmb2-postbox .cmb-spinner{float:right;display:none}.cmb-spinner.is-active{display:block}.cmb2-metabox .cmbhandle{color:#757575;float:left;width:27px;height:30px;cursor:pointer;left:-1em;position:relative}.cmb2-metabox .cmbhandle:before{content:'\f142';left:12px;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:8px 10px;top:0;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.cmb2-metabox .postbox.closed .cmbhandle:before{content:'\f140'}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row{-webkit-appearance:none!important;background:none!important;border:none!important;position:absolute;right:0;top:.5em;line-height:1em;padding:2px 6px 3px;opacity:.5}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]){cursor:pointer;color:#a00;opacity:1}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover{color:red}* html .cmb2-element.ui-helper-clearfix{height:1%}.cmb2-element .ui-datepicker,.cmb2-element.ui-datepicker{padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;background-color:#fff;border:1px solid #dfdfdf;border-top:none;-webkit-box-shadow:0 3px 6px rgba(0,0,0,.075);box-shadow:0 3px 6px rgba(0,0,0,.075);min-width:17em;width:auto}.cmb2-element .ui-datepicker *,.cmb2-element.ui-datepicker *{padding:0;font-family:"Open Sans",sans-serif;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.cmb2-element .ui-datepicker table,.cmb2-element.ui-datepicker table{font-size:13px;margin:0;border:none;border-collapse:collapse}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{border:none;color:#fff;font-weight:400}.cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover{background:0 0;border-color:transparent;cursor:pointer}.cmb2-element .ui-datepicker .ui-datepicker-title,.cmb2-element.ui-datepicker .ui-datepicker-title{margin:0;padding:10px 0;color:#fff;font-size:14px;line-height:14px;text-align:center}.cmb2-element .ui-datepicker .ui-datepicker-title select,.cmb2-element.ui-datepicker .ui-datepicker-title select{margin-top:-8px;margin-bottom:-8px}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-prev{position:relative;top:0;height:34px;width:34px}.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev{border:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover,.cmb2-element.ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover{right:0}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-next-hover,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next-hover{left:0}.cmb2-element .ui-datepicker .ui-datepicker-next span,.cmb2-element .ui-datepicker .ui-datepicker-prev span,.cmb2-element.ui-datepicker .ui-datepicker-next span,.cmb2-element.ui-datepicker .ui-datepicker-prev span{display:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev{float:right}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next{float:left}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{font:400 20px/34px dashicons;padding-right:7px;color:#fff;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:34px;height:34px}.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{content:'\f341'}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before{content:'\f345'}.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before{opacity:.7}.cmb2-element .ui-datepicker select.ui-datepicker-month,.cmb2-element .ui-datepicker select.ui-datepicker-year,.cmb2-element.ui-datepicker select.ui-datepicker-month,.cmb2-element.ui-datepicker select.ui-datepicker-year{width:33%;background:0 0;border-color:transparent;box-shadow:none;color:#fff}.cmb2-element .ui-datepicker select.ui-datepicker-month option,.cmb2-element .ui-datepicker select.ui-datepicker-year option,.cmb2-element.ui-datepicker select.ui-datepicker-month option,.cmb2-element.ui-datepicker select.ui-datepicker-year option{color:#333}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{color:#fff;font-weight:600}.cmb2-element .ui-datepicker thead th,.cmb2-element.ui-datepicker thead th{font-weight:400}.cmb2-element .ui-datepicker th,.cmb2-element.ui-datepicker th{padding:10px}.cmb2-element .ui-datepicker td,.cmb2-element.ui-datepicker td{padding:0;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-other-month,.cmb2-element.ui-datepicker td.ui-datepicker-other-month{border:transparent}.cmb2-element .ui-datepicker td.ui-datepicker-week-end,.cmb2-element.ui-datepicker td.ui-datepicker-week-end{background-color:#f4f4f4;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today{-webkit-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);-moz-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1)}.cmb2-element .ui-datepicker td.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-today{background-color:#f0f0c0}.cmb2-element .ui-datepicker td.ui-datepicker-current-day,.cmb2-element.ui-datepicker td.ui-datepicker-current-day{background:#bd8}.cmb2-element .ui-datepicker td .ui-state-default,.cmb2-element.ui-datepicker td .ui-state-default{background:0 0;border:none;text-align:center;text-decoration:none;width:auto;display:block;padding:5px 10px;font-weight:400;color:#444}.cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default,.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default{opacity:.5}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{background:#32373c}.cmb2-element .ui-datepicker td .ui-state-active,.cmb2-element .ui-datepicker td .ui-state-hover,.cmb2-element.ui-datepicker td .ui-state-active,.cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.cmb2-element .ui-datepicker .ui-timepicker-div,.cmb2-element.ui-datepicker .ui-timepicker-div{font-size:14px}.cmb2-element .ui-datepicker .ui-timepicker-div dl,.cmb2-element.ui-datepicker .ui-timepicker-div dl{text-align:right;padding:0 .6em}.cmb2-element .ui-datepicker .ui-timepicker-div dl dt,.cmb2-element.ui-datepicker .ui-timepicker-div dl dt{float:right;clear:right;padding:0 5px 0 0}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd{margin:0 40% 10px 10px}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd select,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select{width:100%}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane{padding:.6em;text-align:right}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary{padding:0 10px 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;margin:0 .4em .4em .6em}.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.admin-color-fresh .cmb2-element .ui-datepicker thead,.admin-color-fresh .cmb2-element.ui-datepicker thead{background:#32373c}.admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header{background:#52accc}.admin-color-blue .cmb2-element .ui-datepicker thead,.admin-color-blue .cmb2-element.ui-datepicker thead{background:#4796b3}.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover{background:#096484;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header{background:#59524c}.admin-color-coffee .cmb2-element .ui-datepicker thead,.admin-color-coffee .cmb2-element.ui-datepicker thead{background:#46403c}.admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover{background:#c7a589;color:#fff}.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header{background:#523f6d}.admin-color-ectoplasm .cmb2-element .ui-datepicker thead,.admin-color-ectoplasm .cmb2-element.ui-datepicker thead{background:#413256}.admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover{background:#a3b745;color:#fff}.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header{background:#363b3f}.admin-color-midnight .cmb2-element .ui-datepicker thead,.admin-color-midnight .cmb2-element.ui-datepicker thead{background:#26292c}.admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover{background:#e14d43;color:#fff}.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header{background:#738e96}.admin-color-ocean .cmb2-element .ui-datepicker thead,.admin-color-ocean .cmb2-element.ui-datepicker thead{background:#627c83}.admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover{background:#9ebaa0;color:#fff}.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header{background:#cf4944}.admin-color-sunrise .cmb2-element .ui-datepicker th,.admin-color-sunrise .cmb2-element.ui-datepicker th{border-color:#be3631;background:#be3631}.admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover{background:#dd823b;color:#fff}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header{background:#e5e5e5}.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year{color:#555}.admin-color-light .cmb2-element .ui-datepicker thead,.admin-color-light .cmb2-element.ui-datepicker thead{background:#888}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default{color:#555}.admin-color-light .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover{background:#ccc}.admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header{background:#56b274}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead{background:#36533f}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover{background:#446950;color:#fff}.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header{background:#4ca26a}.admin-color-bbp-mint .cmb2-element .ui-datepicker thead,.admin-color-bbp-mint .cmb2-element.ui-datepicker thead{background:#4f6d59}.admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover{background:#5fb37c;color:#fff}.closed .inside{display:none}.cmb-repeatable-grouping{position:relative}.cmb-repeatable-grouping .cmb-group-title{margin-right:-1em;margin-left:-1em;min-height:1.5em}.cmb-repeatable-grouping h3{font-size:14px;padding:8px 12px;margin:0;line-height:1.4}.cmb-repeatable-group.repeatable .cmb-group-title{padding-right:2.2em}.cmb-repeatable-group.non-repeatable .cmb-group-title{padding-right:12px}.cmb-type-group .cmb-row .cmbhandle{left:0;position:absolute}.cmb-spinner{background:url(/wp-admin/images/spinner.gif) no-repeat;-webkit-background-size:20px 20px;background-size:20px 20px;display:none;float:left;vertical-align:middle;opacity:.7;filter:alpha(opacity=70);width:20px;height:20px;margin:4px 10px 0} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front.css new file mode 100755 index 00000000..de538086 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front.css @@ -0,0 +1,1331 @@ +/*! + * CMB2 - v2.6.0 - 2019-01-18 + * https://cmb2.io + * Copyright (c) 2019 + * Licensed GPLv2+ + */ + +@charset "UTF-8"; +/*-------------------------------------------------------------- + * Main Wrap +--------------------------------------------------------------*/ +/* line 5, sass/partials/_main_wrap.scss */ +.cmb2-wrap { + margin: 0; +} +/* line 8, sass/partials/_main_wrap.scss */ +.cmb2-wrap input, +.cmb2-wrap textarea { + font-size: 14px; + max-width: 100%; + padding: 5px; +} +/* line 18, sass/partials/_main_wrap.scss */ +.cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +/* line 23, sass/partials/_main_wrap.scss */ +.cmb2-wrap textarea { + width: 500px; +} +/* line 26, sass/partials/_main_wrap.scss */ +.cmb2-wrap textarea.cmb2-textarea-code { + font-family: "Courier 10 Pitch", Courier, monospace; + line-height: 16px; +} +/* line 34, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-text-small, .cmb2-wrap input.cmb2-timepicker { + width: 100px; +} +/* line 40, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-text-money { + width: 90px; +} +/* line 45, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-text-medium { + width: 230px; +} +/* line 50, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.cmb2-upload-file { + width: 65%; +} +/* line 54, sass/partials/_main_wrap.scss */ +.cmb2-wrap input.ed_button { + padding: 2px 4px; +} +/* line 59, sass/partials/_main_wrap.scss */ +.cmb2-wrap input:not([type="hidden"]) + input, +.cmb2-wrap input:not([type="hidden"]) + .button-secondary, +.cmb2-wrap input:not([type="hidden"]) + select { + margin-left: 20px; +} +/* line 67, sass/partials/_main_wrap.scss */ +.cmb2-wrap ul { + margin: 0; +} +/* line 71, sass/partials/_main_wrap.scss */ +.cmb2-wrap li { + font-size: 14px; + line-height: 16px; + margin: 1px 0 5px 0; +} +/* line 82, sass/partials/_main_wrap.scss */ +.cmb2-wrap select { + font-size: 14px; + margin-top: 3px; +} +/* line 87, sass/partials/_main_wrap.scss */ +.cmb2-wrap input:focus, +.cmb2-wrap textarea:focus { + background: #fffff8; +} +/* line 92, sass/partials/_main_wrap.scss */ +.cmb2-wrap input[type="radio"] { + margin: 0 5px 0 0; + padding: 0; +} +/* line 97, sass/partials/_main_wrap.scss */ +.cmb2-wrap input[type="checkbox"] { + margin: 0 5px 0 0; + padding: 0; +} +/* line 102, sass/partials/_main_wrap.scss */ +.cmb2-wrap button, +.cmb2-wrap .button-secondary { + white-space: nowrap; +} +/* line 107, sass/partials/_main_wrap.scss */ +.cmb2-wrap .mceLayout { + border: 1px solid #e9e9e9 !important; +} +/* line 111, sass/partials/_main_wrap.scss */ +.cmb2-wrap .mceIframeContainer { + background: #ffffff; +} +/* line 115, sass/partials/_main_wrap.scss */ +.cmb2-wrap .meta_mce { + width: 97%; +} +/* line 118, sass/partials/_main_wrap.scss */ +.cmb2-wrap .meta_mce textarea { + width: 100%; +} +/* line 124, sass/partials/_main_wrap.scss */ +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-input-wrap { + vertical-align: middle; +} +/* line 129, sass/partials/_main_wrap.scss */ +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-container { + margin: 0 10px 0 0; +} +/* line 134, sass/partials/_main_wrap.scss */ +.cmb2-wrap .cmb-row { + margin: 0; +} +/* line 137, sass/partials/_main_wrap.scss */ +.cmb2-wrap .cmb-row:after { + content: ''; + clear: both; + display: block; + width: 100%; +} +/* line 144, sass/partials/_main_wrap.scss */ +.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description { + padding-top: 0; + padding-bottom: 1em; +} + +/* line 152, sass/partials/_main_wrap.scss */ +.cmb2-metabox { + clear: both; + margin: 0; +} +/* line 158, sass/partials/_main_wrap.scss */ +.cmb2-metabox > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox > .cmb-row:first-of-type > .cmb-th, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-th { + border: 0; +} + +/* line 165, sass/partials/_main_wrap.scss */ +.cmb-add-row { + margin: 1.8em 0 0; +} + +/* line 169, sass/partials/_main_wrap.scss */ +.cmb-nested .cmb-td, +.cmb-repeatable-group .cmb-th, +.cmb-repeatable-group:first-of-type { + border: 0; +} + +/* line 175, sass/partials/_main_wrap.scss */ +.cmb-row:last-of-type, +.cmb2-wrap .cmb-row:last-of-type, +.cmb-repeatable-group:last-of-type { + border-bottom: 0; +} + +/* line 181, sass/partials/_main_wrap.scss */ +.cmb-repeatable-grouping { + border: 1px solid #e9e9e9; + padding: 0 1em; +} +/* line 185, sass/partials/_main_wrap.scss */ +.cmb-repeatable-grouping.cmb-row { + margin: 0 0 0.8em; +} + +/* line 193, sass/partials/_main_wrap.scss */ +.cmb-th { + color: #222222; + float: left; + font-weight: 600; + line-height: 1.3; + padding: 20px 10px 20px 0; + vertical-align: top; + width: 200px; +} +@media (max-width: 450px) { + /* line 193, sass/partials/_main_wrap.scss */ + .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; + } + /* line 27, sass/partials/_mixins.scss */ + .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; + } +} + +/* line 207, sass/partials/_main_wrap.scss */ +.cmb-td { + line-height: 1.3; + max-width: 100%; + padding: 15px 10px; + vertical-align: middle; +} + +/* line 216, sass/partials/_main_wrap.scss */ +.cmb-type-title .cmb-td { + padding: 0; +} + +/* line 221, sass/partials/_main_wrap.scss */ +.cmb-th label { + display: block; + padding: 5px 0; +} + +/* line 226, sass/partials/_main_wrap.scss */ +.cmb-th + .cmb-td { + float: left; +} + +/* line 230, sass/partials/_main_wrap.scss */ +.cmb-td .cmb-td { + padding-bottom: 1em; +} + +/* line 234, sass/partials/_main_wrap.scss */ +.cmb-remove-row { + text-align: right; +} + +/* line 238, sass/partials/_main_wrap.scss */ +.empty-row.hidden { + display: none; +} + +/* line 243, sass/partials/_main_wrap.scss */ +.cmb-repeat-table { + background-color: #fafafa; + border: 1px solid #e1e1e1; +} +/* line 247, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row { + position: relative; + counter-increment: el; + margin: 0; + padding: 10px 10px 10px 50px; + border-bottom: none !important; +} +/* line 255, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row + .cmb-repeat-row { + border-top: solid 1px #e9e9e9; +} +/* line 259, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper { + outline: dashed 2px #e9e9e9 !important; +} +/* line 263, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row:before { + content: counter(el); + display: block; + top: 0; + left: 0; + position: absolute; + width: 35px; + height: 100%; + line-height: 35px; + cursor: move; + color: #757575; + text-align: center; + border-right: solid 1px #e9e9e9; +} +/* line 280, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td { + margin: 0; + padding: 0; +} +/* line 287, sass/partials/_main_wrap.scss */ +.cmb-repeat-table + .cmb-add-row { + margin: 0; +} +/* line 290, sass/partials/_main_wrap.scss */ +.cmb-repeat-table + .cmb-add-row:before { + content: ''; + width: 1px; + height: 1.6em; + display: block; + margin-left: 17px; + background-color: gainsboro; +} +/* line 300, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-remove-row { + top: 7px; + right: 7px; + position: absolute; + width: auto; + margin-left: 0; + padding: 0 !important; + display: none; +} +/* line 311, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button { + font-size: 20px; + text-indent: -1000px; + overflow: hidden; + position: relative; + height: auto; + line-height: 1; + padding: 0 10px 0; +} +/* line 322, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button:before { + content: ""; + font-family: 'Dashicons'; + speak: none; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + margin: 0; + text-indent: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; +} +/* line 328, sass/partials/_main_wrap.scss */ +.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row { + display: block; +} + +/* line 336, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-th { + padding: 5px; +} +/* line 340, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-title { + background-color: #e9e9e9; + padding: 8px 12px 8px 2.2em; + margin: 0 -1em; + min-height: 1.5em; + font-size: 14px; + line-height: 1.4; +} +/* line 348, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-title h4 { + border: 0; + margin: 0; + font-size: 1.2em; + font-weight: 500; + padding: 0.5em 0.75em; +} +/* line 356, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-title .cmb-th { + display: block; + width: 100%; +} +/* line 362, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-group-description .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; +} +/* line 27, sass/partials/_mixins.scss */ +.cmb-repeatable-group .cmb-group-description .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} +/* line 366, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-shift-rows { + font-size: 1em; + margin-right: 1em; + text-decoration: none; +} +/* line 371, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-shift-rows .dashicons { + font-size: 1.5em; + height: 1.5em; + line-height: 1.2em; + width: 1em; +} +/* line 377, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2 { + line-height: 1.3em; +} +/* line 384, sass/partials/_main_wrap.scss */ +.cmb-repeatable-group .cmb2-upload-button { + float: right; +} + +/* line 390, sass/partials/_main_wrap.scss */ +p.cmb2-metabox-description { + color: #757575; + font-style: italic; + margin: 0; + padding-top: .5em; +} + +/* line 397, sass/partials/_main_wrap.scss */ +span.cmb2-metabox-description { + color: #757575; + font-style: italic; +} + +/* line 402, sass/partials/_main_wrap.scss */ +.cmb2-metabox-title { + margin: 0 0 5px 0; + padding: 5px 0 0 0; + font-size: 14px; +} + +/* line 408, sass/partials/_main_wrap.scss */ +.cmb-inline ul { + padding: 4px 0 0 0; +} + +/* line 412, sass/partials/_main_wrap.scss */ +.cmb-inline li { + display: inline-block; + padding-right: 18px; +} + +/* line 417, sass/partials/_main_wrap.scss */ +.cmb-type-textarea-code pre { + margin: 0; +} + +/* line 423, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status { + clear: none; + display: inline-block; + vertical-align: middle; + margin-right: 10px; + width: auto; +} +/* line 430, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status img { + max-width: 350px; + height: auto; +} +/* line 436, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status img, +.cmb2-media-status .embed-status { + background: #eee; + border: 5px solid #ffffff; + outline: 1px solid #e9e9e9; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.05); + background-image: linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0), linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; + border-radius: 2px; + -moz-border-radius: 2px; + margin: 15px 0 0 0; +} +/* line 450, sass/partials/_main_wrap.scss */ +.cmb2-media-status .embed-status { + float: left; + max-width: 800px; +} +/* line 455, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status, .cmb2-media-status .embed-status { + position: relative; +} +/* line 458, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status .cmb2-remove-file-button, .cmb2-media-status .embed-status .cmb2-remove-file-button { + background: url(../images/ico-delete.png); + height: 16px; + left: -5px; + position: absolute; + text-indent: -9999px; + top: -5px; + width: 16px; +} +/* line 472, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status .cmb2-remove-file-button { + top: 10px; +} +/* line 477, sass/partials/_main_wrap.scss */ +.cmb2-media-status .img-status img, .cmb2-media-status .file-status > span { + cursor: pointer; +} +/* line 482, sass/partials/_main_wrap.scss */ +.cmb2-media-status.cmb-attach-list .img-status img, .cmb2-media-status.cmb-attach-list .file-status > span { + cursor: move; +} + +/* line 489, sass/partials/_main_wrap.scss */ +.cmb-type-file-list .cmb2-media-status .img-status { + clear: none; + vertical-align: middle; + width: auto; + margin-right: 10px; + margin-bottom: 10px; + margin-top: 0; +} + +/* line 498, sass/partials/_main_wrap.scss */ +.cmb-attach-list li { + clear: both; + display: inline-block; + width: 100%; + margin-top: 5px; + margin-bottom: 10px; +} +/* line 504, sass/partials/_main_wrap.scss */ +.cmb-attach-list li img { + float: left; + margin-right: 10px; +} + +/* line 510, sass/partials/_main_wrap.scss */ +.cmb2-remove-wrapper { + margin: 0; +} + +/* line 514, sass/partials/_main_wrap.scss */ +.child-cmb2 .cmb-th { + text-align: left; +} + +/* line 518, sass/partials/_main_wrap.scss */ +.cmb2-indented-hierarchy { + padding-left: 1.5em; +} + +@media (max-width: 450px) { + /* line 523, sass/partials/_main_wrap.scss */ + .cmb-th, + .cmb-td, + .cmb-th + .cmb-td { + display: block; + float: none; + width: 100%; + } +} +/*-------------------------------------------------------------- + * Post Metaboxes +--------------------------------------------------------------*/ +/* line 5, sass/partials/_post_metaboxes.scss */ +#poststuff .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} + +/* line 11, sass/partials/_post_metaboxes.scss */ +#poststuff .repeatable .cmb-group-title { + padding-left: 2.2em; +} + +/* line 17, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb2-wrap, .cmb-type-group .cmb2-wrap { + margin: 0; +} +/* line 20, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb2-wrap > .cmb-field-list > .cmb-row, .cmb-type-group .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.8em 0; +} +/* line 26, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed, .cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} +/* line 32, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-row, .cmb-type-group .cmb-row { + padding: 0 0 1.8em; + margin: 0 0 0.8em; +} +/* line 36, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-row .cmbhandle, .cmb-type-group .cmb-row .cmbhandle { + right: -1em; + position: relative; + color: #222222; +} +/* line 43, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-repeatable-grouping, .cmb-type-group .cmb-repeatable-grouping { + padding: 0 1em; + max-width: 100%; + min-width: 1px !important; +} +/* line 49, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-repeatable-group > .cmb-row, .cmb-type-group .cmb-repeatable-group > .cmb-row { + padding-bottom: 0; +} +/* line 53, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-th, .cmb-type-group .cmb-th { + width: 18%; + padding: 0 2% 0 0; +} +/* line 59, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-td, .cmb-type-group .cmb-td { + margin-bottom: 0; + padding: 0; + line-height: 1.3; +} +/* line 65, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-th + .cmb-td, .cmb-type-group .cmb-th + .cmb-td { + width: 80%; + float: right; +} +/* line 70, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 1px solid #e9e9e9; +} +@media (max-width: 450px) { + /* line 70, sass/partials/_post_metaboxes.scss */ + .cmb2-postbox .cmb-row:not(:last-of-type), + .cmb2-postbox .cmb-repeatable-group:not(:last-of-type), .cmb-type-group .cmb-row:not(:last-of-type), + .cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 0; + } +} +/* line 79, sass/partials/_post_metaboxes.scss */ +.cmb2-postbox .cmb-repeat-group-field, +.cmb2-postbox .cmb-remove-field-row, .cmb-type-group .cmb-repeat-group-field, +.cmb-type-group .cmb-remove-field-row { + padding-top: 1.8em; +} + +/*-------------------------------------------------------------- + * Context Metaboxes +--------------------------------------------------------------*/ +/* Metabox collapse arrow indicators */ +/* line 9, sass/partials/_context_metaboxes.scss */ +.js .cmb2-postbox.context-box .toggle-indicator:before { + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +/* line 22, sass/partials/_context_metaboxes.scss */ +.js .cmb2-postbox.context-box.closed .toggle-indicator:before { + content: "\f140"; +} + +/* line 30, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box { + margin-bottom: 10px; +} +/* line 34, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-before_permalink-box { + margin-top: 10px; +} +/* line 38, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-after_title-box { + margin-top: 10px; +} +/* line 42, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-after_editor-box { + margin-top: 20px; + margin-bottom: 0; +} +/* line 47, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-form_top-box { + margin-top: 10px; +} +/* line 51, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box.context-form_top-box .hndle { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} +/* line 59, sass/partials/_context_metaboxes.scss */ +.cmb2-postbox.context-box .hndle { + cursor: auto; +} + +/* line 64, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap { + margin-top: 10px; +} +/* line 68, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 300px; + width: auto; +} +/* line 75, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox { + padding: 10px; +} +/* line 80, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-th { + padding: 0 2% 0 0; + width: 18%; +} +/* line 85, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-td { + width: 80%; + padding: 0; +} +/* line 90, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-row { + margin-bottom: 10px; +} +/* line 93, sass/partials/_context_metaboxes.scss */ +.cmb2-context-wrap .cmb-row:last-of-type { + margin-bottom: 0; +} + +/* one column on the post write/edit screen */ +@media only screen and (max-width: 850px) { + /* line 103, sass/partials/_context_metaboxes.scss */ + .cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 0; + } +} +/*-------------------------------------------------------------- + * Misc. +--------------------------------------------------------------*/ +/* line 5, sass/partials/_misc.scss */ +#poststuff .cmb-repeatable-group h2 { + margin: 0; +} + +/* line 12, sass/partials/_misc.scss */ +.edit-tags-php .cmb2-metabox-title, +.profile-php .cmb2-metabox-title, +.user-edit-php .cmb2-metabox-title { + font-size: 1.4em; +} + +/* line 18, sass/partials/_misc.scss */ +.cmb2-postbox .cmb-spinner, .cmb2-no-box-wrap .cmb-spinner { + float: left; + display: none; +} + +/* line 24, sass/partials/_misc.scss */ +.cmb-spinner { + display: none; +} +/* line 26, sass/partials/_misc.scss */ +.cmb-spinner.is-active { + display: block; +} + +/*-------------------------------------------------------------- + * Collapsible UI +--------------------------------------------------------------*/ +/* line 6, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox .cmbhandle { + color: #757575; + float: right; + width: 27px; + height: 30px; + cursor: pointer; + right: -1em; + position: relative; +} +/* line 14, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox .cmbhandle:before { + content: '\f142'; + right: 12px; + font: normal 20px/1 'dashicons'; + speak: none; + display: inline-block; + padding: 8px 10px; + top: 0; + position: relative; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +/* line 31, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox .postbox.closed .cmbhandle:before { + content: '\f140'; +} +/* line 37, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + -webkit-appearance: none !important; + background: none !important; + border: none !important; + position: absolute; + left: 0; + top: .5em; + line-height: 1em; + padding: 2px 6px 3px; + opacity: .5; +} +/* line 47, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]) { + cursor: pointer; + color: #a00; + opacity: 1; +} +/* line 51, sass/partials/_collapsible_ui.scss */ +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover { + color: #f00; +} + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress" + * https://github.com/stuttter/wp-datepicker-styling + * + */ +/* line 15, sass/partials/_jquery_ui.scss */ +* html .cmb2-element.ui-helper-clearfix { + height: 1%; +} + +/* line 24, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + width: auto; + /* Default Color Scheme */ +} +/* line 38, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker *, .cmb2-element .ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +/* line 46, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker table, .cmb2-element .ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} +/* line 53, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} +/* line 61, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} +/* line 67, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-title, .cmb2-element .ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} +/* line 75, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-title select, .cmb2-element .ui-datepicker .ui-datepicker-title select { + margin-top: -8px; + margin-bottom: -8px; +} +/* line 81, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-next { + position: relative; + top: 0; + height: 34px; + width: 34px; +} +/* line 89, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next, .cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} +/* line 94, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover, .cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover { + left: 0; +} +/* line 99, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover, .cmb2-element .ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover { + right: 0; +} +/* line 104, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next span, +.cmb2-element.ui-datepicker .ui-datepicker-prev span, .cmb2-element .ui-datepicker .ui-datepicker-next span, +.cmb2-element .ui-datepicker .ui-datepicker-prev span { + display: none; +} +/* line 109, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev, .cmb2-element .ui-datepicker .ui-datepicker-prev { + float: left; +} +/* line 113, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next, .cmb2-element .ui-datepicker .ui-datepicker-next { + float: right; +} +/* line 117, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-left: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} +/* line 129, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, .cmb2-element .ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} +/* line 133, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-next:before, .cmb2-element .ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} +/* line 137, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before, .cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} +/* line 142, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker select.ui-datepicker-month, +.cmb2-element.ui-datepicker select.ui-datepicker-year, .cmb2-element .ui-datepicker select.ui-datepicker-month, +.cmb2-element .ui-datepicker select.ui-datepicker-year { + width: 33%; + background: transparent; + border-color: transparent; + box-shadow: none; + color: #fff; +} +/* line 149, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker select.ui-datepicker-month option, +.cmb2-element.ui-datepicker select.ui-datepicker-year option, .cmb2-element .ui-datepicker select.ui-datepicker-month option, +.cmb2-element .ui-datepicker select.ui-datepicker-year option { + color: #333; +} +/* line 154, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + color: #fff; + font-weight: 600; +} +/* line 157, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker thead th, .cmb2-element .ui-datepicker thead th { + font-weight: normal; +} +/* line 162, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker th, .cmb2-element .ui-datepicker th { + padding: 10px; +} +/* line 166, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td, .cmb2-element .ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} +/* line 171, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-other-month, .cmb2-element .ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} +/* line 175, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-week-end, .cmb2-element .ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} +/* line 178, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today { + -webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); +} +/* line 185, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-today, .cmb2-element .ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} +/* line 189, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-datepicker-current-day, .cmb2-element .ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} +/* line 193, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td .ui-state-default, .cmb2-element .ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} +/* line 205, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default, .cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} +/* line 210, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, .cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +/* line 215, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker thead, .cmb2-element .ui-datepicker thead { + background: #32373c; +} +/* line 219, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker td .ui-state-hover, .cmb2-element.ui-datepicker td .ui-state-active, .cmb2-element .ui-datepicker td .ui-state-hover, .cmb2-element .ui-datepicker td .ui-state-active { + background: #0073aa; + color: #fff; +} +/* line 224, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div, .cmb2-element .ui-datepicker .ui-timepicker-div { + font-size: 14px; +} +/* line 226, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl, .cmb2-element .ui-datepicker .ui-timepicker-div dl { + text-align: left; + padding: 0 .6em; +} +/* line 229, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl dt, .cmb2-element .ui-datepicker .ui-timepicker-div dl dt { + float: left; + clear: left; + padding: 0 0 0 5px; +} +/* line 234, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd { + margin: 0 10px 10px 40%; +} +/* line 236, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select, .cmb2-element .ui-datepicker .ui-timepicker-div dl dd select { + width: 100%; +} +/* line 242, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane { + padding: .6em; + text-align: left; +} +/* line 246, sass/partials/_jquery_ui.scss */ +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, .cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary { + padding: 0 10px 1px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + margin: 0 .6em .4em .4em; +} + +/* line 260, sass/partials/_jquery_ui.scss */ +.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} +/* line 265, sass/partials/_jquery_ui.scss */ +.admin-color-fresh .cmb2-element.ui-datepicker thead, .admin-color-fresh .cmb2-element .ui-datepicker thead { + background: #32373c; +} +/* line 269, sass/partials/_jquery_ui.scss */ +.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* line 277, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #52accc; +} +/* line 282, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker thead, .admin-color-blue .cmb2-element .ui-datepicker thead { + background: #4796b3; +} +/* line 291, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active { + background: #096484; + color: #fff; +} +/* line 296, sass/partials/_jquery_ui.scss */ +.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 305, sass/partials/_jquery_ui.scss */ +.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #59524c; +} +/* line 310, sass/partials/_jquery_ui.scss */ +.admin-color-coffee .cmb2-element.ui-datepicker thead, .admin-color-coffee .cmb2-element .ui-datepicker thead { + background: #46403c; +} +/* line 314, sass/partials/_jquery_ui.scss */ +.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +/* line 322, sass/partials/_jquery_ui.scss */ +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} +/* line 327, sass/partials/_jquery_ui.scss */ +.admin-color-ectoplasm .cmb2-element.ui-datepicker thead, .admin-color-ectoplasm .cmb2-element .ui-datepicker thead { + background: #413256; +} +/* line 331, sass/partials/_jquery_ui.scss */ +.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +/* line 339, sass/partials/_jquery_ui.scss */ +.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} +/* line 344, sass/partials/_jquery_ui.scss */ +.admin-color-midnight .cmb2-element.ui-datepicker thead, .admin-color-midnight .cmb2-element .ui-datepicker thead { + background: #26292c; +} +/* line 348, sass/partials/_jquery_ui.scss */ +.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +/* line 356, sass/partials/_jquery_ui.scss */ +.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #738e96; +} +/* line 361, sass/partials/_jquery_ui.scss */ +.admin-color-ocean .cmb2-element.ui-datepicker thead, .admin-color-ocean .cmb2-element .ui-datepicker thead { + background: #627c83; +} +/* line 365, sass/partials/_jquery_ui.scss */ +.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +/* line 373, sass/partials/_jquery_ui.scss */ +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} +/* line 379, sass/partials/_jquery_ui.scss */ +.admin-color-sunrise .cmb2-element.ui-datepicker th, .admin-color-sunrise .cmb2-element .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} +/* line 384, sass/partials/_jquery_ui.scss */ +.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +/* line 392, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-light .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} +/* line 397, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year, .admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year { + color: #555; +} +/* line 402, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker thead, .admin-color-light .cmb2-element .ui-datepicker thead { + background: #888; +} +/* line 406, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before, .admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before { + color: #555; +} +/* line 414, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element.ui-datepicker td .ui-state-active, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover, .admin-color-light .cmb2-element .ui-datepicker td .ui-state-active { + background: #ccc; +} +/* line 418, sass/partials/_jquery_ui.scss */ +.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today, .admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 426, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #56b274; +} +/* line 431, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead { + background: #36533f; +} +/* line 435, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +/* line 443, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header, .admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} +/* line 448, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-mint .cmb2-element.ui-datepicker thead, .admin-color-bbp-mint .cmb2-element .ui-datepicker thead { + background: #4f6d59; +} +/* line 452, sass/partials/_jquery_ui.scss */ +.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover, .admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} + +/** + * CMB2 Frontend + */ +/*-------------------------------------------------------------- + * CMB2 Frontend +--------------------------------------------------------------*/ +/* line 5, sass/partials/_front.scss */ +.closed .inside { + display: none; +} + +/* line 9, sass/partials/_front.scss */ +.cmb-repeatable-grouping { + position: relative; +} +/* line 12, sass/partials/_front.scss */ +.cmb-repeatable-grouping .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} +/* line 18, sass/partials/_front.scss */ +.cmb-repeatable-grouping h3 { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} + +/* line 29, sass/partials/_front.scss */ +.cmb-repeatable-group.repeatable .cmb-group-title { + padding-left: 2.2em; +} +/* line 33, sass/partials/_front.scss */ +.cmb-repeatable-group.non-repeatable .cmb-group-title { + padding-left: 12px; +} + +/* line 39, sass/partials/_front.scss */ +.cmb-type-group .cmb-row .cmbhandle { + right: 0; + position: absolute; +} + +/* line 44, sass/partials/_front.scss */ +.cmb-spinner { + background: url(/wp-admin/images/spinner.gif) no-repeat; + -webkit-background-size: 20px 20px; + background-size: 20px 20px; + display: none; + float: right; + vertical-align: middle; + opacity: 0.7; + filter: alpha(opacity=70); + width: 20px; + height: 20px; + margin: 4px 10px 0; +} + +/*# sourceMappingURL=cmb2-front.css.map */ diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front.min.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front.min.css new file mode 100755 index 00000000..a3b7fce5 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-front.min.css @@ -0,0 +1,2 @@ +/*! CMB2 - v2.6.0 - 2019-01-18 | https://cmb2.io | Copyright (c) 2019 CMB2 team | Licensed GPLv2 */ +@charset "UTF-8";.cmb2-wrap{margin:0}.cmb2-wrap input,.cmb2-wrap textarea{font-size:14px;max-width:100%;padding:5px}.cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb2-wrap textarea{width:500px}.cmb2-wrap textarea.cmb2-textarea-code{font-family:"Courier 10 Pitch",Courier,monospace;line-height:16px}.cmb2-wrap input.cmb2-text-small,.cmb2-wrap input.cmb2-timepicker{width:100px}.cmb2-wrap input.cmb2-text-money{width:90px}.cmb2-wrap input.cmb2-text-medium{width:230px}.cmb2-wrap input.cmb2-upload-file{width:65%}.cmb2-wrap input.ed_button{padding:2px 4px}.cmb2-wrap input:not([type=hidden])+.button-secondary,.cmb2-wrap input:not([type=hidden])+input,.cmb2-wrap input:not([type=hidden])+select{margin-left:20px}.cmb2-wrap ul{margin:0}.cmb2-wrap li{font-size:14px;line-height:16px;margin:1px 0 5px}.cmb2-wrap select{font-size:14px;margin-top:3px}.cmb2-wrap input:focus,.cmb2-wrap textarea:focus{background:#fffff8}.cmb2-wrap input[type=checkbox],.cmb2-wrap input[type=radio]{margin:0 5px 0 0;padding:0}.cmb2-wrap .button-secondary,.cmb2-wrap button{white-space:nowrap}.cmb2-wrap .mceLayout{border:1px solid #e9e9e9!important}.cmb2-wrap .mceIframeContainer{background:#fff}.cmb2-wrap .meta_mce{width:97%}.cmb2-wrap .meta_mce textarea{width:100%}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-input-wrap{vertical-align:middle}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-container{margin:0 10px 0 0}.cmb2-wrap .cmb-row{margin:0}.cmb2-wrap .cmb-row:after{content:'';clear:both;display:block;width:100%}.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description{padding-top:0;padding-bottom:1em}.cmb2-metabox{clear:both;margin:0}.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-th,.cmb2-metabox>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox>.cmb-row:first-of-type>.cmb-th{border:0}.cmb-add-row{margin:1.8em 0 0}.cmb-nested .cmb-td,.cmb-repeatable-group .cmb-th,.cmb-repeatable-group:first-of-type{border:0}.cmb-repeatable-group:last-of-type,.cmb-row:last-of-type,.cmb2-wrap .cmb-row:last-of-type{border-bottom:0}.cmb-repeatable-grouping{border:1px solid #e9e9e9;padding:0 1em}.cmb-repeatable-grouping.cmb-row{margin:0 0 .8em}.cmb-th{color:#222;float:left;font-weight:600;line-height:1.3;padding:20px 10px 20px 0;vertical-align:top;width:200px}@media (max-width:450px){.cmb-th{font-size:1.2em;display:block;float:none;padding-bottom:1em;text-align:left;width:100%}.cmb-th label{display:block;margin-top:0;margin-bottom:.5em}}.cmb-td{line-height:1.3;max-width:100%;padding:15px 10px;vertical-align:middle}.cmb-type-title .cmb-td{padding:0}.cmb-th label{display:block;padding:5px 0}.cmb-th+.cmb-td{float:left}.cmb-td .cmb-td{padding-bottom:1em}.cmb-remove-row{text-align:right}.empty-row.hidden{display:none}.cmb-repeat-table{background-color:#fafafa;border:1px solid #e1e1e1}.cmb-repeat-table .cmb-row.cmb-repeat-row{position:relative;counter-increment:el;margin:0;padding:10px 10px 10px 50px;border-bottom:none!important}.cmb-repeat-table .cmb-row.cmb-repeat-row+.cmb-repeat-row{border-top:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper{outline:dashed 2px #e9e9e9!important}.cmb-repeat-table .cmb-row.cmb-repeat-row:before{content:counter(el);display:block;top:0;left:0;position:absolute;width:35px;height:100%;line-height:35px;cursor:move;color:#757575;text-align:center;border-right:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td{margin:0;padding:0}.cmb-repeat-table+.cmb-add-row{margin:0}.cmb-repeat-table+.cmb-add-row:before{content:'';width:1px;height:1.6em;display:block;margin-left:17px;background-color:#dcdcdc}.cmb-repeat-table .cmb-remove-row{top:7px;right:7px;position:absolute;width:auto;margin-left:0;padding:0!important;display:none}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button{font-size:20px;text-indent:-1000px;overflow:hidden;position:relative;height:auto;line-height:1;padding:0 10px}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button:before{content:"";font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row{display:block}.cmb-repeatable-group .cmb-th{padding:5px}.cmb-repeatable-group .cmb-group-title{background-color:#e9e9e9;padding:8px 12px 8px 2.2em;margin:0 -1em;min-height:1.5em;font-size:14px;line-height:1.4}.cmb-repeatable-group .cmb-group-title h4{border:0;margin:0;font-size:1.2em;font-weight:500;padding:.5em .75em}.cmb-repeatable-group .cmb-group-title .cmb-th{display:block;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th{font-size:1.2em;display:block;float:none;padding-bottom:1em;text-align:left;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th label{display:block;margin-top:0;margin-bottom:.5em}.cmb-repeatable-group .cmb-shift-rows{font-size:1em;margin-right:1em;text-decoration:none}.cmb-repeatable-group .cmb-shift-rows .dashicons{font-size:1.5em;height:1.5em;line-height:1.2em;width:1em}.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2{line-height:1.3em}.cmb-repeatable-group .cmb2-upload-button{float:right}p.cmb2-metabox-description{color:#757575;font-style:italic;margin:0;padding-top:.5em}span.cmb2-metabox-description{color:#757575;font-style:italic}.cmb2-metabox-title{margin:0 0 5px;padding:5px 0 0;font-size:14px}.cmb-inline ul{padding:4px 0 0}.cmb-inline li{display:inline-block;padding-right:18px}.cmb-type-textarea-code pre{margin:0}.cmb2-media-status .img-status{clear:none;display:inline-block;vertical-align:middle;margin-right:10px;width:auto}.cmb2-media-status .img-status img{max-width:350px;height:auto}.cmb2-media-status .embed-status,.cmb2-media-status .img-status img{background:#eee;border:5px solid #fff;outline:1px solid #e9e9e9;box-shadow:inset 0 0 15px rgba(0,0,0,.3),inset 0 0 0 1px rgba(0,0,0,.05);background-image:linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0),linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0);background-position:0 0,10px 10px;background-size:20px 20px;border-radius:2px;-moz-border-radius:2px;margin:15px 0 0}.cmb2-media-status .embed-status{float:left;max-width:800px}.cmb2-media-status .embed-status,.cmb2-media-status .img-status{position:relative}.cmb2-media-status .embed-status .cmb2-remove-file-button,.cmb2-media-status .img-status .cmb2-remove-file-button{background:url(../images/ico-delete.png);height:16px;left:-5px;position:absolute;text-indent:-9999px;top:-5px;width:16px}.cmb2-media-status .img-status .cmb2-remove-file-button{top:10px}.cmb2-media-status .file-status>span,.cmb2-media-status .img-status img{cursor:pointer}.cmb2-media-status.cmb-attach-list .file-status>span,.cmb2-media-status.cmb-attach-list .img-status img{cursor:move}.cmb-type-file-list .cmb2-media-status .img-status{clear:none;vertical-align:middle;width:auto;margin-right:10px;margin-bottom:10px;margin-top:0}.cmb-attach-list li{clear:both;display:inline-block;width:100%;margin-top:5px;margin-bottom:10px}.cmb-attach-list li img{float:left;margin-right:10px}.cmb2-remove-wrapper{margin:0}.child-cmb2 .cmb-th{text-align:left}.cmb2-indented-hierarchy{padding-left:1.5em}@media (max-width:450px){.cmb-td,.cmb-th,.cmb-th+.cmb-td{display:block;float:none;width:100%}}#poststuff .cmb-group-title{margin-left:-1em;margin-right:-1em;min-height:1.5em}#poststuff .repeatable .cmb-group-title{padding-left:2.2em}.cmb-type-group .cmb2-wrap,.cmb2-postbox .cmb2-wrap{margin:0}.cmb-type-group .cmb2-wrap>.cmb-field-list>.cmb-row,.cmb2-postbox .cmb2-wrap>.cmb-field-list>.cmb-row{padding:1.8em 0}.cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed,.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb-type-group .cmb-row,.cmb2-postbox .cmb-row{padding:0 0 1.8em;margin:0 0 .8em}.cmb-type-group .cmb-row .cmbhandle,.cmb2-postbox .cmb-row .cmbhandle{right:-1em;position:relative;color:#222}.cmb-type-group .cmb-repeatable-grouping,.cmb2-postbox .cmb-repeatable-grouping{padding:0 1em;max-width:100%;min-width:1px!important}.cmb-type-group .cmb-repeatable-group>.cmb-row,.cmb2-postbox .cmb-repeatable-group>.cmb-row{padding-bottom:0}.cmb-type-group .cmb-th,.cmb2-postbox .cmb-th{width:18%;padding:0 2% 0 0}.cmb-type-group .cmb-td,.cmb2-postbox .cmb-td{margin-bottom:0;padding:0;line-height:1.3}.cmb-type-group .cmb-th+.cmb-td,.cmb2-postbox .cmb-th+.cmb-td{width:80%;float:right}.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:1px solid #e9e9e9}@media (max-width:450px){.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:0}}.cmb-type-group .cmb-remove-field-row,.cmb-type-group .cmb-repeat-group-field,.cmb2-postbox .cmb-remove-field-row,.cmb2-postbox .cmb-repeat-group-field{padding-top:1.8em}.js .cmb2-postbox.context-box .toggle-indicator:before{content:"\f142";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.js .cmb2-postbox.context-box.closed .toggle-indicator:before{content:"\f140"}.cmb2-postbox.context-box{margin-bottom:10px}.cmb2-postbox.context-box.context-after_title-box,.cmb2-postbox.context-box.context-before_permalink-box{margin-top:10px}.cmb2-postbox.context-box.context-after_editor-box{margin-top:20px;margin-bottom:0}.cmb2-postbox.context-box.context-form_top-box{margin-top:10px}.cmb2-postbox.context-box.context-form_top-box .hndle{font-size:14px;padding:8px 12px;margin:0;line-height:1.4}.cmb2-postbox.context-box .hndle{cursor:auto}.cmb2-context-wrap{margin-top:10px}.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-right:300px;width:auto}.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox{padding:10px}.cmb2-context-wrap .cmb-th{padding:0 2% 0 0;width:18%}.cmb2-context-wrap .cmb-td{width:80%;padding:0}.cmb2-context-wrap .cmb-row{margin-bottom:10px}.cmb2-context-wrap .cmb-row:last-of-type{margin-bottom:0}@media only screen and (max-width:850px){.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-right:0}}#poststuff .cmb-repeatable-group h2{margin:0}.edit-tags-php .cmb2-metabox-title,.profile-php .cmb2-metabox-title,.user-edit-php .cmb2-metabox-title{font-size:1.4em}.cmb2-no-box-wrap .cmb-spinner,.cmb2-postbox .cmb-spinner{float:left;display:none}.cmb-spinner.is-active{display:block}.cmb2-metabox .cmbhandle{color:#757575;float:right;width:27px;height:30px;cursor:pointer;right:-1em;position:relative}.cmb2-metabox .cmbhandle:before{content:'\f142';right:12px;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:8px 10px;top:0;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.cmb2-metabox .postbox.closed .cmbhandle:before{content:'\f140'}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row{-webkit-appearance:none!important;background:none!important;border:none!important;position:absolute;left:0;top:.5em;line-height:1em;padding:2px 6px 3px;opacity:.5}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]){cursor:pointer;color:#a00;opacity:1}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover{color:red}* html .cmb2-element.ui-helper-clearfix{height:1%}.cmb2-element .ui-datepicker,.cmb2-element.ui-datepicker{padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;background-color:#fff;border:1px solid #dfdfdf;border-top:none;-webkit-box-shadow:0 3px 6px rgba(0,0,0,.075);box-shadow:0 3px 6px rgba(0,0,0,.075);min-width:17em;width:auto}.cmb2-element .ui-datepicker *,.cmb2-element.ui-datepicker *{padding:0;font-family:"Open Sans",sans-serif;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.cmb2-element .ui-datepicker table,.cmb2-element.ui-datepicker table{font-size:13px;margin:0;border:none;border-collapse:collapse}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{border:none;color:#fff;font-weight:400}.cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover{background:0 0;border-color:transparent;cursor:pointer}.cmb2-element .ui-datepicker .ui-datepicker-title,.cmb2-element.ui-datepicker .ui-datepicker-title{margin:0;padding:10px 0;color:#fff;font-size:14px;line-height:14px;text-align:center}.cmb2-element .ui-datepicker .ui-datepicker-title select,.cmb2-element.ui-datepicker .ui-datepicker-title select{margin-top:-8px;margin-bottom:-8px}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-prev{position:relative;top:0;height:34px;width:34px}.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev{border:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover,.cmb2-element.ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover{left:0}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-next-hover,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next-hover{right:0}.cmb2-element .ui-datepicker .ui-datepicker-next span,.cmb2-element .ui-datepicker .ui-datepicker-prev span,.cmb2-element.ui-datepicker .ui-datepicker-next span,.cmb2-element.ui-datepicker .ui-datepicker-prev span{display:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev{float:left}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next{float:right}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{font:400 20px/34px dashicons;padding-left:7px;color:#fff;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:34px;height:34px}.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{content:'\f341'}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before{content:'\f345'}.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before{opacity:.7}.cmb2-element .ui-datepicker select.ui-datepicker-month,.cmb2-element .ui-datepicker select.ui-datepicker-year,.cmb2-element.ui-datepicker select.ui-datepicker-month,.cmb2-element.ui-datepicker select.ui-datepicker-year{width:33%;background:0 0;border-color:transparent;box-shadow:none;color:#fff}.cmb2-element .ui-datepicker select.ui-datepicker-month option,.cmb2-element .ui-datepicker select.ui-datepicker-year option,.cmb2-element.ui-datepicker select.ui-datepicker-month option,.cmb2-element.ui-datepicker select.ui-datepicker-year option{color:#333}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{color:#fff;font-weight:600}.cmb2-element .ui-datepicker thead th,.cmb2-element.ui-datepicker thead th{font-weight:400}.cmb2-element .ui-datepicker th,.cmb2-element.ui-datepicker th{padding:10px}.cmb2-element .ui-datepicker td,.cmb2-element.ui-datepicker td{padding:0;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-other-month,.cmb2-element.ui-datepicker td.ui-datepicker-other-month{border:transparent}.cmb2-element .ui-datepicker td.ui-datepicker-week-end,.cmb2-element.ui-datepicker td.ui-datepicker-week-end{background-color:#f4f4f4;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today{-webkit-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);-moz-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1)}.cmb2-element .ui-datepicker td.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-today{background-color:#f0f0c0}.cmb2-element .ui-datepicker td.ui-datepicker-current-day,.cmb2-element.ui-datepicker td.ui-datepicker-current-day{background:#bd8}.cmb2-element .ui-datepicker td .ui-state-default,.cmb2-element.ui-datepicker td .ui-state-default{background:0 0;border:none;text-align:center;text-decoration:none;width:auto;display:block;padding:5px 10px;font-weight:400;color:#444}.cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default,.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default{opacity:.5}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{background:#32373c}.cmb2-element .ui-datepicker td .ui-state-active,.cmb2-element .ui-datepicker td .ui-state-hover,.cmb2-element.ui-datepicker td .ui-state-active,.cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.cmb2-element .ui-datepicker .ui-timepicker-div,.cmb2-element.ui-datepicker .ui-timepicker-div{font-size:14px}.cmb2-element .ui-datepicker .ui-timepicker-div dl,.cmb2-element.ui-datepicker .ui-timepicker-div dl{text-align:left;padding:0 .6em}.cmb2-element .ui-datepicker .ui-timepicker-div dl dt,.cmb2-element.ui-datepicker .ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd{margin:0 10px 10px 40%}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd select,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select{width:100%}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane{padding:.6em;text-align:left}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary{padding:0 10px 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;margin:0 .6em .4em .4em}.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.admin-color-fresh .cmb2-element .ui-datepicker thead,.admin-color-fresh .cmb2-element.ui-datepicker thead{background:#32373c}.admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header{background:#52accc}.admin-color-blue .cmb2-element .ui-datepicker thead,.admin-color-blue .cmb2-element.ui-datepicker thead{background:#4796b3}.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover{background:#096484;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header{background:#59524c}.admin-color-coffee .cmb2-element .ui-datepicker thead,.admin-color-coffee .cmb2-element.ui-datepicker thead{background:#46403c}.admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover{background:#c7a589;color:#fff}.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header{background:#523f6d}.admin-color-ectoplasm .cmb2-element .ui-datepicker thead,.admin-color-ectoplasm .cmb2-element.ui-datepicker thead{background:#413256}.admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover{background:#a3b745;color:#fff}.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header{background:#363b3f}.admin-color-midnight .cmb2-element .ui-datepicker thead,.admin-color-midnight .cmb2-element.ui-datepicker thead{background:#26292c}.admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover{background:#e14d43;color:#fff}.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header{background:#738e96}.admin-color-ocean .cmb2-element .ui-datepicker thead,.admin-color-ocean .cmb2-element.ui-datepicker thead{background:#627c83}.admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover{background:#9ebaa0;color:#fff}.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header{background:#cf4944}.admin-color-sunrise .cmb2-element .ui-datepicker th,.admin-color-sunrise .cmb2-element.ui-datepicker th{border-color:#be3631;background:#be3631}.admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover{background:#dd823b;color:#fff}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header{background:#e5e5e5}.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year{color:#555}.admin-color-light .cmb2-element .ui-datepicker thead,.admin-color-light .cmb2-element.ui-datepicker thead{background:#888}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default{color:#555}.admin-color-light .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover{background:#ccc}.admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header{background:#56b274}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead{background:#36533f}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover{background:#446950;color:#fff}.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header{background:#4ca26a}.admin-color-bbp-mint .cmb2-element .ui-datepicker thead,.admin-color-bbp-mint .cmb2-element.ui-datepicker thead{background:#4f6d59}.admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover{background:#5fb37c;color:#fff}.closed .inside{display:none}.cmb-repeatable-grouping{position:relative}.cmb-repeatable-grouping .cmb-group-title{margin-left:-1em;margin-right:-1em;min-height:1.5em}.cmb-repeatable-grouping h3{font-size:14px;padding:8px 12px;margin:0;line-height:1.4}.cmb-repeatable-group.repeatable .cmb-group-title{padding-left:2.2em}.cmb-repeatable-group.non-repeatable .cmb-group-title{padding-left:12px}.cmb-type-group .cmb-row .cmbhandle{right:0;position:absolute}.cmb-spinner{background:url(/wp-admin/images/spinner.gif) no-repeat;-webkit-background-size:20px 20px;background-size:20px 20px;display:none;float:right;vertical-align:middle;opacity:.7;filter:alpha(opacity=70);width:20px;height:20px;margin:4px 10px 0} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-rtl.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-rtl.css new file mode 100755 index 00000000..070499e1 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-rtl.css @@ -0,0 +1,2098 @@ +/*! + * CMB2 - v2.6.0 - 2019-01-18 + * https://cmb2.io + * Copyright (c) 2019 + * Licensed GPLv2+ + */ + +/*-------------------------------------------------------------- + * Main Wrap +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_main_wrap.scss */ + +.cmb2-wrap { + margin: 0; +} + +/* line 8, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input, +.cmb2-wrap textarea { + font-size: 14px; + max-width: 100%; + padding: 5px; +} + +/* line 18, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} + +/* line 23, sass/partials/_main_wrap.scss */ + +.cmb2-wrap textarea { + width: 500px; +} + +/* line 26, sass/partials/_main_wrap.scss */ + +.cmb2-wrap textarea.cmb2-textarea-code { + font-family: "Courier 10 Pitch", Courier, monospace; + line-height: 16px; +} + +/* line 34, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-text-small, +.cmb2-wrap input.cmb2-timepicker { + width: 100px; +} + +/* line 40, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-text-money { + width: 90px; +} + +/* line 45, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-text-medium { + width: 230px; +} + +/* line 50, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-upload-file { + width: 65%; +} + +/* line 54, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.ed_button { + padding: 2px 4px; +} + +/* line 59, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input:not([type="hidden"]) + input, +.cmb2-wrap input:not([type="hidden"]) + .button-secondary, +.cmb2-wrap input:not([type="hidden"]) + select { + margin-right: 20px; +} + +/* line 67, sass/partials/_main_wrap.scss */ + +.cmb2-wrap ul { + margin: 0; +} + +/* line 71, sass/partials/_main_wrap.scss */ + +.cmb2-wrap li { + font-size: 14px; + line-height: 16px; + margin: 1px 0 5px 0; +} + +/* line 82, sass/partials/_main_wrap.scss */ + +.cmb2-wrap select { + font-size: 14px; + margin-top: 3px; +} + +/* line 87, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input:focus, +.cmb2-wrap textarea:focus { + background: #fffff8; +} + +/* line 92, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input[type="radio"] { + margin: 0 0 0 5px; + padding: 0; +} + +/* line 97, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input[type="checkbox"] { + margin: 0 0 0 5px; + padding: 0; +} + +/* line 102, sass/partials/_main_wrap.scss */ + +.cmb2-wrap button, +.cmb2-wrap .button-secondary { + white-space: nowrap; +} + +/* line 107, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .mceLayout { + border: 1px solid #e9e9e9 !important; +} + +/* line 111, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .mceIframeContainer { + background: #ffffff; +} + +/* line 115, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .meta_mce { + width: 97%; +} + +/* line 118, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .meta_mce textarea { + width: 100%; +} + +/* line 124, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-input-wrap { + vertical-align: middle; +} + +/* line 129, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-container { + margin: 0 0 0 10px; +} + +/* line 134, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .cmb-row { + margin: 0; +} + +/* line 137, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .cmb-row:after { + content: ''; + clear: both; + display: block; + width: 100%; +} + +/* line 144, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description { + padding-top: 0; + padding-bottom: 1em; +} + +/* line 152, sass/partials/_main_wrap.scss */ + +.cmb2-metabox { + clear: both; + margin: 0; +} + +/* line 158, sass/partials/_main_wrap.scss */ + +.cmb2-metabox > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox > .cmb-row:first-of-type > .cmb-th, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-th { + border: 0; +} + +/* line 165, sass/partials/_main_wrap.scss */ + +.cmb-add-row { + margin: 1.8em 0 0; +} + +/* line 169, sass/partials/_main_wrap.scss */ + +.cmb-nested .cmb-td, +.cmb-repeatable-group .cmb-th, +.cmb-repeatable-group:first-of-type { + border: 0; +} + +/* line 175, sass/partials/_main_wrap.scss */ + +.cmb-row:last-of-type, +.cmb2-wrap .cmb-row:last-of-type, +.cmb-repeatable-group:last-of-type { + border-bottom: 0; +} + +/* line 181, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-grouping { + border: 1px solid #e9e9e9; + padding: 0 1em; +} + +/* line 185, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-grouping.cmb-row { + margin: 0 0 0.8em; +} + +/* line 193, sass/partials/_main_wrap.scss */ + +.cmb-th { + color: #222222; + float: right; + font-weight: 600; + line-height: 1.3; + padding: 20px 0 20px 10px; + vertical-align: top; + width: 200px; +} + +/* line 207, sass/partials/_main_wrap.scss */ + +.cmb-td { + line-height: 1.3; + max-width: 100%; + padding: 15px 10px; + vertical-align: middle; +} + +/* line 216, sass/partials/_main_wrap.scss */ + +.cmb-type-title .cmb-td { + padding: 0; +} + +/* line 221, sass/partials/_main_wrap.scss */ + +.cmb-th label { + display: block; + padding: 5px 0; +} + +/* line 226, sass/partials/_main_wrap.scss */ + +.cmb-th + .cmb-td { + float: right; +} + +/* line 230, sass/partials/_main_wrap.scss */ + +.cmb-td .cmb-td { + padding-bottom: 1em; +} + +/* line 234, sass/partials/_main_wrap.scss */ + +.cmb-remove-row { + text-align: left; +} + +/* line 238, sass/partials/_main_wrap.scss */ + +.empty-row.hidden { + display: none; +} + +/* line 243, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table { + background-color: #fafafa; + border: 1px solid #e1e1e1; +} + +/* line 247, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row { + position: relative; + counter-increment: el; + margin: 0; + padding: 10px 50px 10px 10px; + border-bottom: none !important; +} + +/* line 255, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row + .cmb-repeat-row { + border-top: solid 1px #e9e9e9; +} + +/* line 259, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper { + outline: dashed 2px #e9e9e9 !important; +} + +/* line 263, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row:before { + content: counter(el); + display: block; + top: 0; + right: 0; + position: absolute; + width: 35px; + height: 100%; + line-height: 35px; + cursor: move; + color: #757575; + text-align: center; + border-left: solid 1px #e9e9e9; +} + +/* line 280, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td { + margin: 0; + padding: 0; +} + +/* line 287, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table + .cmb-add-row { + margin: 0; +} + +/* line 290, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table + .cmb-add-row:before { + content: ''; + width: 1px; + height: 1.6em; + display: block; + margin-right: 17px; + background-color: gainsboro; +} + +/* line 300, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-remove-row { + top: 7px; + left: 7px; + position: absolute; + width: auto; + margin-right: 0; + padding: 0 !important; + display: none; +} + +/* line 311, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button { + font-size: 20px; + text-indent: -1000px; + overflow: hidden; + position: relative; + height: auto; + line-height: 1; + padding: 0 10px 0; +} + +/* line 322, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button:before { + content: ""; + font-family: 'Dashicons'; + speak: none; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + margin: 0; + text-indent: 0; + position: absolute; + top: 0; + right: 0; + width: 100%; + height: 100%; + text-align: center; +} + +/* line 328, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row { + display: block; +} + +/* line 336, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-th { + padding: 5px; +} + +/* line 340, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-title { + background-color: #e9e9e9; + padding: 8px 2.2em 8px 12px; + margin: 0 -1em; + min-height: 1.5em; + font-size: 14px; + line-height: 1.4; +} + +/* line 348, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-title h4 { + border: 0; + margin: 0; + font-size: 1.2em; + font-weight: 500; + padding: 0.5em 0.75em; +} + +/* line 356, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-title .cmb-th { + display: block; + width: 100%; +} + +/* line 362, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-description .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: right; + width: 100%; +} + +/* line 27, sass/partials/_mixins.scss */ + +.cmb-repeatable-group .cmb-group-description .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} + +/* line 366, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-shift-rows { + font-size: 1em; + margin-left: 1em; + text-decoration: none; +} + +/* line 371, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-shift-rows .dashicons { + font-size: 1.5em; + height: 1.5em; + line-height: 1.2em; + width: 1em; +} + +/* line 377, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2 { + line-height: 1.3em; +} + +/* line 384, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb2-upload-button { + float: left; +} + +/* line 390, sass/partials/_main_wrap.scss */ + +p.cmb2-metabox-description { + color: #757575; + font-style: italic; + margin: 0; + padding-top: .5em; +} + +/* line 397, sass/partials/_main_wrap.scss */ + +span.cmb2-metabox-description { + color: #757575; + font-style: italic; +} + +/* line 402, sass/partials/_main_wrap.scss */ + +.cmb2-metabox-title { + margin: 0 0 5px 0; + padding: 5px 0 0 0; + font-size: 14px; +} + +/* line 408, sass/partials/_main_wrap.scss */ + +.cmb-inline ul { + padding: 4px 0 0 0; +} + +/* line 412, sass/partials/_main_wrap.scss */ + +.cmb-inline li { + display: inline-block; + padding-left: 18px; +} + +/* line 417, sass/partials/_main_wrap.scss */ + +.cmb-type-textarea-code pre { + margin: 0; +} + +/* line 423, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status { + clear: none; + display: inline-block; + vertical-align: middle; + margin-left: 10px; + width: auto; +} + +/* line 430, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status img { + max-width: 350px; + height: auto; +} + +/* line 436, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status img, +.cmb2-media-status .embed-status { + background: #eee; + border: 5px solid #ffffff; + outline: 1px solid #e9e9e9; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.05); + background-image: linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0), linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; + border-radius: 2px; + -moz-border-radius: 2px; + margin: 15px 0 0 0; +} + +/* line 450, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .embed-status { + float: right; + max-width: 800px; +} + +/* line 455, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status, +.cmb2-media-status .embed-status { + position: relative; +} + +/* line 458, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status .cmb2-remove-file-button, +.cmb2-media-status .embed-status .cmb2-remove-file-button { + background: url(../images/ico-delete.png); + height: 16px; + right: -5px; + position: absolute; + text-indent: -9999px; + top: -5px; + width: 16px; +} + +/* line 472, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status .cmb2-remove-file-button { + top: 10px; +} + +/* line 477, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status img, +.cmb2-media-status .file-status > span { + cursor: pointer; +} + +/* line 482, sass/partials/_main_wrap.scss */ + +.cmb2-media-status.cmb-attach-list .img-status img, +.cmb2-media-status.cmb-attach-list .file-status > span { + cursor: move; +} + +/* line 489, sass/partials/_main_wrap.scss */ + +.cmb-type-file-list .cmb2-media-status .img-status { + clear: none; + vertical-align: middle; + width: auto; + margin-left: 10px; + margin-bottom: 10px; + margin-top: 0; +} + +/* line 498, sass/partials/_main_wrap.scss */ + +.cmb-attach-list li { + clear: both; + display: inline-block; + width: 100%; + margin-top: 5px; + margin-bottom: 10px; +} + +/* line 504, sass/partials/_main_wrap.scss */ + +.cmb-attach-list li img { + float: right; + margin-left: 10px; +} + +/* line 510, sass/partials/_main_wrap.scss */ + +.cmb2-remove-wrapper { + margin: 0; +} + +/* line 514, sass/partials/_main_wrap.scss */ + +.child-cmb2 .cmb-th { + text-align: right; +} + +/* line 518, sass/partials/_main_wrap.scss */ + +.cmb2-indented-hierarchy { + padding-right: 1.5em; +} + +/*-------------------------------------------------------------- + * Post Metaboxes +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_post_metaboxes.scss */ + +#poststuff .cmb-group-title { + margin-right: -1em; + margin-left: -1em; + min-height: 1.5em; +} + +/* line 11, sass/partials/_post_metaboxes.scss */ + +#poststuff .repeatable .cmb-group-title { + padding-right: 2.2em; +} + +/* line 17, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb2-wrap, +.cmb-type-group .cmb2-wrap { + margin: 0; +} + +/* line 20, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb2-wrap > .cmb-field-list > .cmb-row, +.cmb-type-group .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.8em 0; +} + +/* line 26, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed, +.cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} + +/* line 32, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row, +.cmb-type-group .cmb-row { + padding: 0 0 1.8em; + margin: 0 0 0.8em; +} + +/* line 36, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row .cmbhandle, +.cmb-type-group .cmb-row .cmbhandle { + left: -1em; + position: relative; + color: #222222; +} + +/* line 43, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-repeatable-grouping, +.cmb-type-group .cmb-repeatable-grouping { + padding: 0 1em; + max-width: 100%; + min-width: 1px !important; +} + +/* line 49, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-repeatable-group > .cmb-row, +.cmb-type-group .cmb-repeatable-group > .cmb-row { + padding-bottom: 0; +} + +/* line 53, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-th, +.cmb-type-group .cmb-th { + width: 18%; + padding: 0 0 0 2%; +} + +/* line 59, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-td, +.cmb-type-group .cmb-td { + margin-bottom: 0; + padding: 0; + line-height: 1.3; +} + +/* line 65, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-th + .cmb-td, +.cmb-type-group .cmb-th + .cmb-td { + width: 80%; + float: left; +} + +/* line 70, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), +.cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 1px solid #e9e9e9; +} + +/* line 79, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-repeat-group-field, +.cmb2-postbox .cmb-remove-field-row, +.cmb-type-group .cmb-repeat-group-field, +.cmb-type-group .cmb-remove-field-row { + padding-top: 1.8em; +} + +/*-------------------------------------------------------------- + * Context Metaboxes +--------------------------------------------------------------*/ + +/* Metabox collapse arrow indicators */ + +/* line 9, sass/partials/_context_metaboxes.scss */ + +.js .cmb2-postbox.context-box .toggle-indicator:before { + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} + +/* line 22, sass/partials/_context_metaboxes.scss */ + +.js .cmb2-postbox.context-box.closed .toggle-indicator:before { + content: "\f140"; +} + +/* line 30, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box { + margin-bottom: 10px; +} + +/* line 34, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-before_permalink-box { + margin-top: 10px; +} + +/* line 38, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-after_title-box { + margin-top: 10px; +} + +/* line 42, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-after_editor-box { + margin-top: 20px; + margin-bottom: 0; +} + +/* line 47, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-form_top-box { + margin-top: 10px; +} + +/* line 51, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-form_top-box .hndle { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} + +/* line 59, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box .hndle { + cursor: auto; +} + +/* line 64, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap { + margin-top: 10px; +} + +/* line 68, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-left: 300px; + width: auto; +} + +/* line 75, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox { + padding: 10px; +} + +/* line 80, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-th { + padding: 0 0 0 2%; + width: 18%; +} + +/* line 85, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-td { + width: 80%; + padding: 0; +} + +/* line 90, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-row { + margin-bottom: 10px; +} + +/* line 93, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-row:last-of-type { + margin-bottom: 0; +} + +/* one column on the post write/edit screen */ + +/*-------------------------------------------------------------- + * Options page +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_options-page.scss */ + +.cmb2-options-page { + max-width: 1200px; +} + +/* line 8, sass/partials/_options-page.scss */ + +.cmb2-options-page.wrap > h2 { + margin-bottom: 1em; +} + +/* line 12, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row { + padding: 1em; + margin-top: -1px; + background: #ffffff; + border: 1px solid #e9e9e9; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} + +/* line 19, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th { + padding: 0; + font-weight: initial; +} + +/* line 24, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th + .cmb-td { + float: none; + padding: 0 1em 0 0; + margin-right: 200px; +} + +/* line 37, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-wrap .cmb-type-title { + margin-top: 1em; + padding: 0.6em 1em; + background-color: #fafafa; +} + +/* line 42, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-title { + font-size: 12px; + margin-top: 0; + margin-bottom: 0; + text-transform: uppercase; +} + +/* line 49, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-description { + padding-top: 0.25em; +} + +/* line 55, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb-repeatable-group .cmb-group-description .cmb-th { + padding: 0 0 0.8em 0; +} + +/* line 59, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb-repeatable-group .cmb-group-name { + font-size: 16px; + margin-top: 0; + margin-bottom: 0; +} + +/* line 65, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb-repeatable-group .cmb-th > .cmb2-metabox-description { + font-weight: 400; + padding-bottom: 0 !important; +} + +/*-------------------------------------------------------------- + * New-Term Page +--------------------------------------------------------------*/ + +/* line 6, sass/partials/_new_term.scss */ + +#addtag .cmb-th { + float: none; + width: auto; + padding: 20px 0 0; +} + +/* line 12, sass/partials/_new_term.scss */ + +#addtag .cmb-td { + padding: 0; +} + +/* line 16, sass/partials/_new_term.scss */ + +#addtag .cmb-th + .cmb-td { + float: none; +} + +/* line 20, sass/partials/_new_term.scss */ + +#addtag select { + max-width: 100%; +} + +/* line 24, sass/partials/_new_term.scss */ + +#addtag .cmb2-metabox { + padding-bottom: 20px; +} + +/* line 28, sass/partials/_new_term.scss */ + +#addtag .cmb-row li label { + display: inline; +} + +/*-------------------------------------------------------------- + * Misc. +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_misc.scss */ + +#poststuff .cmb-repeatable-group h2 { + margin: 0; +} + +/* line 12, sass/partials/_misc.scss */ + +.edit-tags-php .cmb2-metabox-title, +.profile-php .cmb2-metabox-title, +.user-edit-php .cmb2-metabox-title { + font-size: 1.4em; +} + +/* line 18, sass/partials/_misc.scss */ + +.cmb2-postbox .cmb-spinner, +.cmb2-no-box-wrap .cmb-spinner { + float: right; + display: none; +} + +/* line 24, sass/partials/_misc.scss */ + +.cmb-spinner { + display: none; +} + +/* line 26, sass/partials/_misc.scss */ + +.cmb-spinner.is-active { + display: block; +} + +/*-------------------------------------------------------------- + * Sidebar Placement Adjustments +--------------------------------------------------------------*/ + +/* line 10, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap > .cmb-field-list > .cmb-row, +#side-sortables .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.4em 0; +} + +/* line 16, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input[type=text]:not(.wp-color-picker), +#side-sortables .cmb2-wrap input[type=text]:not(.wp-color-picker) { + width: 100%; +} + +/* line 20, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input + input:not(.wp-picker-clear), +.inner-sidebar .cmb2-wrap input + select, +#side-sortables .cmb2-wrap input + input:not(.wp-picker-clear), +#side-sortables .cmb2-wrap input + select { + margin-right: 0; + margin-top: 1em; + display: block; +} + +/* line 26, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input.cmb2-text-money, +#side-sortables .cmb2-wrap input.cmb2-text-money { + max-width: 70%; +} + +/* line 28, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input.cmb2-text-money + .cmb2-metabox-description, +#side-sortables .cmb2-wrap input.cmb2-text-money + .cmb2-metabox-description { + display: block; +} + +/* line 34, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap label, +#side-sortables .cmb2-wrap label { + display: block; + font-weight: 700; + padding: 0 0 5px; +} + +/* line 42, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar textarea, +#side-sortables textarea { + max-width: 99%; +} + +/* line 46, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-repeatable-group, +#side-sortables .cmb-repeatable-group { + border-bottom: 1px solid #e9e9e9; +} + +/* line 50, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-type-group > .cmb-td > .cmb-repeatable-group, +#side-sortables .cmb-type-group > .cmb-td > .cmb-repeatable-group { + border-bottom: 0; + margin-bottom: -1.4em; +} + +/* line 55, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-th, +.inner-sidebar .cmb-td:not(.cmb-remove-row), +.inner-sidebar .cmb-th + .cmb-td, +#side-sortables .cmb-th, +#side-sortables .cmb-td:not(.cmb-remove-row), +#side-sortables .cmb-th + .cmb-td { + width: 100%; + display: block; + float: none; +} + +/* line 63, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .closed .inside, +#side-sortables .closed .inside { + display: none; +} + +/* line 67, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-th, +#side-sortables .cmb-th { + display: block; + float: none; + padding-bottom: 1em; + text-align: right; + width: 100%; + padding-right: 0; + padding-left: 0; +} + +/* line 27, sass/partials/_mixins.scss */ + +.inner-sidebar .cmb-th label, +#side-sortables .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} + +/* line 14, sass/partials/_mixins.scss */ + +.inner-sidebar .cmb-th label, +#side-sortables .cmb-th label { + font-size: 14px; + line-height: 1.4em; +} + +/* line 74, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-group-description .cmb-th, +#side-sortables .cmb-group-description .cmb-th { + padding-top: 0; +} + +/* line 77, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-group-description .cmb2-metabox-description, +#side-sortables .cmb-group-description .cmb2-metabox-description { + padding: 0; +} + +/* line 84, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-group-title .cmb-th, +#side-sortables .cmb-group-title .cmb-th { + padding: 0; +} + +/* line 90, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-repeatable-grouping + .cmb-repeatable-grouping, +#side-sortables .cmb-repeatable-grouping + .cmb-repeatable-grouping { + margin-top: 1em; +} + +/* line 99, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-media-status .img-status img, +.inner-sidebar .cmb2-media-status .embed-status img, +#side-sortables .cmb2-media-status .img-status img, +#side-sortables .cmb2-media-status .embed-status img { + max-width: 90%; + height: auto; +} + +/* line 107, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-list label, +#side-sortables .cmb2-list label { + display: inline; + font-weight: normal; +} + +/* line 112, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-metabox-description, +#side-sortables .cmb2-metabox-description { + display: block; + padding: 7px 0 0; +} + +/* line 119, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-type-checkbox .cmb-td label, +.inner-sidebar .cmb-type-checkbox .cmb2-metabox-description, +#side-sortables .cmb-type-checkbox .cmb-td label, +#side-sortables .cmb-type-checkbox .cmb2-metabox-description { + font-weight: normal; + display: inline; +} + +/* line 126, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-row .cmb2-metabox-description, +#side-sortables .cmb-row .cmb2-metabox-description { + padding-bottom: 1.8em; +} + +/* line 130, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-metabox-title, +#side-sortables .cmb2-metabox-title { + font-size: 1.2em; + font-style: italic; +} + +/* line 135, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-remove-row, +#side-sortables .cmb-remove-row { + clear: both; + padding-top: 12px; + padding-bottom: 0; +} + +/* line 141, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-upload-button, +#side-sortables .cmb2-upload-button { + clear: both; + margin-top: 12px; +} + +/*-------------------------------------------------------------- + * Collapsible UI +--------------------------------------------------------------*/ + +/* line 6, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox .cmbhandle { + color: #757575; + float: left; + width: 27px; + height: 30px; + cursor: pointer; + left: -1em; + position: relative; +} + +/* line 14, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox .cmbhandle:before { + content: '\f142'; + left: 12px; + font: normal 20px/1 'dashicons'; + speak: none; + display: inline-block; + padding: 8px 10px; + top: 0; + position: relative; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} + +/* line 31, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox .postbox.closed .cmbhandle:before { + content: '\f140'; +} + +/* line 37, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + -webkit-appearance: none !important; + background: none !important; + border: none !important; + position: absolute; + right: 0; + top: .5em; + line-height: 1em; + padding: 2px 6px 3px; + opacity: .5; +} + +/* line 47, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]) { + cursor: pointer; + color: #a00; + opacity: 1; +} + +/* line 51, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover { + color: #f00; +} + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress" + * https://github.com/stuttter/wp-datepicker-styling + * + */ + +/* line 15, sass/partials/_jquery_ui.scss */ + +* html .cmb2-element.ui-helper-clearfix { + height: 1%; +} + +/* line 24, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker, +.cmb2-element .ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + width: auto; /* Default Color Scheme */ +} + +/* line 38, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker *, +.cmb2-element .ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +/* line 46, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker table, +.cmb2-element .ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} + +/* line 53, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, +.cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} + +/* line 61, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, +.cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} + +/* line 67, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-title, +.cmb2-element .ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} + +/* line 75, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-title select, +.cmb2-element .ui-datepicker .ui-datepicker-title select { + margin-top: -8px; + margin-bottom: -8px; +} + +/* line 81, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-next { + position: relative; + top: 0; + height: 34px; + width: 34px; +} + +/* line 89, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} + +/* line 94, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover, +.cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover { + right: 0; +} + +/* line 99, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover, +.cmb2-element .ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover { + left: 0; +} + +/* line 104, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next span, +.cmb2-element.ui-datepicker .ui-datepicker-prev span, +.cmb2-element .ui-datepicker .ui-datepicker-next span, +.cmb2-element .ui-datepicker .ui-datepicker-prev span { + display: none; +} + +/* line 109, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev { + float: right; +} + +/* line 113, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next { + float: left; +} + +/* line 117, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element.ui-datepicker .ui-datepicker-next:before, +.cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-right: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} + +/* line 129, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} + +/* line 133, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} + +/* line 137, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} + +/* line 142, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker select.ui-datepicker-month, +.cmb2-element.ui-datepicker select.ui-datepicker-year, +.cmb2-element .ui-datepicker select.ui-datepicker-month, +.cmb2-element .ui-datepicker select.ui-datepicker-year { + width: 33%; + background: transparent; + border-color: transparent; + box-shadow: none; + color: #fff; +} + +/* line 149, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker select.ui-datepicker-month option, +.cmb2-element.ui-datepicker select.ui-datepicker-year option, +.cmb2-element .ui-datepicker select.ui-datepicker-month option, +.cmb2-element .ui-datepicker select.ui-datepicker-year option { + color: #333; +} + +/* line 154, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker thead, +.cmb2-element .ui-datepicker thead { + color: #fff; + font-weight: 600; +} + +/* line 157, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker thead th, +.cmb2-element .ui-datepicker thead th { + font-weight: normal; +} + +/* line 162, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker th, +.cmb2-element .ui-datepicker th { + padding: 10px; +} + +/* line 166, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td, +.cmb2-element .ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} + +/* line 171, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-other-month, +.cmb2-element .ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} + +/* line 175, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-week-end, +.cmb2-element .ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} + +/* line 178, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today, +.cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today { + -webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); +} + +/* line 185, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-today, +.cmb2-element .ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} + +/* line 189, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-current-day, +.cmb2-element .ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} + +/* line 193, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td .ui-state-default, +.cmb2-element .ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} + +/* line 205, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default, +.cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} + +/* line 210, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, +.cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +/* line 215, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker thead, +.cmb2-element .ui-datepicker thead { + background: #32373c; +} + +/* line 219, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td .ui-state-hover, +.cmb2-element.ui-datepicker td .ui-state-active, +.cmb2-element .ui-datepicker td .ui-state-hover, +.cmb2-element .ui-datepicker td .ui-state-active { + background: #0073aa; + color: #fff; +} + +/* line 224, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div, +.cmb2-element .ui-datepicker .ui-timepicker-div { + font-size: 14px; +} + +/* line 226, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl, +.cmb2-element .ui-datepicker .ui-timepicker-div dl { + text-align: right; + padding: 0 .6em; +} + +/* line 229, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl dt, +.cmb2-element .ui-datepicker .ui-timepicker-div dl dt { + float: right; + clear: right; + padding: 0 5px 0 0; +} + +/* line 234, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd, +.cmb2-element .ui-datepicker .ui-timepicker-div dl dd { + margin: 0 40% 10px 10px; +} + +/* line 236, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select, +.cmb2-element .ui-datepicker .ui-timepicker-div dl dd select { + width: 100%; +} + +/* line 242, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane, +.cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane { + padding: .6em; + text-align: right; +} + +/* line 246, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary, +.cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, +.cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary { + padding: 0 10px 1px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + margin: 0 .4em .4em .6em; +} + +/* line 260, sass/partials/_jquery_ui.scss */ + +.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +/* line 265, sass/partials/_jquery_ui.scss */ + +.admin-color-fresh .cmb2-element.ui-datepicker thead, +.admin-color-fresh .cmb2-element .ui-datepicker thead { + background: #32373c; +} + +/* line 269, sass/partials/_jquery_ui.scss */ + +.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* line 277, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #52accc; +} + +/* line 282, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker thead, +.admin-color-blue .cmb2-element .ui-datepicker thead { + background: #4796b3; +} + +/* line 291, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active, +.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover, +.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active { + background: #096484; + color: #fff; +} + +/* line 296, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today, +.admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 305, sass/partials/_jquery_ui.scss */ + +.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #59524c; +} + +/* line 310, sass/partials/_jquery_ui.scss */ + +.admin-color-coffee .cmb2-element.ui-datepicker thead, +.admin-color-coffee .cmb2-element .ui-datepicker thead { + background: #46403c; +} + +/* line 314, sass/partials/_jquery_ui.scss */ + +.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +/* line 322, sass/partials/_jquery_ui.scss */ + +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} + +/* line 327, sass/partials/_jquery_ui.scss */ + +.admin-color-ectoplasm .cmb2-element.ui-datepicker thead, +.admin-color-ectoplasm .cmb2-element .ui-datepicker thead { + background: #413256; +} + +/* line 331, sass/partials/_jquery_ui.scss */ + +.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +/* line 339, sass/partials/_jquery_ui.scss */ + +.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} + +/* line 344, sass/partials/_jquery_ui.scss */ + +.admin-color-midnight .cmb2-element.ui-datepicker thead, +.admin-color-midnight .cmb2-element .ui-datepicker thead { + background: #26292c; +} + +/* line 348, sass/partials/_jquery_ui.scss */ + +.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +/* line 356, sass/partials/_jquery_ui.scss */ + +.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #738e96; +} + +/* line 361, sass/partials/_jquery_ui.scss */ + +.admin-color-ocean .cmb2-element.ui-datepicker thead, +.admin-color-ocean .cmb2-element .ui-datepicker thead { + background: #627c83; +} + +/* line 365, sass/partials/_jquery_ui.scss */ + +.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +/* line 373, sass/partials/_jquery_ui.scss */ + +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} + +/* line 379, sass/partials/_jquery_ui.scss */ + +.admin-color-sunrise .cmb2-element.ui-datepicker th, +.admin-color-sunrise .cmb2-element .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} + +/* line 384, sass/partials/_jquery_ui.scss */ + +.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +/* line 392, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} + +/* line 397, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year { + color: #555; +} + +/* line 402, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker thead, +.admin-color-light .cmb2-element .ui-datepicker thead { + background: #888; +} + +/* line 406, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before { + color: #555; +} + +/* line 414, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-active, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-active { + background: #ccc; +} + +/* line 418, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today, +.admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 426, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #56b274; +} + +/* line 431, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead { + background: #36533f; +} + +/* line 435, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +/* line 443, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} + +/* line 448, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-mint .cmb2-element.ui-datepicker thead, +.admin-color-bbp-mint .cmb2-element .ui-datepicker thead { + background: #4f6d59; +} + +/* line 452, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} + +/*# sourceMappingURL=cmb2.css.map */ + +@media only screen and (max-width: 850px) { + +/* line 103, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-left: 0; +} + +} + +@media (max-width: 450px) { + +/* line 193, sass/partials/_main_wrap.scss */ + +.cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: right; + width: 100%; +} + +/* line 27, sass/partials/_mixins.scss */ + +.cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} + +/* line 523, sass/partials/_main_wrap.scss */ + +.cmb-th, +.cmb-td, +.cmb-th + .cmb-td { + display: block; + float: none; + width: 100%; +} + +/* line 70, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), +.cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 0; +} + +/* line 24, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th + .cmb-td { + padding: 0; + margin-right: 0; +} + +} + diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2-rtl.min.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-rtl.min.css new file mode 100755 index 00000000..df2fa0f0 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2-rtl.min.css @@ -0,0 +1,2 @@ +/*! CMB2 - v2.6.0 - 2019-01-18 | https://cmb2.io | Copyright (c) 2019 CMB2 team | Licensed GPLv2 */ +.cmb2-wrap{margin:0}.cmb2-wrap input,.cmb2-wrap textarea{font-size:14px;max-width:100%;padding:5px}.cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb2-wrap textarea{width:500px}.cmb2-wrap textarea.cmb2-textarea-code{font-family:"Courier 10 Pitch",Courier,monospace;line-height:16px}.cmb2-wrap input.cmb2-text-small,.cmb2-wrap input.cmb2-timepicker{width:100px}.cmb2-wrap input.cmb2-text-money{width:90px}.cmb2-wrap input.cmb2-text-medium{width:230px}.cmb2-wrap input.cmb2-upload-file{width:65%}.cmb2-wrap input.ed_button{padding:2px 4px}.cmb2-wrap input:not([type=hidden])+.button-secondary,.cmb2-wrap input:not([type=hidden])+input,.cmb2-wrap input:not([type=hidden])+select{margin-right:20px}.cmb2-wrap ul{margin:0}.cmb2-wrap li{font-size:14px;line-height:16px;margin:1px 0 5px}.cmb2-wrap select{font-size:14px;margin-top:3px}.cmb2-wrap input:focus,.cmb2-wrap textarea:focus{background:#fffff8}.cmb2-wrap input[type=checkbox],.cmb2-wrap input[type=radio]{margin:0 0 0 5px;padding:0}.cmb2-wrap .button-secondary,.cmb2-wrap button{white-space:nowrap}.cmb2-wrap .mceLayout{border:1px solid #e9e9e9!important}.cmb2-wrap .mceIframeContainer{background:#fff}.cmb2-wrap .meta_mce{width:97%}.cmb2-wrap .meta_mce textarea{width:100%}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-input-wrap{vertical-align:middle}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-container{margin:0 0 0 10px}.cmb2-wrap .cmb-row{margin:0}.cmb2-wrap .cmb-row:after{content:'';clear:both;display:block;width:100%}.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description{padding-top:0;padding-bottom:1em}.cmb2-metabox{clear:both;margin:0}.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-th,.cmb2-metabox>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox>.cmb-row:first-of-type>.cmb-th{border:0}.cmb-add-row{margin:1.8em 0 0}.cmb-nested .cmb-td,.cmb-repeatable-group .cmb-th,.cmb-repeatable-group:first-of-type{border:0}.cmb-repeatable-group:last-of-type,.cmb-row:last-of-type,.cmb2-wrap .cmb-row:last-of-type{border-bottom:0}.cmb-repeatable-grouping{border:1px solid #e9e9e9;padding:0 1em}.cmb-repeatable-grouping.cmb-row{margin:0 0 .8em}.cmb-th{color:#222;float:right;font-weight:600;line-height:1.3;padding:20px 0 20px 10px;vertical-align:top;width:200px}.cmb-td{line-height:1.3;max-width:100%;padding:15px 10px;vertical-align:middle}.cmb-type-title .cmb-td{padding:0}.cmb-th label{display:block;padding:5px 0}.cmb-th+.cmb-td{float:right}.cmb-td .cmb-td{padding-bottom:1em}.cmb-remove-row{text-align:left}.empty-row.hidden{display:none}.cmb-repeat-table{background-color:#fafafa;border:1px solid #e1e1e1}.cmb-repeat-table .cmb-row.cmb-repeat-row{position:relative;counter-increment:el;margin:0;padding:10px 50px 10px 10px;border-bottom:none!important}.cmb-repeat-table .cmb-row.cmb-repeat-row+.cmb-repeat-row{border-top:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper{outline:dashed 2px #e9e9e9!important}.cmb-repeat-table .cmb-row.cmb-repeat-row:before{content:counter(el);display:block;top:0;right:0;position:absolute;width:35px;height:100%;line-height:35px;cursor:move;color:#757575;text-align:center;border-left:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td{margin:0;padding:0}.cmb-repeat-table+.cmb-add-row{margin:0}.cmb-repeat-table+.cmb-add-row:before{content:'';width:1px;height:1.6em;display:block;margin-right:17px;background-color:#dcdcdc}.cmb-repeat-table .cmb-remove-row{top:7px;left:7px;position:absolute;width:auto;margin-right:0;padding:0!important;display:none}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button{font-size:20px;text-indent:-1000px;overflow:hidden;position:relative;height:auto;line-height:1;padding:0 10px}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button:before{content:"";font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;right:0;width:100%;height:100%;text-align:center}.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row{display:block}.cmb-repeatable-group .cmb-th{padding:5px}.cmb-repeatable-group .cmb-group-title{background-color:#e9e9e9;padding:8px 2.2em 8px 12px;margin:0 -1em;min-height:1.5em;font-size:14px;line-height:1.4}.cmb-repeatable-group .cmb-group-title h4{border:0;margin:0;font-size:1.2em;font-weight:500;padding:.5em .75em}.cmb-repeatable-group .cmb-group-title .cmb-th{display:block;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th{font-size:1.2em;display:block;float:none;padding-bottom:1em;text-align:right;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th label{display:block;margin-top:0;margin-bottom:.5em}.cmb-repeatable-group .cmb-shift-rows{font-size:1em;margin-left:1em;text-decoration:none}.cmb-repeatable-group .cmb-shift-rows .dashicons{font-size:1.5em;height:1.5em;line-height:1.2em;width:1em}.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2{line-height:1.3em}.cmb-repeatable-group .cmb2-upload-button{float:left}p.cmb2-metabox-description{color:#757575;font-style:italic;margin:0;padding-top:.5em}span.cmb2-metabox-description{color:#757575;font-style:italic}.cmb2-metabox-title{margin:0 0 5px;padding:5px 0 0;font-size:14px}.cmb-inline ul{padding:4px 0 0}.cmb-inline li{display:inline-block;padding-left:18px}.cmb-type-textarea-code pre{margin:0}.cmb2-media-status .img-status{clear:none;display:inline-block;vertical-align:middle;margin-left:10px;width:auto}.cmb2-media-status .img-status img{max-width:350px;height:auto}.cmb2-media-status .embed-status,.cmb2-media-status .img-status img{background:#eee;border:5px solid #fff;outline:1px solid #e9e9e9;box-shadow:inset 0 0 15px rgba(0,0,0,.3),inset 0 0 0 1px rgba(0,0,0,.05);background-image:linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0),linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0);background-position:0 0,10px 10px;background-size:20px 20px;border-radius:2px;-moz-border-radius:2px;margin:15px 0 0}.cmb2-media-status .embed-status{float:right;max-width:800px}.cmb2-media-status .embed-status,.cmb2-media-status .img-status{position:relative}.cmb2-media-status .embed-status .cmb2-remove-file-button,.cmb2-media-status .img-status .cmb2-remove-file-button{background:url(../images/ico-delete.png);height:16px;right:-5px;position:absolute;text-indent:-9999px;top:-5px;width:16px}.cmb2-media-status .img-status .cmb2-remove-file-button{top:10px}.cmb2-media-status .file-status>span,.cmb2-media-status .img-status img{cursor:pointer}.cmb2-media-status.cmb-attach-list .file-status>span,.cmb2-media-status.cmb-attach-list .img-status img{cursor:move}.cmb-type-file-list .cmb2-media-status .img-status{clear:none;vertical-align:middle;width:auto;margin-left:10px;margin-bottom:10px;margin-top:0}.cmb-attach-list li{clear:both;display:inline-block;width:100%;margin-top:5px;margin-bottom:10px}.cmb-attach-list li img{float:right;margin-left:10px}.cmb2-remove-wrapper{margin:0}.child-cmb2 .cmb-th{text-align:right}.cmb2-indented-hierarchy{padding-right:1.5em}#poststuff .cmb-group-title{margin-right:-1em;margin-left:-1em;min-height:1.5em}#poststuff .repeatable .cmb-group-title{padding-right:2.2em}.cmb-type-group .cmb2-wrap,.cmb2-postbox .cmb2-wrap{margin:0}.cmb-type-group .cmb2-wrap>.cmb-field-list>.cmb-row,.cmb2-postbox .cmb2-wrap>.cmb-field-list>.cmb-row{padding:1.8em 0}.cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed,.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb-type-group .cmb-row,.cmb2-postbox .cmb-row{padding:0 0 1.8em;margin:0 0 .8em}.cmb-type-group .cmb-row .cmbhandle,.cmb2-postbox .cmb-row .cmbhandle{left:-1em;position:relative;color:#222}.cmb-type-group .cmb-repeatable-grouping,.cmb2-postbox .cmb-repeatable-grouping{padding:0 1em;max-width:100%;min-width:1px!important}.cmb-type-group .cmb-repeatable-group>.cmb-row,.cmb2-postbox .cmb-repeatable-group>.cmb-row{padding-bottom:0}.cmb-type-group .cmb-th,.cmb2-postbox .cmb-th{width:18%;padding:0 0 0 2%}.cmb-type-group .cmb-td,.cmb2-postbox .cmb-td{margin-bottom:0;padding:0;line-height:1.3}.cmb-type-group .cmb-th+.cmb-td,.cmb2-postbox .cmb-th+.cmb-td{width:80%;float:left}.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:1px solid #e9e9e9}.cmb-type-group .cmb-remove-field-row,.cmb-type-group .cmb-repeat-group-field,.cmb2-postbox .cmb-remove-field-row,.cmb2-postbox .cmb-repeat-group-field{padding-top:1.8em}.js .cmb2-postbox.context-box .toggle-indicator:before{content:"\f142";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.js .cmb2-postbox.context-box.closed .toggle-indicator:before{content:"\f140"}.cmb2-postbox.context-box{margin-bottom:10px}.cmb2-postbox.context-box.context-after_title-box,.cmb2-postbox.context-box.context-before_permalink-box{margin-top:10px}.cmb2-postbox.context-box.context-after_editor-box{margin-top:20px;margin-bottom:0}.cmb2-postbox.context-box.context-form_top-box{margin-top:10px}.cmb2-postbox.context-box.context-form_top-box .hndle{font-size:14px;padding:8px 12px;margin:0;line-height:1.4}.cmb2-postbox.context-box .hndle{cursor:auto}.cmb2-context-wrap{margin-top:10px}.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-left:300px;width:auto}.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox{padding:10px}.cmb2-context-wrap .cmb-th{padding:0 0 0 2%;width:18%}.cmb2-context-wrap .cmb-td{width:80%;padding:0}.cmb2-context-wrap .cmb-row{margin-bottom:10px}.cmb2-context-wrap .cmb-row:last-of-type{margin-bottom:0}.cmb2-options-page{max-width:1200px}.cmb2-options-page.wrap>h2{margin-bottom:1em}.cmb2-options-page .cmb2-metabox>.cmb-row{padding:1em;margin-top:-1px;background:#fff;border:1px solid #e9e9e9;box-shadow:0 1px 1px rgba(0,0,0,.05)}.cmb2-options-page .cmb2-metabox>.cmb-row>.cmb-th{padding:0;font-weight:initial}.cmb2-options-page .cmb2-metabox>.cmb-row>.cmb-th+.cmb-td{float:none;padding:0 1em 0 0;margin-right:200px}.cmb2-options-page .cmb2-wrap .cmb-type-title{margin-top:1em;padding:.6em 1em;background-color:#fafafa}.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-title{font-size:12px;margin-top:0;margin-bottom:0;text-transform:uppercase}.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-description{padding-top:.25em}.cmb2-options-page .cmb-repeatable-group .cmb-group-description .cmb-th{padding:0 0 .8em}.cmb2-options-page .cmb-repeatable-group .cmb-group-name{font-size:16px;margin-top:0;margin-bottom:0}.cmb2-options-page .cmb-repeatable-group .cmb-th>.cmb2-metabox-description{font-weight:400;padding-bottom:0!important}#addtag .cmb-th{float:none;width:auto;padding:20px 0 0}#addtag .cmb-td{padding:0}#addtag .cmb-th+.cmb-td{float:none}#addtag select{max-width:100%}#addtag .cmb2-metabox{padding-bottom:20px}#addtag .cmb-row li label{display:inline}#poststuff .cmb-repeatable-group h2{margin:0}.edit-tags-php .cmb2-metabox-title,.profile-php .cmb2-metabox-title,.user-edit-php .cmb2-metabox-title{font-size:1.4em}.cmb2-no-box-wrap .cmb-spinner,.cmb2-postbox .cmb-spinner{float:right;display:none}.cmb-spinner{display:none}.cmb-spinner.is-active{display:block}#side-sortables .cmb2-wrap>.cmb-field-list>.cmb-row,.inner-sidebar .cmb2-wrap>.cmb-field-list>.cmb-row{padding:1.4em 0}#side-sortables .cmb2-wrap input[type=text]:not(.wp-color-picker),.inner-sidebar .cmb2-wrap input[type=text]:not(.wp-color-picker){width:100%}#side-sortables .cmb2-wrap input+input:not(.wp-picker-clear),#side-sortables .cmb2-wrap input+select,.inner-sidebar .cmb2-wrap input+input:not(.wp-picker-clear),.inner-sidebar .cmb2-wrap input+select{margin-right:0;margin-top:1em;display:block}#side-sortables .cmb2-wrap input.cmb2-text-money,.inner-sidebar .cmb2-wrap input.cmb2-text-money{max-width:70%}#side-sortables .cmb2-wrap input.cmb2-text-money+.cmb2-metabox-description,.inner-sidebar .cmb2-wrap input.cmb2-text-money+.cmb2-metabox-description{display:block}#side-sortables .cmb2-wrap label,.inner-sidebar .cmb2-wrap label{display:block;font-weight:700;padding:0 0 5px}#side-sortables textarea,.inner-sidebar textarea{max-width:99%}#side-sortables .cmb-repeatable-group,.inner-sidebar .cmb-repeatable-group{border-bottom:1px solid #e9e9e9}#side-sortables .cmb-type-group>.cmb-td>.cmb-repeatable-group,.inner-sidebar .cmb-type-group>.cmb-td>.cmb-repeatable-group{border-bottom:0;margin-bottom:-1.4em}#side-sortables .cmb-td:not(.cmb-remove-row),#side-sortables .cmb-th,#side-sortables .cmb-th+.cmb-td,.inner-sidebar .cmb-td:not(.cmb-remove-row),.inner-sidebar .cmb-th,.inner-sidebar .cmb-th+.cmb-td{width:100%;display:block;float:none}#side-sortables .closed .inside,.inner-sidebar .closed .inside{display:none}#side-sortables .cmb-th,.inner-sidebar .cmb-th{display:block;float:none;padding-bottom:1em;text-align:right;width:100%;padding-right:0;padding-left:0}#side-sortables .cmb-th label,.inner-sidebar .cmb-th label{display:block;margin-top:0;margin-bottom:.5em;font-size:14px;line-height:1.4em}#side-sortables .cmb-group-description .cmb-th,.inner-sidebar .cmb-group-description .cmb-th{padding-top:0}#side-sortables .cmb-group-description .cmb2-metabox-description,#side-sortables .cmb-group-title .cmb-th,.inner-sidebar .cmb-group-description .cmb2-metabox-description,.inner-sidebar .cmb-group-title .cmb-th{padding:0}#side-sortables .cmb-repeatable-grouping+.cmb-repeatable-grouping,.inner-sidebar .cmb-repeatable-grouping+.cmb-repeatable-grouping{margin-top:1em}#side-sortables .cmb2-media-status .embed-status img,#side-sortables .cmb2-media-status .img-status img,.inner-sidebar .cmb2-media-status .embed-status img,.inner-sidebar .cmb2-media-status .img-status img{max-width:90%;height:auto}#side-sortables .cmb2-list label,.inner-sidebar .cmb2-list label{display:inline;font-weight:400}#side-sortables .cmb2-metabox-description,.inner-sidebar .cmb2-metabox-description{display:block;padding:7px 0 0}#side-sortables .cmb-type-checkbox .cmb-td label,#side-sortables .cmb-type-checkbox .cmb2-metabox-description,.inner-sidebar .cmb-type-checkbox .cmb-td label,.inner-sidebar .cmb-type-checkbox .cmb2-metabox-description{font-weight:400;display:inline}#side-sortables .cmb-row .cmb2-metabox-description,.inner-sidebar .cmb-row .cmb2-metabox-description{padding-bottom:1.8em}#side-sortables .cmb2-metabox-title,.inner-sidebar .cmb2-metabox-title{font-size:1.2em;font-style:italic}#side-sortables .cmb-remove-row,.inner-sidebar .cmb-remove-row{clear:both;padding-top:12px;padding-bottom:0}#side-sortables .cmb2-upload-button,.inner-sidebar .cmb2-upload-button{clear:both;margin-top:12px}.cmb2-metabox .cmbhandle{color:#757575;float:left;width:27px;height:30px;cursor:pointer;left:-1em;position:relative}.cmb2-metabox .cmbhandle:before{content:'\f142';left:12px;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:8px 10px;top:0;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.cmb2-metabox .postbox.closed .cmbhandle:before{content:'\f140'}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row{-webkit-appearance:none!important;background:none!important;border:none!important;position:absolute;right:0;top:.5em;line-height:1em;padding:2px 6px 3px;opacity:.5}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]){cursor:pointer;color:#a00;opacity:1}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover{color:red}* html .cmb2-element.ui-helper-clearfix{height:1%}.cmb2-element .ui-datepicker,.cmb2-element.ui-datepicker{padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;background-color:#fff;border:1px solid #dfdfdf;border-top:none;-webkit-box-shadow:0 3px 6px rgba(0,0,0,.075);box-shadow:0 3px 6px rgba(0,0,0,.075);min-width:17em;width:auto}.cmb2-element .ui-datepicker *,.cmb2-element.ui-datepicker *{padding:0;font-family:"Open Sans",sans-serif;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.cmb2-element .ui-datepicker table,.cmb2-element.ui-datepicker table{font-size:13px;margin:0;border:none;border-collapse:collapse}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{border:none;color:#fff;font-weight:400}.cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover{background:0 0;border-color:transparent;cursor:pointer}.cmb2-element .ui-datepicker .ui-datepicker-title,.cmb2-element.ui-datepicker .ui-datepicker-title{margin:0;padding:10px 0;color:#fff;font-size:14px;line-height:14px;text-align:center}.cmb2-element .ui-datepicker .ui-datepicker-title select,.cmb2-element.ui-datepicker .ui-datepicker-title select{margin-top:-8px;margin-bottom:-8px}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-prev{position:relative;top:0;height:34px;width:34px}.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev{border:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover,.cmb2-element.ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover{right:0}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-next-hover,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next-hover{left:0}.cmb2-element .ui-datepicker .ui-datepicker-next span,.cmb2-element .ui-datepicker .ui-datepicker-prev span,.cmb2-element.ui-datepicker .ui-datepicker-next span,.cmb2-element.ui-datepicker .ui-datepicker-prev span{display:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev{float:right}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next{float:left}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{font:400 20px/34px dashicons;padding-right:7px;color:#fff;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:34px;height:34px}.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{content:'\f341'}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before{content:'\f345'}.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before{opacity:.7}.cmb2-element .ui-datepicker select.ui-datepicker-month,.cmb2-element .ui-datepicker select.ui-datepicker-year,.cmb2-element.ui-datepicker select.ui-datepicker-month,.cmb2-element.ui-datepicker select.ui-datepicker-year{width:33%;background:0 0;border-color:transparent;box-shadow:none;color:#fff}.cmb2-element .ui-datepicker select.ui-datepicker-month option,.cmb2-element .ui-datepicker select.ui-datepicker-year option,.cmb2-element.ui-datepicker select.ui-datepicker-month option,.cmb2-element.ui-datepicker select.ui-datepicker-year option{color:#333}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{color:#fff;font-weight:600}.cmb2-element .ui-datepicker thead th,.cmb2-element.ui-datepicker thead th{font-weight:400}.cmb2-element .ui-datepicker th,.cmb2-element.ui-datepicker th{padding:10px}.cmb2-element .ui-datepicker td,.cmb2-element.ui-datepicker td{padding:0;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-other-month,.cmb2-element.ui-datepicker td.ui-datepicker-other-month{border:transparent}.cmb2-element .ui-datepicker td.ui-datepicker-week-end,.cmb2-element.ui-datepicker td.ui-datepicker-week-end{background-color:#f4f4f4;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today{-webkit-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);-moz-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1)}.cmb2-element .ui-datepicker td.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-today{background-color:#f0f0c0}.cmb2-element .ui-datepicker td.ui-datepicker-current-day,.cmb2-element.ui-datepicker td.ui-datepicker-current-day{background:#bd8}.cmb2-element .ui-datepicker td .ui-state-default,.cmb2-element.ui-datepicker td .ui-state-default{background:0 0;border:none;text-align:center;text-decoration:none;width:auto;display:block;padding:5px 10px;font-weight:400;color:#444}.cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default,.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default{opacity:.5}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{background:#32373c}.cmb2-element .ui-datepicker td .ui-state-active,.cmb2-element .ui-datepicker td .ui-state-hover,.cmb2-element.ui-datepicker td .ui-state-active,.cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.cmb2-element .ui-datepicker .ui-timepicker-div,.cmb2-element.ui-datepicker .ui-timepicker-div{font-size:14px}.cmb2-element .ui-datepicker .ui-timepicker-div dl,.cmb2-element.ui-datepicker .ui-timepicker-div dl{text-align:right;padding:0 .6em}.cmb2-element .ui-datepicker .ui-timepicker-div dl dt,.cmb2-element.ui-datepicker .ui-timepicker-div dl dt{float:right;clear:right;padding:0 5px 0 0}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd{margin:0 40% 10px 10px}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd select,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select{width:100%}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane{padding:.6em;text-align:right}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary{padding:0 10px 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;margin:0 .4em .4em .6em}.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.admin-color-fresh .cmb2-element .ui-datepicker thead,.admin-color-fresh .cmb2-element.ui-datepicker thead{background:#32373c}.admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header{background:#52accc}.admin-color-blue .cmb2-element .ui-datepicker thead,.admin-color-blue .cmb2-element.ui-datepicker thead{background:#4796b3}.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover{background:#096484;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header{background:#59524c}.admin-color-coffee .cmb2-element .ui-datepicker thead,.admin-color-coffee .cmb2-element.ui-datepicker thead{background:#46403c}.admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover{background:#c7a589;color:#fff}.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header{background:#523f6d}.admin-color-ectoplasm .cmb2-element .ui-datepicker thead,.admin-color-ectoplasm .cmb2-element.ui-datepicker thead{background:#413256}.admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover{background:#a3b745;color:#fff}.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header{background:#363b3f}.admin-color-midnight .cmb2-element .ui-datepicker thead,.admin-color-midnight .cmb2-element.ui-datepicker thead{background:#26292c}.admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover{background:#e14d43;color:#fff}.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header{background:#738e96}.admin-color-ocean .cmb2-element .ui-datepicker thead,.admin-color-ocean .cmb2-element.ui-datepicker thead{background:#627c83}.admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover{background:#9ebaa0;color:#fff}.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header{background:#cf4944}.admin-color-sunrise .cmb2-element .ui-datepicker th,.admin-color-sunrise .cmb2-element.ui-datepicker th{border-color:#be3631;background:#be3631}.admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover{background:#dd823b;color:#fff}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header{background:#e5e5e5}.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year{color:#555}.admin-color-light .cmb2-element .ui-datepicker thead,.admin-color-light .cmb2-element.ui-datepicker thead{background:#888}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default{color:#555}.admin-color-light .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover{background:#ccc}.admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header{background:#56b274}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead{background:#36533f}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover{background:#446950;color:#fff}.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header{background:#4ca26a}.admin-color-bbp-mint .cmb2-element .ui-datepicker thead,.admin-color-bbp-mint .cmb2-element.ui-datepicker thead{background:#4f6d59}.admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover{background:#5fb37c;color:#fff}@media only screen and (max-width:850px){.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-left:0}}@media (max-width:450px){.cmb-th{font-size:1.2em;padding-bottom:1em;text-align:right}.cmb-th label{display:block;margin-top:0;margin-bottom:.5em}.cmb-td,.cmb-th,.cmb-th+.cmb-td{display:block;float:none;width:100%}.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:0}.cmb2-options-page .cmb2-metabox>.cmb-row>.cmb-th+.cmb-td{padding:0;margin-right:0}} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2.css new file mode 100755 index 00000000..34107620 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2.css @@ -0,0 +1,2098 @@ +/*! + * CMB2 - v2.6.0 - 2019-01-18 + * https://cmb2.io + * Copyright (c) 2019 + * Licensed GPLv2+ + */ + +/*-------------------------------------------------------------- + * Main Wrap +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_main_wrap.scss */ + +.cmb2-wrap { + margin: 0; +} + +/* line 8, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input, +.cmb2-wrap textarea { + font-size: 14px; + max-width: 100%; + padding: 5px; +} + +/* line 18, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} + +/* line 23, sass/partials/_main_wrap.scss */ + +.cmb2-wrap textarea { + width: 500px; +} + +/* line 26, sass/partials/_main_wrap.scss */ + +.cmb2-wrap textarea.cmb2-textarea-code { + font-family: "Courier 10 Pitch", Courier, monospace; + line-height: 16px; +} + +/* line 34, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-text-small, +.cmb2-wrap input.cmb2-timepicker { + width: 100px; +} + +/* line 40, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-text-money { + width: 90px; +} + +/* line 45, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-text-medium { + width: 230px; +} + +/* line 50, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.cmb2-upload-file { + width: 65%; +} + +/* line 54, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input.ed_button { + padding: 2px 4px; +} + +/* line 59, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input:not([type="hidden"]) + input, +.cmb2-wrap input:not([type="hidden"]) + .button-secondary, +.cmb2-wrap input:not([type="hidden"]) + select { + margin-left: 20px; +} + +/* line 67, sass/partials/_main_wrap.scss */ + +.cmb2-wrap ul { + margin: 0; +} + +/* line 71, sass/partials/_main_wrap.scss */ + +.cmb2-wrap li { + font-size: 14px; + line-height: 16px; + margin: 1px 0 5px 0; +} + +/* line 82, sass/partials/_main_wrap.scss */ + +.cmb2-wrap select { + font-size: 14px; + margin-top: 3px; +} + +/* line 87, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input:focus, +.cmb2-wrap textarea:focus { + background: #fffff8; +} + +/* line 92, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input[type="radio"] { + margin: 0 5px 0 0; + padding: 0; +} + +/* line 97, sass/partials/_main_wrap.scss */ + +.cmb2-wrap input[type="checkbox"] { + margin: 0 5px 0 0; + padding: 0; +} + +/* line 102, sass/partials/_main_wrap.scss */ + +.cmb2-wrap button, +.cmb2-wrap .button-secondary { + white-space: nowrap; +} + +/* line 107, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .mceLayout { + border: 1px solid #e9e9e9 !important; +} + +/* line 111, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .mceIframeContainer { + background: #ffffff; +} + +/* line 115, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .meta_mce { + width: 97%; +} + +/* line 118, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .meta_mce textarea { + width: 100%; +} + +/* line 124, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-input-wrap { + vertical-align: middle; +} + +/* line 129, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .wp-color-result, +.cmb2-wrap .wp-picker-container { + margin: 0 10px 0 0; +} + +/* line 134, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .cmb-row { + margin: 0; +} + +/* line 137, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .cmb-row:after { + content: ''; + clear: both; + display: block; + width: 100%; +} + +/* line 144, sass/partials/_main_wrap.scss */ + +.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description { + padding-top: 0; + padding-bottom: 1em; +} + +/* line 152, sass/partials/_main_wrap.scss */ + +.cmb2-metabox { + clear: both; + margin: 0; +} + +/* line 158, sass/partials/_main_wrap.scss */ + +.cmb2-metabox > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox > .cmb-row:first-of-type > .cmb-th, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-td, +.cmb2-metabox .cmb-field-list > .cmb-row:first-of-type > .cmb-th { + border: 0; +} + +/* line 165, sass/partials/_main_wrap.scss */ + +.cmb-add-row { + margin: 1.8em 0 0; +} + +/* line 169, sass/partials/_main_wrap.scss */ + +.cmb-nested .cmb-td, +.cmb-repeatable-group .cmb-th, +.cmb-repeatable-group:first-of-type { + border: 0; +} + +/* line 175, sass/partials/_main_wrap.scss */ + +.cmb-row:last-of-type, +.cmb2-wrap .cmb-row:last-of-type, +.cmb-repeatable-group:last-of-type { + border-bottom: 0; +} + +/* line 181, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-grouping { + border: 1px solid #e9e9e9; + padding: 0 1em; +} + +/* line 185, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-grouping.cmb-row { + margin: 0 0 0.8em; +} + +/* line 193, sass/partials/_main_wrap.scss */ + +.cmb-th { + color: #222222; + float: left; + font-weight: 600; + line-height: 1.3; + padding: 20px 10px 20px 0; + vertical-align: top; + width: 200px; +} + +/* line 207, sass/partials/_main_wrap.scss */ + +.cmb-td { + line-height: 1.3; + max-width: 100%; + padding: 15px 10px; + vertical-align: middle; +} + +/* line 216, sass/partials/_main_wrap.scss */ + +.cmb-type-title .cmb-td { + padding: 0; +} + +/* line 221, sass/partials/_main_wrap.scss */ + +.cmb-th label { + display: block; + padding: 5px 0; +} + +/* line 226, sass/partials/_main_wrap.scss */ + +.cmb-th + .cmb-td { + float: left; +} + +/* line 230, sass/partials/_main_wrap.scss */ + +.cmb-td .cmb-td { + padding-bottom: 1em; +} + +/* line 234, sass/partials/_main_wrap.scss */ + +.cmb-remove-row { + text-align: right; +} + +/* line 238, sass/partials/_main_wrap.scss */ + +.empty-row.hidden { + display: none; +} + +/* line 243, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table { + background-color: #fafafa; + border: 1px solid #e1e1e1; +} + +/* line 247, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row { + position: relative; + counter-increment: el; + margin: 0; + padding: 10px 10px 10px 50px; + border-bottom: none !important; +} + +/* line 255, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row + .cmb-repeat-row { + border-top: solid 1px #e9e9e9; +} + +/* line 259, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper { + outline: dashed 2px #e9e9e9 !important; +} + +/* line 263, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row:before { + content: counter(el); + display: block; + top: 0; + left: 0; + position: absolute; + width: 35px; + height: 100%; + line-height: 35px; + cursor: move; + color: #757575; + text-align: center; + border-right: solid 1px #e9e9e9; +} + +/* line 280, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td { + margin: 0; + padding: 0; +} + +/* line 287, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table + .cmb-add-row { + margin: 0; +} + +/* line 290, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table + .cmb-add-row:before { + content: ''; + width: 1px; + height: 1.6em; + display: block; + margin-left: 17px; + background-color: gainsboro; +} + +/* line 300, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-remove-row { + top: 7px; + right: 7px; + position: absolute; + width: auto; + margin-left: 0; + padding: 0 !important; + display: none; +} + +/* line 311, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button { + font-size: 20px; + text-indent: -1000px; + overflow: hidden; + position: relative; + height: auto; + line-height: 1; + padding: 0 10px 0; +} + +/* line 322, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-remove-row > .cmb-remove-row-button:before { + content: ""; + font-family: 'Dashicons'; + speak: none; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + margin: 0; + text-indent: 0; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; +} + +/* line 328, sass/partials/_main_wrap.scss */ + +.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row { + display: block; +} + +/* line 336, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-th { + padding: 5px; +} + +/* line 340, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-title { + background-color: #e9e9e9; + padding: 8px 12px 8px 2.2em; + margin: 0 -1em; + min-height: 1.5em; + font-size: 14px; + line-height: 1.4; +} + +/* line 348, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-title h4 { + border: 0; + margin: 0; + font-size: 1.2em; + font-weight: 500; + padding: 0.5em 0.75em; +} + +/* line 356, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-title .cmb-th { + display: block; + width: 100%; +} + +/* line 362, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-group-description .cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; +} + +/* line 27, sass/partials/_mixins.scss */ + +.cmb-repeatable-group .cmb-group-description .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} + +/* line 366, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-shift-rows { + font-size: 1em; + margin-right: 1em; + text-decoration: none; +} + +/* line 371, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-shift-rows .dashicons { + font-size: 1.5em; + height: 1.5em; + line-height: 1.2em; + width: 1em; +} + +/* line 377, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2 { + line-height: 1.3em; +} + +/* line 384, sass/partials/_main_wrap.scss */ + +.cmb-repeatable-group .cmb2-upload-button { + float: right; +} + +/* line 390, sass/partials/_main_wrap.scss */ + +p.cmb2-metabox-description { + color: #757575; + font-style: italic; + margin: 0; + padding-top: .5em; +} + +/* line 397, sass/partials/_main_wrap.scss */ + +span.cmb2-metabox-description { + color: #757575; + font-style: italic; +} + +/* line 402, sass/partials/_main_wrap.scss */ + +.cmb2-metabox-title { + margin: 0 0 5px 0; + padding: 5px 0 0 0; + font-size: 14px; +} + +/* line 408, sass/partials/_main_wrap.scss */ + +.cmb-inline ul { + padding: 4px 0 0 0; +} + +/* line 412, sass/partials/_main_wrap.scss */ + +.cmb-inline li { + display: inline-block; + padding-right: 18px; +} + +/* line 417, sass/partials/_main_wrap.scss */ + +.cmb-type-textarea-code pre { + margin: 0; +} + +/* line 423, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status { + clear: none; + display: inline-block; + vertical-align: middle; + margin-right: 10px; + width: auto; +} + +/* line 430, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status img { + max-width: 350px; + height: auto; +} + +/* line 436, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status img, +.cmb2-media-status .embed-status { + background: #eee; + border: 5px solid #ffffff; + outline: 1px solid #e9e9e9; + box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.05); + background-image: linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0), linear-gradient(45deg, #d0d0d0 25%, transparent 25%, transparent 75%, #d0d0d0 75%, #d0d0d0); + background-position: 0 0, 10px 10px; + background-size: 20px 20px; + border-radius: 2px; + -moz-border-radius: 2px; + margin: 15px 0 0 0; +} + +/* line 450, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .embed-status { + float: left; + max-width: 800px; +} + +/* line 455, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status, +.cmb2-media-status .embed-status { + position: relative; +} + +/* line 458, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status .cmb2-remove-file-button, +.cmb2-media-status .embed-status .cmb2-remove-file-button { + background: url(../images/ico-delete.png); + height: 16px; + left: -5px; + position: absolute; + text-indent: -9999px; + top: -5px; + width: 16px; +} + +/* line 472, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status .cmb2-remove-file-button { + top: 10px; +} + +/* line 477, sass/partials/_main_wrap.scss */ + +.cmb2-media-status .img-status img, +.cmb2-media-status .file-status > span { + cursor: pointer; +} + +/* line 482, sass/partials/_main_wrap.scss */ + +.cmb2-media-status.cmb-attach-list .img-status img, +.cmb2-media-status.cmb-attach-list .file-status > span { + cursor: move; +} + +/* line 489, sass/partials/_main_wrap.scss */ + +.cmb-type-file-list .cmb2-media-status .img-status { + clear: none; + vertical-align: middle; + width: auto; + margin-right: 10px; + margin-bottom: 10px; + margin-top: 0; +} + +/* line 498, sass/partials/_main_wrap.scss */ + +.cmb-attach-list li { + clear: both; + display: inline-block; + width: 100%; + margin-top: 5px; + margin-bottom: 10px; +} + +/* line 504, sass/partials/_main_wrap.scss */ + +.cmb-attach-list li img { + float: left; + margin-right: 10px; +} + +/* line 510, sass/partials/_main_wrap.scss */ + +.cmb2-remove-wrapper { + margin: 0; +} + +/* line 514, sass/partials/_main_wrap.scss */ + +.child-cmb2 .cmb-th { + text-align: left; +} + +/* line 518, sass/partials/_main_wrap.scss */ + +.cmb2-indented-hierarchy { + padding-left: 1.5em; +} + +/*-------------------------------------------------------------- + * Post Metaboxes +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_post_metaboxes.scss */ + +#poststuff .cmb-group-title { + margin-left: -1em; + margin-right: -1em; + min-height: 1.5em; +} + +/* line 11, sass/partials/_post_metaboxes.scss */ + +#poststuff .repeatable .cmb-group-title { + padding-left: 2.2em; +} + +/* line 17, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb2-wrap, +.cmb-type-group .cmb2-wrap { + margin: 0; +} + +/* line 20, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb2-wrap > .cmb-field-list > .cmb-row, +.cmb-type-group .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.8em 0; +} + +/* line 26, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed, +.cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed { + width: 100%; +} + +/* line 32, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row, +.cmb-type-group .cmb-row { + padding: 0 0 1.8em; + margin: 0 0 0.8em; +} + +/* line 36, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row .cmbhandle, +.cmb-type-group .cmb-row .cmbhandle { + right: -1em; + position: relative; + color: #222222; +} + +/* line 43, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-repeatable-grouping, +.cmb-type-group .cmb-repeatable-grouping { + padding: 0 1em; + max-width: 100%; + min-width: 1px !important; +} + +/* line 49, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-repeatable-group > .cmb-row, +.cmb-type-group .cmb-repeatable-group > .cmb-row { + padding-bottom: 0; +} + +/* line 53, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-th, +.cmb-type-group .cmb-th { + width: 18%; + padding: 0 2% 0 0; +} + +/* line 59, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-td, +.cmb-type-group .cmb-td { + margin-bottom: 0; + padding: 0; + line-height: 1.3; +} + +/* line 65, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-th + .cmb-td, +.cmb-type-group .cmb-th + .cmb-td { + width: 80%; + float: right; +} + +/* line 70, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), +.cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 1px solid #e9e9e9; +} + +/* line 79, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-repeat-group-field, +.cmb2-postbox .cmb-remove-field-row, +.cmb-type-group .cmb-repeat-group-field, +.cmb-type-group .cmb-remove-field-row { + padding-top: 1.8em; +} + +/*-------------------------------------------------------------- + * Context Metaboxes +--------------------------------------------------------------*/ + +/* Metabox collapse arrow indicators */ + +/* line 9, sass/partials/_context_metaboxes.scss */ + +.js .cmb2-postbox.context-box .toggle-indicator:before { + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} + +/* line 22, sass/partials/_context_metaboxes.scss */ + +.js .cmb2-postbox.context-box.closed .toggle-indicator:before { + content: "\f140"; +} + +/* line 30, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box { + margin-bottom: 10px; +} + +/* line 34, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-before_permalink-box { + margin-top: 10px; +} + +/* line 38, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-after_title-box { + margin-top: 10px; +} + +/* line 42, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-after_editor-box { + margin-top: 20px; + margin-bottom: 0; +} + +/* line 47, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-form_top-box { + margin-top: 10px; +} + +/* line 51, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box.context-form_top-box .hndle { + font-size: 14px; + padding: 8px 12px; + margin: 0; + line-height: 1.4; +} + +/* line 59, sass/partials/_context_metaboxes.scss */ + +.cmb2-postbox.context-box .hndle { + cursor: auto; +} + +/* line 64, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap { + margin-top: 10px; +} + +/* line 68, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 300px; + width: auto; +} + +/* line 75, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox { + padding: 10px; +} + +/* line 80, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-th { + padding: 0 2% 0 0; + width: 18%; +} + +/* line 85, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-td { + width: 80%; + padding: 0; +} + +/* line 90, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-row { + margin-bottom: 10px; +} + +/* line 93, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap .cmb-row:last-of-type { + margin-bottom: 0; +} + +/* one column on the post write/edit screen */ + +/*-------------------------------------------------------------- + * Options page +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_options-page.scss */ + +.cmb2-options-page { + max-width: 1200px; +} + +/* line 8, sass/partials/_options-page.scss */ + +.cmb2-options-page.wrap > h2 { + margin-bottom: 1em; +} + +/* line 12, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row { + padding: 1em; + margin-top: -1px; + background: #ffffff; + border: 1px solid #e9e9e9; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} + +/* line 19, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th { + padding: 0; + font-weight: initial; +} + +/* line 24, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th + .cmb-td { + float: none; + padding: 0 0 0 1em; + margin-left: 200px; +} + +/* line 37, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-wrap .cmb-type-title { + margin-top: 1em; + padding: 0.6em 1em; + background-color: #fafafa; +} + +/* line 42, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-title { + font-size: 12px; + margin-top: 0; + margin-bottom: 0; + text-transform: uppercase; +} + +/* line 49, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-description { + padding-top: 0.25em; +} + +/* line 55, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb-repeatable-group .cmb-group-description .cmb-th { + padding: 0 0 0.8em 0; +} + +/* line 59, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb-repeatable-group .cmb-group-name { + font-size: 16px; + margin-top: 0; + margin-bottom: 0; +} + +/* line 65, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb-repeatable-group .cmb-th > .cmb2-metabox-description { + font-weight: 400; + padding-bottom: 0 !important; +} + +/*-------------------------------------------------------------- + * New-Term Page +--------------------------------------------------------------*/ + +/* line 6, sass/partials/_new_term.scss */ + +#addtag .cmb-th { + float: none; + width: auto; + padding: 20px 0 0; +} + +/* line 12, sass/partials/_new_term.scss */ + +#addtag .cmb-td { + padding: 0; +} + +/* line 16, sass/partials/_new_term.scss */ + +#addtag .cmb-th + .cmb-td { + float: none; +} + +/* line 20, sass/partials/_new_term.scss */ + +#addtag select { + max-width: 100%; +} + +/* line 24, sass/partials/_new_term.scss */ + +#addtag .cmb2-metabox { + padding-bottom: 20px; +} + +/* line 28, sass/partials/_new_term.scss */ + +#addtag .cmb-row li label { + display: inline; +} + +/*-------------------------------------------------------------- + * Misc. +--------------------------------------------------------------*/ + +/* line 5, sass/partials/_misc.scss */ + +#poststuff .cmb-repeatable-group h2 { + margin: 0; +} + +/* line 12, sass/partials/_misc.scss */ + +.edit-tags-php .cmb2-metabox-title, +.profile-php .cmb2-metabox-title, +.user-edit-php .cmb2-metabox-title { + font-size: 1.4em; +} + +/* line 18, sass/partials/_misc.scss */ + +.cmb2-postbox .cmb-spinner, +.cmb2-no-box-wrap .cmb-spinner { + float: left; + display: none; +} + +/* line 24, sass/partials/_misc.scss */ + +.cmb-spinner { + display: none; +} + +/* line 26, sass/partials/_misc.scss */ + +.cmb-spinner.is-active { + display: block; +} + +/*-------------------------------------------------------------- + * Sidebar Placement Adjustments +--------------------------------------------------------------*/ + +/* line 10, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap > .cmb-field-list > .cmb-row, +#side-sortables .cmb2-wrap > .cmb-field-list > .cmb-row { + padding: 1.4em 0; +} + +/* line 16, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input[type=text]:not(.wp-color-picker), +#side-sortables .cmb2-wrap input[type=text]:not(.wp-color-picker) { + width: 100%; +} + +/* line 20, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input + input:not(.wp-picker-clear), +.inner-sidebar .cmb2-wrap input + select, +#side-sortables .cmb2-wrap input + input:not(.wp-picker-clear), +#side-sortables .cmb2-wrap input + select { + margin-left: 0; + margin-top: 1em; + display: block; +} + +/* line 26, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input.cmb2-text-money, +#side-sortables .cmb2-wrap input.cmb2-text-money { + max-width: 70%; +} + +/* line 28, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap input.cmb2-text-money + .cmb2-metabox-description, +#side-sortables .cmb2-wrap input.cmb2-text-money + .cmb2-metabox-description { + display: block; +} + +/* line 34, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-wrap label, +#side-sortables .cmb2-wrap label { + display: block; + font-weight: 700; + padding: 0 0 5px; +} + +/* line 42, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar textarea, +#side-sortables textarea { + max-width: 99%; +} + +/* line 46, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-repeatable-group, +#side-sortables .cmb-repeatable-group { + border-bottom: 1px solid #e9e9e9; +} + +/* line 50, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-type-group > .cmb-td > .cmb-repeatable-group, +#side-sortables .cmb-type-group > .cmb-td > .cmb-repeatable-group { + border-bottom: 0; + margin-bottom: -1.4em; +} + +/* line 55, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-th, +.inner-sidebar .cmb-td:not(.cmb-remove-row), +.inner-sidebar .cmb-th + .cmb-td, +#side-sortables .cmb-th, +#side-sortables .cmb-td:not(.cmb-remove-row), +#side-sortables .cmb-th + .cmb-td { + width: 100%; + display: block; + float: none; +} + +/* line 63, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .closed .inside, +#side-sortables .closed .inside { + display: none; +} + +/* line 67, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-th, +#side-sortables .cmb-th { + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; + padding-left: 0; + padding-right: 0; +} + +/* line 27, sass/partials/_mixins.scss */ + +.inner-sidebar .cmb-th label, +#side-sortables .cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} + +/* line 14, sass/partials/_mixins.scss */ + +.inner-sidebar .cmb-th label, +#side-sortables .cmb-th label { + font-size: 14px; + line-height: 1.4em; +} + +/* line 74, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-group-description .cmb-th, +#side-sortables .cmb-group-description .cmb-th { + padding-top: 0; +} + +/* line 77, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-group-description .cmb2-metabox-description, +#side-sortables .cmb-group-description .cmb2-metabox-description { + padding: 0; +} + +/* line 84, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-group-title .cmb-th, +#side-sortables .cmb-group-title .cmb-th { + padding: 0; +} + +/* line 90, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-repeatable-grouping + .cmb-repeatable-grouping, +#side-sortables .cmb-repeatable-grouping + .cmb-repeatable-grouping { + margin-top: 1em; +} + +/* line 99, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-media-status .img-status img, +.inner-sidebar .cmb2-media-status .embed-status img, +#side-sortables .cmb2-media-status .img-status img, +#side-sortables .cmb2-media-status .embed-status img { + max-width: 90%; + height: auto; +} + +/* line 107, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-list label, +#side-sortables .cmb2-list label { + display: inline; + font-weight: normal; +} + +/* line 112, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-metabox-description, +#side-sortables .cmb2-metabox-description { + display: block; + padding: 7px 0 0; +} + +/* line 119, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-type-checkbox .cmb-td label, +.inner-sidebar .cmb-type-checkbox .cmb2-metabox-description, +#side-sortables .cmb-type-checkbox .cmb-td label, +#side-sortables .cmb-type-checkbox .cmb2-metabox-description { + font-weight: normal; + display: inline; +} + +/* line 126, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-row .cmb2-metabox-description, +#side-sortables .cmb-row .cmb2-metabox-description { + padding-bottom: 1.8em; +} + +/* line 130, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-metabox-title, +#side-sortables .cmb2-metabox-title { + font-size: 1.2em; + font-style: italic; +} + +/* line 135, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb-remove-row, +#side-sortables .cmb-remove-row { + clear: both; + padding-top: 12px; + padding-bottom: 0; +} + +/* line 141, sass/partials/_sidebar_placements.scss */ + +.inner-sidebar .cmb2-upload-button, +#side-sortables .cmb2-upload-button { + clear: both; + margin-top: 12px; +} + +/*-------------------------------------------------------------- + * Collapsible UI +--------------------------------------------------------------*/ + +/* line 6, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox .cmbhandle { + color: #757575; + float: right; + width: 27px; + height: 30px; + cursor: pointer; + right: -1em; + position: relative; +} + +/* line 14, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox .cmbhandle:before { + content: '\f142'; + right: 12px; + font: normal 20px/1 'dashicons'; + speak: none; + display: inline-block; + padding: 8px 10px; + top: 0; + position: relative; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} + +/* line 31, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox .postbox.closed .cmbhandle:before { + content: '\f140'; +} + +/* line 37, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row { + -webkit-appearance: none !important; + background: none !important; + border: none !important; + position: absolute; + left: 0; + top: .5em; + line-height: 1em; + padding: 2px 6px 3px; + opacity: .5; +} + +/* line 47, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]) { + cursor: pointer; + color: #a00; + opacity: 1; +} + +/* line 51, sass/partials/_collapsible_ui.scss */ + +.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover { + color: #f00; +} + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress" + * https://github.com/stuttter/wp-datepicker-styling + * + */ + +/* line 15, sass/partials/_jquery_ui.scss */ + +* html .cmb2-element.ui-helper-clearfix { + height: 1%; +} + +/* line 24, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker, +.cmb2-element .ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + width: auto; /* Default Color Scheme */ +} + +/* line 38, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker *, +.cmb2-element .ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +/* line 46, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker table, +.cmb2-element .ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} + +/* line 53, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, +.cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} + +/* line 61, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, +.cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} + +/* line 67, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-title, +.cmb2-element .ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} + +/* line 75, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-title select, +.cmb2-element .ui-datepicker .ui-datepicker-title select { + margin-top: -8px; + margin-bottom: -8px; +} + +/* line 81, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-next { + position: relative; + top: 0; + height: 34px; + width: 34px; +} + +/* line 89, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} + +/* line 94, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover, +.cmb2-element .ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover { + left: 0; +} + +/* line 99, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover, +.cmb2-element .ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover { + right: 0; +} + +/* line 104, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next span, +.cmb2-element.ui-datepicker .ui-datepicker-prev span, +.cmb2-element .ui-datepicker .ui-datepicker-next span, +.cmb2-element .ui-datepicker .ui-datepicker-prev span { + display: none; +} + +/* line 109, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev, +.cmb2-element .ui-datepicker .ui-datepicker-prev { + float: left; +} + +/* line 113, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next, +.cmb2-element .ui-datepicker .ui-datepicker-next { + float: right; +} + +/* line 117, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element.ui-datepicker .ui-datepicker-next:before, +.cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-left: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} + +/* line 129, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.cmb2-element .ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} + +/* line 133, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-next:before, +.cmb2-element .ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} + +/* line 137, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before, +.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} + +/* line 142, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker select.ui-datepicker-month, +.cmb2-element.ui-datepicker select.ui-datepicker-year, +.cmb2-element .ui-datepicker select.ui-datepicker-month, +.cmb2-element .ui-datepicker select.ui-datepicker-year { + width: 33%; + background: transparent; + border-color: transparent; + box-shadow: none; + color: #fff; +} + +/* line 149, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker select.ui-datepicker-month option, +.cmb2-element.ui-datepicker select.ui-datepicker-year option, +.cmb2-element .ui-datepicker select.ui-datepicker-month option, +.cmb2-element .ui-datepicker select.ui-datepicker-year option { + color: #333; +} + +/* line 154, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker thead, +.cmb2-element .ui-datepicker thead { + color: #fff; + font-weight: 600; +} + +/* line 157, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker thead th, +.cmb2-element .ui-datepicker thead th { + font-weight: normal; +} + +/* line 162, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker th, +.cmb2-element .ui-datepicker th { + padding: 10px; +} + +/* line 166, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td, +.cmb2-element .ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; +} + +/* line 171, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-other-month, +.cmb2-element .ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} + +/* line 175, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-week-end, +.cmb2-element .ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} + +/* line 178, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today, +.cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today { + -webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1); +} + +/* line 185, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-today, +.cmb2-element .ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} + +/* line 189, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-datepicker-current-day, +.cmb2-element .ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} + +/* line 193, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td .ui-state-default, +.cmb2-element .ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} + +/* line 205, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default, +.cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} + +/* line 210, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-widget-header, +.cmb2-element.ui-datepicker .ui-datepicker-header, +.cmb2-element .ui-datepicker .ui-widget-header, +.cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +/* line 215, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker thead, +.cmb2-element .ui-datepicker thead { + background: #32373c; +} + +/* line 219, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker td .ui-state-hover, +.cmb2-element.ui-datepicker td .ui-state-active, +.cmb2-element .ui-datepicker td .ui-state-hover, +.cmb2-element .ui-datepicker td .ui-state-active { + background: #0073aa; + color: #fff; +} + +/* line 224, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div, +.cmb2-element .ui-datepicker .ui-timepicker-div { + font-size: 14px; +} + +/* line 226, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl, +.cmb2-element .ui-datepicker .ui-timepicker-div dl { + text-align: left; + padding: 0 .6em; +} + +/* line 229, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl dt, +.cmb2-element .ui-datepicker .ui-timepicker-div dl dt { + float: left; + clear: left; + padding: 0 0 0 5px; +} + +/* line 234, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd, +.cmb2-element .ui-datepicker .ui-timepicker-div dl dd { + margin: 0 10px 10px 40%; +} + +/* line 236, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select, +.cmb2-element .ui-datepicker .ui-timepicker-div dl dd select { + width: 100%; +} + +/* line 242, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane, +.cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane { + padding: .6em; + text-align: left; +} + +/* line 246, sass/partials/_jquery_ui.scss */ + +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, +.cmb2-element.ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary, +.cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-primary, +.cmb2-element .ui-datepicker .ui-timepicker-div + .ui-datepicker-buttonpane .button-secondary { + padding: 0 10px 1px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + margin: 0 .6em .4em .4em; +} + +/* line 260, sass/partials/_jquery_ui.scss */ + +.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +/* line 265, sass/partials/_jquery_ui.scss */ + +.admin-color-fresh .cmb2-element.ui-datepicker thead, +.admin-color-fresh .cmb2-element .ui-datepicker thead { + background: #32373c; +} + +/* line 269, sass/partials/_jquery_ui.scss */ + +.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* line 277, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #52accc; +} + +/* line 282, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker thead, +.admin-color-blue .cmb2-element .ui-datepicker thead { + background: #4796b3; +} + +/* line 291, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active, +.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover, +.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active { + background: #096484; + color: #fff; +} + +/* line 296, sass/partials/_jquery_ui.scss */ + +.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today, +.admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 305, sass/partials/_jquery_ui.scss */ + +.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #59524c; +} + +/* line 310, sass/partials/_jquery_ui.scss */ + +.admin-color-coffee .cmb2-element.ui-datepicker thead, +.admin-color-coffee .cmb2-element .ui-datepicker thead { + background: #46403c; +} + +/* line 314, sass/partials/_jquery_ui.scss */ + +.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +/* line 322, sass/partials/_jquery_ui.scss */ + +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} + +/* line 327, sass/partials/_jquery_ui.scss */ + +.admin-color-ectoplasm .cmb2-element.ui-datepicker thead, +.admin-color-ectoplasm .cmb2-element .ui-datepicker thead { + background: #413256; +} + +/* line 331, sass/partials/_jquery_ui.scss */ + +.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +/* line 339, sass/partials/_jquery_ui.scss */ + +.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} + +/* line 344, sass/partials/_jquery_ui.scss */ + +.admin-color-midnight .cmb2-element.ui-datepicker thead, +.admin-color-midnight .cmb2-element .ui-datepicker thead { + background: #26292c; +} + +/* line 348, sass/partials/_jquery_ui.scss */ + +.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +/* line 356, sass/partials/_jquery_ui.scss */ + +.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #738e96; +} + +/* line 361, sass/partials/_jquery_ui.scss */ + +.admin-color-ocean .cmb2-element.ui-datepicker thead, +.admin-color-ocean .cmb2-element .ui-datepicker thead { + background: #627c83; +} + +/* line 365, sass/partials/_jquery_ui.scss */ + +.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +/* line 373, sass/partials/_jquery_ui.scss */ + +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} + +/* line 379, sass/partials/_jquery_ui.scss */ + +.admin-color-sunrise .cmb2-element.ui-datepicker th, +.admin-color-sunrise .cmb2-element .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} + +/* line 384, sass/partials/_jquery_ui.scss */ + +.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +/* line 392, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} + +/* line 397, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month, +.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year { + color: #555; +} + +/* line 402, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker thead, +.admin-color-light .cmb2-element .ui-datepicker thead { + background: #888; +} + +/* line 406, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before { + color: #555; +} + +/* line 414, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-light .cmb2-element.ui-datepicker td .ui-state-active, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover, +.admin-color-light .cmb2-element .ui-datepicker td .ui-state-active { + background: #ccc; +} + +/* line 418, sass/partials/_jquery_ui.scss */ + +.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today, +.admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today { + background: #eee; +} + +/* line 426, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #56b274; +} + +/* line 431, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead { + background: #36533f; +} + +/* line 435, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +/* line 443, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} + +/* line 448, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-mint .cmb2-element.ui-datepicker thead, +.admin-color-bbp-mint .cmb2-element .ui-datepicker thead { + background: #4f6d59; +} + +/* line 452, sass/partials/_jquery_ui.scss */ + +.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover, +.admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} + +/*# sourceMappingURL=cmb2.css.map */ + +@media only screen and (max-width: 850px) { + +/* line 103, sass/partials/_context_metaboxes.scss */ + +.cmb2-context-wrap.cmb2-context-wrap-form_top { + margin-right: 0; +} + +} + +@media (max-width: 450px) { + +/* line 193, sass/partials/_main_wrap.scss */ + +.cmb-th { + font-size: 1.2em; + display: block; + float: none; + padding-bottom: 1em; + text-align: left; + width: 100%; +} + +/* line 27, sass/partials/_mixins.scss */ + +.cmb-th label { + display: block; + margin-top: 0; + margin-bottom: 0.5em; +} + +/* line 523, sass/partials/_main_wrap.scss */ + +.cmb-th, +.cmb-td, +.cmb-th + .cmb-td { + display: block; + float: none; + width: 100%; +} + +/* line 70, sass/partials/_post_metaboxes.scss */ + +.cmb2-postbox .cmb-row:not(:last-of-type), +.cmb2-postbox .cmb-repeatable-group:not(:last-of-type), +.cmb-type-group .cmb-row:not(:last-of-type), +.cmb-type-group .cmb-repeatable-group:not(:last-of-type) { + border-bottom: 0; +} + +/* line 24, sass/partials/_options-page.scss */ + +.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th + .cmb-td { + padding: 0; + margin-left: 0; +} + +} + diff --git a/inc/vendors/cmb2-plugins/cmb2/css/cmb2.min.css b/inc/vendors/cmb2-plugins/cmb2/css/cmb2.min.css new file mode 100755 index 00000000..ebe72573 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/cmb2.min.css @@ -0,0 +1,2 @@ +/*! CMB2 - v2.6.0 - 2019-01-18 | https://cmb2.io | Copyright (c) 2019 CMB2 team | Licensed GPLv2 */ +.cmb2-wrap{margin:0}.cmb2-wrap input,.cmb2-wrap textarea{font-size:14px;max-width:100%;padding:5px}.cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb2-wrap textarea{width:500px}.cmb2-wrap textarea.cmb2-textarea-code{font-family:"Courier 10 Pitch",Courier,monospace;line-height:16px}.cmb2-wrap input.cmb2-text-small,.cmb2-wrap input.cmb2-timepicker{width:100px}.cmb2-wrap input.cmb2-text-money{width:90px}.cmb2-wrap input.cmb2-text-medium{width:230px}.cmb2-wrap input.cmb2-upload-file{width:65%}.cmb2-wrap input.ed_button{padding:2px 4px}.cmb2-wrap input:not([type=hidden])+.button-secondary,.cmb2-wrap input:not([type=hidden])+input,.cmb2-wrap input:not([type=hidden])+select{margin-left:20px}.cmb2-wrap ul{margin:0}.cmb2-wrap li{font-size:14px;line-height:16px;margin:1px 0 5px}.cmb2-wrap select{font-size:14px;margin-top:3px}.cmb2-wrap input:focus,.cmb2-wrap textarea:focus{background:#fffff8}.cmb2-wrap input[type=checkbox],.cmb2-wrap input[type=radio]{margin:0 5px 0 0;padding:0}.cmb2-wrap .button-secondary,.cmb2-wrap button{white-space:nowrap}.cmb2-wrap .mceLayout{border:1px solid #e9e9e9!important}.cmb2-wrap .mceIframeContainer{background:#fff}.cmb2-wrap .meta_mce{width:97%}.cmb2-wrap .meta_mce textarea{width:100%}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-input-wrap{vertical-align:middle}.cmb2-wrap .wp-color-result,.cmb2-wrap .wp-picker-container{margin:0 10px 0 0}.cmb2-wrap .cmb-row{margin:0}.cmb2-wrap .cmb-row:after{content:'';clear:both;display:block;width:100%}.cmb2-wrap .cmb-row.cmb-repeat .cmb2-metabox-description{padding-top:0;padding-bottom:1em}.cmb2-metabox{clear:both;margin:0}.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox .cmb-field-list>.cmb-row:first-of-type>.cmb-th,.cmb2-metabox>.cmb-row:first-of-type>.cmb-td,.cmb2-metabox>.cmb-row:first-of-type>.cmb-th{border:0}.cmb-add-row{margin:1.8em 0 0}.cmb-nested .cmb-td,.cmb-repeatable-group .cmb-th,.cmb-repeatable-group:first-of-type{border:0}.cmb-repeatable-group:last-of-type,.cmb-row:last-of-type,.cmb2-wrap .cmb-row:last-of-type{border-bottom:0}.cmb-repeatable-grouping{border:1px solid #e9e9e9;padding:0 1em}.cmb-repeatable-grouping.cmb-row{margin:0 0 .8em}.cmb-th{color:#222;float:left;font-weight:600;line-height:1.3;padding:20px 10px 20px 0;vertical-align:top;width:200px}.cmb-td{line-height:1.3;max-width:100%;padding:15px 10px;vertical-align:middle}.cmb-type-title .cmb-td{padding:0}.cmb-th label{display:block;padding:5px 0}.cmb-th+.cmb-td{float:left}.cmb-td .cmb-td{padding-bottom:1em}.cmb-remove-row{text-align:right}.empty-row.hidden{display:none}.cmb-repeat-table{background-color:#fafafa;border:1px solid #e1e1e1}.cmb-repeat-table .cmb-row.cmb-repeat-row{position:relative;counter-increment:el;margin:0;padding:10px 10px 10px 50px;border-bottom:none!important}.cmb-repeat-table .cmb-row.cmb-repeat-row+.cmb-repeat-row{border-top:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row.ui-sortable-helper{outline:dashed 2px #e9e9e9!important}.cmb-repeat-table .cmb-row.cmb-repeat-row:before{content:counter(el);display:block;top:0;left:0;position:absolute;width:35px;height:100%;line-height:35px;cursor:move;color:#757575;text-align:center;border-right:solid 1px #e9e9e9}.cmb-repeat-table .cmb-row.cmb-repeat-row .cmb-td{margin:0;padding:0}.cmb-repeat-table+.cmb-add-row{margin:0}.cmb-repeat-table+.cmb-add-row:before{content:'';width:1px;height:1.6em;display:block;margin-left:17px;background-color:#dcdcdc}.cmb-repeat-table .cmb-remove-row{top:7px;right:7px;position:absolute;width:auto;margin-left:0;padding:0!important;display:none}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button{font-size:20px;text-indent:-1000px;overflow:hidden;position:relative;height:auto;line-height:1;padding:0 10px}.cmb-repeat-table .cmb-remove-row>.cmb-remove-row-button:before{content:"";font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.cmb-repeat-table .cmb-repeat-row:hover .cmb-remove-row{display:block}.cmb-repeatable-group .cmb-th{padding:5px}.cmb-repeatable-group .cmb-group-title{background-color:#e9e9e9;padding:8px 12px 8px 2.2em;margin:0 -1em;min-height:1.5em;font-size:14px;line-height:1.4}.cmb-repeatable-group .cmb-group-title h4{border:0;margin:0;font-size:1.2em;font-weight:500;padding:.5em .75em}.cmb-repeatable-group .cmb-group-title .cmb-th{display:block;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th{font-size:1.2em;display:block;float:none;padding-bottom:1em;text-align:left;width:100%}.cmb-repeatable-group .cmb-group-description .cmb-th label{display:block;margin-top:0;margin-bottom:.5em}.cmb-repeatable-group .cmb-shift-rows{font-size:1em;margin-right:1em;text-decoration:none}.cmb-repeatable-group .cmb-shift-rows .dashicons{font-size:1.5em;height:1.5em;line-height:1.2em;width:1em}.cmb-repeatable-group .cmb-shift-rows .dashicons.dashicons-arrow-down-alt2{line-height:1.3em}.cmb-repeatable-group .cmb2-upload-button{float:right}p.cmb2-metabox-description{color:#757575;font-style:italic;margin:0;padding-top:.5em}span.cmb2-metabox-description{color:#757575;font-style:italic}.cmb2-metabox-title{margin:0 0 5px;padding:5px 0 0;font-size:14px}.cmb-inline ul{padding:4px 0 0}.cmb-inline li{display:inline-block;padding-right:18px}.cmb-type-textarea-code pre{margin:0}.cmb2-media-status .img-status{clear:none;display:inline-block;vertical-align:middle;margin-right:10px;width:auto}.cmb2-media-status .img-status img{max-width:350px;height:auto}.cmb2-media-status .embed-status,.cmb2-media-status .img-status img{background:#eee;border:5px solid #fff;outline:1px solid #e9e9e9;box-shadow:inset 0 0 15px rgba(0,0,0,.3),inset 0 0 0 1px rgba(0,0,0,.05);background-image:linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0),linear-gradient(45deg,#d0d0d0 25%,transparent 25%,transparent 75%,#d0d0d0 75%,#d0d0d0);background-position:0 0,10px 10px;background-size:20px 20px;border-radius:2px;-moz-border-radius:2px;margin:15px 0 0}.cmb2-media-status .embed-status{float:left;max-width:800px}.cmb2-media-status .embed-status,.cmb2-media-status .img-status{position:relative}.cmb2-media-status .embed-status .cmb2-remove-file-button,.cmb2-media-status .img-status .cmb2-remove-file-button{background:url(../images/ico-delete.png);height:16px;left:-5px;position:absolute;text-indent:-9999px;top:-5px;width:16px}.cmb2-media-status .img-status .cmb2-remove-file-button{top:10px}.cmb2-media-status .file-status>span,.cmb2-media-status .img-status img{cursor:pointer}.cmb2-media-status.cmb-attach-list .file-status>span,.cmb2-media-status.cmb-attach-list .img-status img{cursor:move}.cmb-type-file-list .cmb2-media-status .img-status{clear:none;vertical-align:middle;width:auto;margin-right:10px;margin-bottom:10px;margin-top:0}.cmb-attach-list li{clear:both;display:inline-block;width:100%;margin-top:5px;margin-bottom:10px}.cmb-attach-list li img{float:left;margin-right:10px}.cmb2-remove-wrapper{margin:0}.child-cmb2 .cmb-th{text-align:left}.cmb2-indented-hierarchy{padding-left:1.5em}#poststuff .cmb-group-title{margin-left:-1em;margin-right:-1em;min-height:1.5em}#poststuff .repeatable .cmb-group-title{padding-left:2.2em}.cmb-type-group .cmb2-wrap,.cmb2-postbox .cmb2-wrap{margin:0}.cmb-type-group .cmb2-wrap>.cmb-field-list>.cmb-row,.cmb2-postbox .cmb2-wrap>.cmb-field-list>.cmb-row{padding:1.8em 0}.cmb-type-group .cmb2-wrap input[type=text].cmb2-oembed,.cmb2-postbox .cmb2-wrap input[type=text].cmb2-oembed{width:100%}.cmb-type-group .cmb-row,.cmb2-postbox .cmb-row{padding:0 0 1.8em;margin:0 0 .8em}.cmb-type-group .cmb-row .cmbhandle,.cmb2-postbox .cmb-row .cmbhandle{right:-1em;position:relative;color:#222}.cmb-type-group .cmb-repeatable-grouping,.cmb2-postbox .cmb-repeatable-grouping{padding:0 1em;max-width:100%;min-width:1px!important}.cmb-type-group .cmb-repeatable-group>.cmb-row,.cmb2-postbox .cmb-repeatable-group>.cmb-row{padding-bottom:0}.cmb-type-group .cmb-th,.cmb2-postbox .cmb-th{width:18%;padding:0 2% 0 0}.cmb-type-group .cmb-td,.cmb2-postbox .cmb-td{margin-bottom:0;padding:0;line-height:1.3}.cmb-type-group .cmb-th+.cmb-td,.cmb2-postbox .cmb-th+.cmb-td{width:80%;float:right}.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:1px solid #e9e9e9}.cmb-type-group .cmb-remove-field-row,.cmb-type-group .cmb-repeat-group-field,.cmb2-postbox .cmb-remove-field-row,.cmb2-postbox .cmb-repeat-group-field{padding-top:1.8em}.js .cmb2-postbox.context-box .toggle-indicator:before{content:"\f142";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.js .cmb2-postbox.context-box.closed .toggle-indicator:before{content:"\f140"}.cmb2-postbox.context-box{margin-bottom:10px}.cmb2-postbox.context-box.context-after_title-box,.cmb2-postbox.context-box.context-before_permalink-box{margin-top:10px}.cmb2-postbox.context-box.context-after_editor-box{margin-top:20px;margin-bottom:0}.cmb2-postbox.context-box.context-form_top-box{margin-top:10px}.cmb2-postbox.context-box.context-form_top-box .hndle{font-size:14px;padding:8px 12px;margin:0;line-height:1.4}.cmb2-postbox.context-box .hndle{cursor:auto}.cmb2-context-wrap{margin-top:10px}.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-right:300px;width:auto}.cmb2-context-wrap.cmb2-context-wrap-no-title .cmb2-metabox{padding:10px}.cmb2-context-wrap .cmb-th{padding:0 2% 0 0;width:18%}.cmb2-context-wrap .cmb-td{width:80%;padding:0}.cmb2-context-wrap .cmb-row{margin-bottom:10px}.cmb2-context-wrap .cmb-row:last-of-type{margin-bottom:0}.cmb2-options-page{max-width:1200px}.cmb2-options-page.wrap>h2{margin-bottom:1em}.cmb2-options-page .cmb2-metabox>.cmb-row{padding:1em;margin-top:-1px;background:#fff;border:1px solid #e9e9e9;box-shadow:0 1px 1px rgba(0,0,0,.05)}.cmb2-options-page .cmb2-metabox>.cmb-row>.cmb-th{padding:0;font-weight:initial}.cmb2-options-page .cmb2-metabox>.cmb-row>.cmb-th+.cmb-td{float:none;padding:0 0 0 1em;margin-left:200px}.cmb2-options-page .cmb2-wrap .cmb-type-title{margin-top:1em;padding:.6em 1em;background-color:#fafafa}.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-title{font-size:12px;margin-top:0;margin-bottom:0;text-transform:uppercase}.cmb2-options-page .cmb2-wrap .cmb-type-title .cmb2-metabox-description{padding-top:.25em}.cmb2-options-page .cmb-repeatable-group .cmb-group-description .cmb-th{padding:0 0 .8em}.cmb2-options-page .cmb-repeatable-group .cmb-group-name{font-size:16px;margin-top:0;margin-bottom:0}.cmb2-options-page .cmb-repeatable-group .cmb-th>.cmb2-metabox-description{font-weight:400;padding-bottom:0!important}#addtag .cmb-th{float:none;width:auto;padding:20px 0 0}#addtag .cmb-td{padding:0}#addtag .cmb-th+.cmb-td{float:none}#addtag select{max-width:100%}#addtag .cmb2-metabox{padding-bottom:20px}#addtag .cmb-row li label{display:inline}#poststuff .cmb-repeatable-group h2{margin:0}.edit-tags-php .cmb2-metabox-title,.profile-php .cmb2-metabox-title,.user-edit-php .cmb2-metabox-title{font-size:1.4em}.cmb2-no-box-wrap .cmb-spinner,.cmb2-postbox .cmb-spinner{float:left;display:none}.cmb-spinner{display:none}.cmb-spinner.is-active{display:block}#side-sortables .cmb2-wrap>.cmb-field-list>.cmb-row,.inner-sidebar .cmb2-wrap>.cmb-field-list>.cmb-row{padding:1.4em 0}#side-sortables .cmb2-wrap input[type=text]:not(.wp-color-picker),.inner-sidebar .cmb2-wrap input[type=text]:not(.wp-color-picker){width:100%}#side-sortables .cmb2-wrap input+input:not(.wp-picker-clear),#side-sortables .cmb2-wrap input+select,.inner-sidebar .cmb2-wrap input+input:not(.wp-picker-clear),.inner-sidebar .cmb2-wrap input+select{margin-left:0;margin-top:1em;display:block}#side-sortables .cmb2-wrap input.cmb2-text-money,.inner-sidebar .cmb2-wrap input.cmb2-text-money{max-width:70%}#side-sortables .cmb2-wrap input.cmb2-text-money+.cmb2-metabox-description,.inner-sidebar .cmb2-wrap input.cmb2-text-money+.cmb2-metabox-description{display:block}#side-sortables .cmb2-wrap label,.inner-sidebar .cmb2-wrap label{display:block;font-weight:700;padding:0 0 5px}#side-sortables textarea,.inner-sidebar textarea{max-width:99%}#side-sortables .cmb-repeatable-group,.inner-sidebar .cmb-repeatable-group{border-bottom:1px solid #e9e9e9}#side-sortables .cmb-type-group>.cmb-td>.cmb-repeatable-group,.inner-sidebar .cmb-type-group>.cmb-td>.cmb-repeatable-group{border-bottom:0;margin-bottom:-1.4em}#side-sortables .cmb-td:not(.cmb-remove-row),#side-sortables .cmb-th,#side-sortables .cmb-th+.cmb-td,.inner-sidebar .cmb-td:not(.cmb-remove-row),.inner-sidebar .cmb-th,.inner-sidebar .cmb-th+.cmb-td{width:100%;display:block;float:none}#side-sortables .closed .inside,.inner-sidebar .closed .inside{display:none}#side-sortables .cmb-th,.inner-sidebar .cmb-th{display:block;float:none;padding-bottom:1em;text-align:left;width:100%;padding-left:0;padding-right:0}#side-sortables .cmb-th label,.inner-sidebar .cmb-th label{display:block;margin-top:0;margin-bottom:.5em;font-size:14px;line-height:1.4em}#side-sortables .cmb-group-description .cmb-th,.inner-sidebar .cmb-group-description .cmb-th{padding-top:0}#side-sortables .cmb-group-description .cmb2-metabox-description,#side-sortables .cmb-group-title .cmb-th,.inner-sidebar .cmb-group-description .cmb2-metabox-description,.inner-sidebar .cmb-group-title .cmb-th{padding:0}#side-sortables .cmb-repeatable-grouping+.cmb-repeatable-grouping,.inner-sidebar .cmb-repeatable-grouping+.cmb-repeatable-grouping{margin-top:1em}#side-sortables .cmb2-media-status .embed-status img,#side-sortables .cmb2-media-status .img-status img,.inner-sidebar .cmb2-media-status .embed-status img,.inner-sidebar .cmb2-media-status .img-status img{max-width:90%;height:auto}#side-sortables .cmb2-list label,.inner-sidebar .cmb2-list label{display:inline;font-weight:400}#side-sortables .cmb2-metabox-description,.inner-sidebar .cmb2-metabox-description{display:block;padding:7px 0 0}#side-sortables .cmb-type-checkbox .cmb-td label,#side-sortables .cmb-type-checkbox .cmb2-metabox-description,.inner-sidebar .cmb-type-checkbox .cmb-td label,.inner-sidebar .cmb-type-checkbox .cmb2-metabox-description{font-weight:400;display:inline}#side-sortables .cmb-row .cmb2-metabox-description,.inner-sidebar .cmb-row .cmb2-metabox-description{padding-bottom:1.8em}#side-sortables .cmb2-metabox-title,.inner-sidebar .cmb2-metabox-title{font-size:1.2em;font-style:italic}#side-sortables .cmb-remove-row,.inner-sidebar .cmb-remove-row{clear:both;padding-top:12px;padding-bottom:0}#side-sortables .cmb2-upload-button,.inner-sidebar .cmb2-upload-button{clear:both;margin-top:12px}.cmb2-metabox .cmbhandle{color:#757575;float:right;width:27px;height:30px;cursor:pointer;right:-1em;position:relative}.cmb2-metabox .cmbhandle:before{content:'\f142';right:12px;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:8px 10px;top:0;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.cmb2-metabox .postbox.closed .cmbhandle:before{content:'\f140'}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row{-webkit-appearance:none!important;background:none!important;border:none!important;position:absolute;left:0;top:.5em;line-height:1em;padding:2px 6px 3px;opacity:.5}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]){cursor:pointer;color:#a00;opacity:1}.cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row:not([disabled]):hover{color:red}* html .cmb2-element.ui-helper-clearfix{height:1%}.cmb2-element .ui-datepicker,.cmb2-element.ui-datepicker{padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;background-color:#fff;border:1px solid #dfdfdf;border-top:none;-webkit-box-shadow:0 3px 6px rgba(0,0,0,.075);box-shadow:0 3px 6px rgba(0,0,0,.075);min-width:17em;width:auto}.cmb2-element .ui-datepicker *,.cmb2-element.ui-datepicker *{padding:0;font-family:"Open Sans",sans-serif;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.cmb2-element .ui-datepicker table,.cmb2-element.ui-datepicker table{font-size:13px;margin:0;border:none;border-collapse:collapse}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{border:none;color:#fff;font-weight:400}.cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover{background:0 0;border-color:transparent;cursor:pointer}.cmb2-element .ui-datepicker .ui-datepicker-title,.cmb2-element.ui-datepicker .ui-datepicker-title{margin:0;padding:10px 0;color:#fff;font-size:14px;line-height:14px;text-align:center}.cmb2-element .ui-datepicker .ui-datepicker-title select,.cmb2-element.ui-datepicker .ui-datepicker-title select{margin-top:-8px;margin-bottom:-8px}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-prev{position:relative;top:0;height:34px;width:34px}.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element .ui-datepicker .ui-state-hover.ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-next,.cmb2-element.ui-datepicker .ui-state-hover.ui-datepicker-prev{border:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover,.cmb2-element.ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover{left:0}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element .ui-datepicker .ui-datepicker-next-hover,.cmb2-element.ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next-hover{right:0}.cmb2-element .ui-datepicker .ui-datepicker-next span,.cmb2-element .ui-datepicker .ui-datepicker-prev span,.cmb2-element.ui-datepicker .ui-datepicker-next span,.cmb2-element.ui-datepicker .ui-datepicker-prev span{display:none}.cmb2-element .ui-datepicker .ui-datepicker-prev,.cmb2-element.ui-datepicker .ui-datepicker-prev{float:left}.cmb2-element .ui-datepicker .ui-datepicker-next,.cmb2-element.ui-datepicker .ui-datepicker-next{float:right}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{font:400 20px/34px dashicons;padding-left:7px;color:#fff;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:34px;height:34px}.cmb2-element .ui-datepicker .ui-datepicker-prev:before,.cmb2-element.ui-datepicker .ui-datepicker-prev:before{content:'\f341'}.cmb2-element .ui-datepicker .ui-datepicker-next:before,.cmb2-element.ui-datepicker .ui-datepicker-next:before{content:'\f345'}.cmb2-element .ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element .ui-datepicker .ui-datepicker-prev-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-next-hover:before,.cmb2-element.ui-datepicker .ui-datepicker-prev-hover:before{opacity:.7}.cmb2-element .ui-datepicker select.ui-datepicker-month,.cmb2-element .ui-datepicker select.ui-datepicker-year,.cmb2-element.ui-datepicker select.ui-datepicker-month,.cmb2-element.ui-datepicker select.ui-datepicker-year{width:33%;background:0 0;border-color:transparent;box-shadow:none;color:#fff}.cmb2-element .ui-datepicker select.ui-datepicker-month option,.cmb2-element .ui-datepicker select.ui-datepicker-year option,.cmb2-element.ui-datepicker select.ui-datepicker-month option,.cmb2-element.ui-datepicker select.ui-datepicker-year option{color:#333}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{color:#fff;font-weight:600}.cmb2-element .ui-datepicker thead th,.cmb2-element.ui-datepicker thead th{font-weight:400}.cmb2-element .ui-datepicker th,.cmb2-element.ui-datepicker th{padding:10px}.cmb2-element .ui-datepicker td,.cmb2-element.ui-datepicker td{padding:0;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-other-month,.cmb2-element.ui-datepicker td.ui-datepicker-other-month{border:transparent}.cmb2-element .ui-datepicker td.ui-datepicker-week-end,.cmb2-element.ui-datepicker td.ui-datepicker-week-end{background-color:#f4f4f4;border:1px solid #f4f4f4}.cmb2-element .ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-week-end.ui-datepicker-today{-webkit-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);-moz-box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1);box-shadow:inset 0 0 1px 0 rgba(0,0,0,.1)}.cmb2-element .ui-datepicker td.ui-datepicker-today,.cmb2-element.ui-datepicker td.ui-datepicker-today{background-color:#f0f0c0}.cmb2-element .ui-datepicker td.ui-datepicker-current-day,.cmb2-element.ui-datepicker td.ui-datepicker-current-day{background:#bd8}.cmb2-element .ui-datepicker td .ui-state-default,.cmb2-element.ui-datepicker td .ui-state-default{background:0 0;border:none;text-align:center;text-decoration:none;width:auto;display:block;padding:5px 10px;font-weight:400;color:#444}.cmb2-element .ui-datepicker td.ui-state-disabled .ui-state-default,.cmb2-element.ui-datepicker td.ui-state-disabled .ui-state-default{opacity:.5}.cmb2-element .ui-datepicker .ui-datepicker-header,.cmb2-element .ui-datepicker .ui-widget-header,.cmb2-element.ui-datepicker .ui-datepicker-header,.cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.cmb2-element .ui-datepicker thead,.cmb2-element.ui-datepicker thead{background:#32373c}.cmb2-element .ui-datepicker td .ui-state-active,.cmb2-element .ui-datepicker td .ui-state-hover,.cmb2-element.ui-datepicker td .ui-state-active,.cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.cmb2-element .ui-datepicker .ui-timepicker-div,.cmb2-element.ui-datepicker .ui-timepicker-div{font-size:14px}.cmb2-element .ui-datepicker .ui-timepicker-div dl,.cmb2-element.ui-datepicker .ui-timepicker-div dl{text-align:left;padding:0 .6em}.cmb2-element .ui-datepicker .ui-timepicker-div dl dt,.cmb2-element.ui-datepicker .ui-timepicker-div dl dt{float:left;clear:left;padding:0 0 0 5px}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd{margin:0 10px 10px 40%}.cmb2-element .ui-datepicker .ui-timepicker-div dl dd select,.cmb2-element.ui-datepicker .ui-timepicker-div dl dd select{width:100%}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane{padding:.6em;text-align:left}.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element .ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-primary,.cmb2-element.ui-datepicker .ui-timepicker-div+.ui-datepicker-buttonpane .button-secondary{padding:0 10px 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;margin:0 .6em .4em .4em}.admin-color-fresh .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-fresh .cmb2-element.ui-datepicker .ui-widget-header{background:#00a0d2}.admin-color-fresh .cmb2-element .ui-datepicker thead,.admin-color-fresh .cmb2-element.ui-datepicker thead{background:#32373c}.admin-color-fresh .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-fresh .cmb2-element.ui-datepicker td .ui-state-hover{background:#0073aa;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-blue .cmb2-element.ui-datepicker .ui-widget-header{background:#52accc}.admin-color-blue .cmb2-element .ui-datepicker thead,.admin-color-blue .cmb2-element.ui-datepicker thead{background:#4796b3}.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-blue .cmb2-element.ui-datepicker td .ui-state-hover{background:#096484;color:#fff}.admin-color-blue .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-blue .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-coffee .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-coffee .cmb2-element.ui-datepicker .ui-widget-header{background:#59524c}.admin-color-coffee .cmb2-element .ui-datepicker thead,.admin-color-coffee .cmb2-element.ui-datepicker thead{background:#46403c}.admin-color-coffee .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-coffee .cmb2-element.ui-datepicker td .ui-state-hover{background:#c7a589;color:#fff}.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ectoplasm .cmb2-element.ui-datepicker .ui-widget-header{background:#523f6d}.admin-color-ectoplasm .cmb2-element .ui-datepicker thead,.admin-color-ectoplasm .cmb2-element.ui-datepicker thead{background:#413256}.admin-color-ectoplasm .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ectoplasm .cmb2-element.ui-datepicker td .ui-state-hover{background:#a3b745;color:#fff}.admin-color-midnight .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-midnight .cmb2-element.ui-datepicker .ui-widget-header{background:#363b3f}.admin-color-midnight .cmb2-element .ui-datepicker thead,.admin-color-midnight .cmb2-element.ui-datepicker thead{background:#26292c}.admin-color-midnight .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-midnight .cmb2-element.ui-datepicker td .ui-state-hover{background:#e14d43;color:#fff}.admin-color-ocean .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-ocean .cmb2-element.ui-datepicker .ui-widget-header{background:#738e96}.admin-color-ocean .cmb2-element .ui-datepicker thead,.admin-color-ocean .cmb2-element.ui-datepicker thead{background:#627c83}.admin-color-ocean .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-ocean .cmb2-element.ui-datepicker td .ui-state-hover{background:#9ebaa0;color:#fff}.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-datepicker-header .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker .ui-widget-header{background:#cf4944}.admin-color-sunrise .cmb2-element .ui-datepicker th,.admin-color-sunrise .cmb2-element.ui-datepicker th{border-color:#be3631;background:#be3631}.admin-color-sunrise .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-sunrise .cmb2-element.ui-datepicker td .ui-state-hover{background:#dd823b;color:#fff}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-light .cmb2-element.ui-datepicker .ui-widget-header{background:#e5e5e5}.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element .ui-datepicker select.ui-datepicker-year,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-month,.admin-color-light .cmb2-element.ui-datepicker select.ui-datepicker-year{color:#555}.admin-color-light .cmb2-element .ui-datepicker thead,.admin-color-light .cmb2-element.ui-datepicker thead{background:#888}.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element .ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-default,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-next:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-prev:before,.admin-color-light .cmb2-element.ui-datepicker .ui-datepicker-title,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-default{color:#555}.admin-color-light .cmb2-element .ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-active,.admin-color-light .cmb2-element.ui-datepicker td .ui-state-hover{background:#ccc}.admin-color-light .cmb2-element .ui-datepicker td.ui-datepicker-today,.admin-color-light .cmb2-element.ui-datepicker td.ui-datepicker-today{background:#eee}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker .ui-widget-header{background:#56b274}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker thead,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker thead{background:#36533f}.admin-color-bbp-evergreen .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-evergreen .cmb2-element.ui-datepicker td .ui-state-hover{background:#446950;color:#fff}.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element .ui-datepicker .ui-widget-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-datepicker-header,.admin-color-bbp-mint .cmb2-element.ui-datepicker .ui-widget-header{background:#4ca26a}.admin-color-bbp-mint .cmb2-element .ui-datepicker thead,.admin-color-bbp-mint .cmb2-element.ui-datepicker thead{background:#4f6d59}.admin-color-bbp-mint .cmb2-element .ui-datepicker td .ui-state-hover,.admin-color-bbp-mint .cmb2-element.ui-datepicker td .ui-state-hover{background:#5fb37c;color:#fff}@media only screen and (max-width:850px){.cmb2-context-wrap.cmb2-context-wrap-form_top{margin-right:0}}@media (max-width:450px){.cmb-th{font-size:1.2em;padding-bottom:1em;text-align:left}.cmb-th label{display:block;margin-top:0;margin-bottom:.5em}.cmb-td,.cmb-th,.cmb-th+.cmb-td{display:block;float:none;width:100%}.cmb-type-group .cmb-repeatable-group:not(:last-of-type),.cmb-type-group .cmb-row:not(:last-of-type),.cmb2-postbox .cmb-repeatable-group:not(:last-of-type),.cmb2-postbox .cmb-row:not(:last-of-type){border-bottom:0}.cmb2-options-page .cmb2-metabox>.cmb-row>.cmb-th+.cmb-td{padding:0;margin-left:0}} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/css/index.php b/inc/vendors/cmb2-plugins/cmb2/css/index.php new file mode 100755 index 00000000..eea59b98 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/css/index.php @@ -0,0 +1,2 @@ + 0 && longitude.val().length > 0 ) { + latLng = new google.maps.LatLng( latitude.val(), longitude.val() ); + zoom = 17; + } + + // Map + var mapOptions = { + center: latLng, + zoom: zoom + }; + var map = new google.maps.Map( mapCanvas[0], mapOptions ); + + latitude.on('change', function() { + map.setCenter( new google.maps.LatLng( latitude.val(), longitude.val() ) ); + }); + + longitude.on('change', function() { + map.setCenter( new google.maps.LatLng( latitude.val(), longitude.val() ) ); + }); + + // Marker + var markerOptions = { + map: map, + draggable: true, + title: 'Drag to set the exact location' + }; + var marker = new google.maps.Marker( markerOptions ); + + //if ( latitude.val().length > 0 && longitude.val().length > 0 ) { + marker.setPosition( latLng ); + // } + + // Search + var autocomplete = new google.maps.places.Autocomplete( searchInput[0] ); + autocomplete.bindTo( 'bounds', map ); + + google.maps.event.addListener( autocomplete, 'place_changed', function() { + var place = autocomplete.getPlace(); + if ( ! place.geometry ) { + return; + } + + if ( place.geometry.viewport ) { + map.fitBounds( place.geometry.viewport ); + } else { + map.setCenter( place.geometry.location ); + map.setZoom( 17 ); + } + + marker.setPosition( place.geometry.location ); + + latitude.val( place.geometry.location.lat() ); + longitude.val( place.geometry.location.lng() ); + }); + + $( searchInput ).keypress( function( event ) { + if ( 13 === event.keyCode ) { + event.preventDefault(); + } + }); + + // Allow marker to be repositioned + google.maps.event.addListener( marker, 'drag', function() { + latitude.val( marker.getPosition().lat() ); + longitude.val( marker.getPosition().lng() ); + }); + + maps.push( map ); + } + + // Resize map when meta box is opened + if ( typeof postboxes !== 'undefined' ) { + postboxes.pbshow = function () { + var arrayLength = maps.length; + for (var i = 0; i < arrayLength; i++) { + var mapCenter = maps[i].getCenter(); + google.maps.event.trigger( maps[i], 'resize' ); + maps[i].setCenter( mapCenter ); + } + }; + } + + // When a new row is added, reinitialize Google Maps + $( '.cmb-repeatable-group' ).on( 'cmb2_add_row', function( event, newRow ) { + var groupWrap = $( newRow ).closest( '.cmb-repeatable-group' ); + groupWrap.find( '.cmb-type-opal-map' ).each( function() { + initializeMap( $( this ) ); + }); + }); + +})( jQuery ); diff --git a/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php b/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php new file mode 100755 index 00000000..0c9ffd04 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php @@ -0,0 +1,116 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +class Opalestate_Field_Map { + + /** + * Current version number + */ + const VERSION = '1.0.0'; + + /** + * Initialize the plugin by hooking into CMB2 + */ + public function __construct() { + add_filter( 'cmb2_render_opal_map', array( $this, 'render_map' ), 10, 5 ); + add_filter( 'cmb2_sanitize_opal_map', array( $this, 'sanitize_map' ), 10, 4 ); + } + + /** + * Render field + */ + public function render_map( $field, $field_escaped_value, $field_object_id, $field_object_type, $field_type_object ) { + $this->setup_admin_scripts(); + $address = (isset( $field_escaped_value['address'] ) ? $field_escaped_value['address'] : ''); + + echo '
            +
            +
            +
            +
            +
            + + '; + echo '
            '; + + $field_type_object->_desc( true, true ); + + echo '
            '; + echo ''; + echo $field_type_object->input( array( + 'type' => 'text', + 'name' => $field->args( '_name' ) . '[latitude]', + 'value' => isset( $field_escaped_value['latitude'] ) ? $field_escaped_value['latitude'] : '', + 'class' => 'opal-map-latitude form-control', + 'desc' => '', + ) ); + echo '
            '; + echo '
            '; + echo ''; + echo $field_type_object->input( array( + 'type' => 'text', + 'name' => $field->args( '_name' ) . '[longitude]', + 'value' => isset( $field_escaped_value['longitude'] ) ? $field_escaped_value['longitude'] : '', + 'class' => 'opal-map-longitude form-control', + 'desc' => '', + ) ); + echo '
            '; + echo '

            ' . __( 'You need to register Google API Key, then put the key in plugin setting.', + 'opalestate-pro' ) . '

            '; + + echo '
            '; + echo '
            '; + } + + /** + * Optionally save the latitude/longitude values into two custom fields + */ + public function sanitize_map( $override_value, $value, $object_id, $field_args ) { + if ( isset( $field_args['split_values'] ) && $field_args['split_values'] ) { + if ( ! empty( $value['latitude'] ) ) { + update_post_meta( $object_id, $field_args['id'] . '_latitude', $value['latitude'] ); + } + + if ( ! empty( $value['longitude'] ) ) { + update_post_meta( $object_id, $field_args['id'] . '_longitude', $value['longitude'] ); + } + + if ( ! empty( $value['address'] ) ) { + update_post_meta( $object_id, $field_args['id'] . '_address', $value['address'] ); + } + } + + return $value; + } + + /** + * Enqueue scripts and styles + */ + public function setup_admin_scripts() { + $api = opalestate_get_map_api_uri(); + + wp_enqueue_script("opalestate-google-maps", $api, null, "0.0.1", false); + + wp_enqueue_script( 'opalestate-google-maps-js', plugins_url( 'js/script.js', __FILE__ ), array( ) ); + wp_enqueue_style( 'opalestate-google-maps', plugins_url( 'css/style.css', __FILE__ ), array() ); + + + } +} + +new Opalestate_Field_Map(); diff --git a/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/readme.md b/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/readme.md new file mode 100755 index 00000000..edab3718 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/readme.md @@ -0,0 +1,39 @@ +# CMB2 Field Type: Google Maps + +## Description + +Google Maps field type for [CMB2](https://github.com/WebDevStudios/CMB2). + +The `pw_map` field stores the latitude/longitude values which you can then use to display a map in your theme. + +## Installation + +You can install this field type as you would a WordPress plugin: + +1. Download the plugin +2. Place the plugin folder in your `/wp-content/plugins/` directory +3. Activate the plugin in the Plugin dashboard + +## Usage + +### `pw_map` + +Save a location on a map. Example: + +```php +array( + 'name' => 'Location', + 'desc' => 'Drag the marker to set the exact location', + 'id' => $prefix . 'location', + 'type' => 'pw_map', + // 'split_values' => true, // Save latitude and longitude as two separate fields +), +``` + +#### Extra Parameters: + +* `split_values` Save the latitude/longitude values into two custom fields, they will be stored as `$id . '_latitude'` and `$id . '_longitude'`. + +## Screenshot + +![Image](screenshot-1.png?raw=true) \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/screenshot-1.png b/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/screenshot-1.png new file mode 100755 index 00000000..e2859114 Binary files /dev/null and b/inc/vendors/cmb2-plugins/cmb2/custom-fields/map/screenshot-1.png differ diff --git a/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/assets/script.js b/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/assets/script.js new file mode 100755 index 00000000..03d5becb --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/assets/script.js @@ -0,0 +1,49 @@ +(function( $ ) { + 'use strict'; + $( document ).ready( function() { + + + $( ".adduser-team" ).delegate( ".remove-user", "click", function() { + if( confirm( $(this).data('alert') ) ){ + $(this).parents( '.user-team' ).remove(); + } + }); + + $( '.opalestate-add-user-field' ).each( function() { + var $this = $(this); + $('.button', this).click( function () { + + + var user_search = $( '.opalestate-adduser-search', $(this).parent().parent() ).val(); + + + $('.opalestate-ajax').show(); + + var data = { + action: 'opalestate_ajax_search_username', + user_name: user_search, + + }; + + + + $.ajax({ + type: "POST", + data: data, + dataType: "json", + url: ajaxurl, + success: function ( response ) { + if( response.status == true ){ + var template = wp.template( 'adduser-team-template' ); + $('.adduser-team', $this ).append( template( response.user ) ); + }else { + alert( response.message ); + } + } + }); + + } ); + } ); + } ); + +})( jQuery ); \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/assets/style.css b/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/assets/style.css new file mode 100755 index 00000000..aa9106a3 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/assets/style.css @@ -0,0 +1,29 @@ +.adduser-team{ + width: 80%; +} +.user-team{ + padding: 12px 10px; + display: block; + border-bottom: solid 1px #f3f3f3 +} +.user-team > div{ + display: inline-block; + width: 33%; + +} + +.user-team > div img{ + width: 30px; + height: 30px; + border: solid 3px #CCC; + border-radius: 50%; + float: left; + margin-right: 6px; +} + +.remove-user { + cursor: pointer; +} +.remove-user:hover { + color: red; +} \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php b/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php new file mode 100755 index 00000000..4561f746 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php @@ -0,0 +1,100 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +class Opalestate_Field_Adduser { + + /** + * Current version number + */ + const VERSION = '1.0.0'; + + /** + * Initialize the plugin by hooking into CMB2 + */ + public static function init() { + add_filter( 'cmb2_render_adduser', array( __CLASS__, 'render_map' ), 10, 5 ); + add_filter( 'cmb2_sanitize_adduser', array( __CLASS__, 'sanitize_map' ), 10, 4 ); + } + + /** + * Render field + */ + public static function render_map( $field, $field_escaped_value, $field_object_id, $field_object_type, $field_type_object ) { + self::setup_admin_scripts(); + + $users = $field->value; + + // echo '
            '.print_r( $value, 1 );die;
            +		echo '
            '; ?> +
            +
            +
            +

            + +
            + +
            +
            +
            +
            +
            +
            + + + data ?> +
            + + +
            +
            + + + +
            +
            + + + + '; + } + + /** + * Optionally save the latitude/longitude values into two custom fields + */ + public static function sanitize_map( $override_value, $value, $object_id, $field_args ) { + + return $value; + } + + /** + * Enqueue scripts and styles + */ + public static function setup_admin_scripts() { + wp_enqueue_script( 'opalestate-adduser', plugins_url( 'assets/script.js', __FILE__ ), array( ), self::VERSION ); + wp_enqueue_style( 'opalestate-adduser', plugins_url( 'assets/style.css', __FILE__ ), array(), self::VERSION ); + } +} + +Opalestate_Field_Adduser::init(); diff --git a/inc/vendors/cmb2-plugins/cmb2/images/ico-delete.png b/inc/vendors/cmb2-plugins/cmb2/images/ico-delete.png new file mode 100755 index 00000000..08f24936 Binary files /dev/null and b/inc/vendors/cmb2-plugins/cmb2/images/ico-delete.png differ diff --git a/inc/vendors/cmb2-plugins/cmb2/images/index.php b/inc/vendors/cmb2-plugins/cmb2/images/index.php new file mode 100755 index 00000000..eea59b98 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/images/index.php @@ -0,0 +1,2 @@ + '', + 'title' => '', + // Post type slug, or 'user', 'term', 'comment', or 'options-page'. + 'object_types' => array(), + + /** + * The context within the screen where the boxes should display. Available contexts vary + * from screen to screen. Post edit screen contexts include 'normal', 'side', and 'advanced'. + * + * For placement in locations outside of a metabox, other options include: + * 'form_top', 'before_permalink', 'after_title', 'after_editor' + * + * Comments screen contexts include 'normal' and 'side'. Default is 'normal'. + */ + 'context' => 'normal', + 'priority' => 'high', + 'show_names' => true, // Show field names on the left. + 'show_on_cb' => null, // Callback to determine if metabox should display. + 'show_on' => array(), // Post IDs or page templates to display this metabox. overrides 'show_on_cb'. + 'cmb_styles' => true, // Include CMB2 stylesheet. + 'enqueue_js' => true, // Include CMB2 JS. + 'fields' => array(), + + /** + * Handles hooking CMB2 forms/metaboxes into the post/attachement/user/options-page screens + * and handles hooking in and saving those fields. + */ + 'hookup' => true, + 'save_fields' => true, // Will not save during hookup if false. + 'closed' => false, // Default metabox to being closed. + 'taxonomies' => array(), + 'new_user_section' => 'add-new-user', // or 'add-existing-user'. + 'new_term_section' => true, + 'show_in_rest' => false, + 'classes' => null, // Optionally add classes to the CMB2 wrapper. + 'classes_cb' => '', // Optionally add classes to the CMB2 wrapper (via a callback). + + /* + * The following parameter is for post alternate-context metaboxes only. + * + * To output the fields 'naked' (without a postbox wrapper/style), then + * add a `'remove_box_wrap' => true` to your metabox registration array. + */ + 'remove_box_wrap' => false, + + /* + * The following parameter is any additional arguments passed as $callback_args + * to add_meta_box, if/when applicable. + * + * CMB2 does not use these arguments in the add_meta_box callback, however, these args + * are parsed for certain special properties, like determining Gutenberg/block-editor + * compatibility. + * + * Examples: + * + * - Make sure default editor is used as metabox is not compatible with block editor + * [ '__block_editor_compatible_meta_box' => false/true ] + * + * - Or declare this box exists for backwards compatibility + * [ '__back_compat_meta_box' => false ] + * + * More: https://wordpress.org/gutenberg/handbook/extensibility/meta-box/ + */ + 'mb_callback_args' => null, + + /* + * The following parameters are for options-page metaboxes, + * and several are passed along to add_menu_page()/add_submenu_page() + */ + + // 'menu_title' => null, // Falls back to 'title' (above). Do not define here so we can set a fallback. + 'message_cb' => '', // Optionally define the options-save message (via a callback). + 'option_key' => '', // The actual option key and admin menu page slug. + 'parent_slug' => '', // Used as first param in add_submenu_page(). + 'capability' => 'manage_options', // Cap required to view options-page. + 'icon_url' => '', // Menu icon. Only applicable if 'parent_slug' is left empty. + 'position' => null, // Menu position. Only applicable if 'parent_slug' is left empty. + + 'admin_menu_hook' => 'admin_menu', // Alternately 'network_admin_menu' to add network-level options page. + 'display_cb' => false, // Override the options-page form output (CMB2_Hookup::options_page_output()). + 'save_button' => '', // The text for the options-page save button. Defaults to 'Save'. + 'disable_settings_errors' => false, // On settings pages (not options-general.php sub-pages), allows disabling. + 'tab_group' => '', // Tab-group identifier, enables options page tab navigation. + // 'tab_title' => null, // Falls back to 'title' (above). Do not define here so we can set a fallback. + // 'autoload' => true, // Defaults to true, the options-page option will be autloaded. + ); + + /** + * Metabox field objects + * + * @var array + * @since 2.0.3 + */ + protected $fields = array(); + + /** + * An array of hidden fields to output at the end of the form + * + * @var array + * @since 2.0.0 + */ + protected $hidden_fields = array(); + + /** + * Array of key => value data for saving. Likely $_POST data. + * + * @var string + * @since 2.0.0 + */ + protected $generated_nonce = ''; + + /** + * Whether there are fields to be shown in columns. Set in CMB2::add_field(). + * + * @var bool + * @since 2.2.2 + */ + protected $has_columns = false; + + /** + * If taxonomy field is requesting to remove_default, we store the taxonomy here. + * + * @var array + * @since 2.2.3 + */ + protected $tax_metaboxes_to_remove = array(); + + /** + * Get started + * + * @since 0.4.0 + * @param array $config Metabox config array. + * @param integer $object_id Optional object id. + */ + public function __construct( $config, $object_id = 0 ) { + + if ( empty( $config['id'] ) ) { + wp_die( esc_html__( 'Metabox configuration is required to have an ID parameter.', 'cmb2' ) ); + } + + $this->cmb_id = $config['id']; + $this->meta_box = wp_parse_args( $config, $this->mb_defaults ); + $this->meta_box['fields'] = array(); + + // Ensures object_types is an array. + $this->set_prop( 'object_types', $this->box_types() ); + $this->object_id( $object_id ); + + if ( $this->is_options_page_mb() ) { + $this->init_options_mb(); + } + + $this->mb_object_type(); + + if ( ! empty( $config['fields'] ) && is_array( $config['fields'] ) ) { + $this->add_fields( $config['fields'] ); + } + + CMB2_Boxes::add( $this ); + + /** + * Hook during initiation of CMB2 object + * + * The dynamic portion of the hook name, $this->cmb_id, is this meta_box id. + * + * @param array $cmb This CMB2 object + */ + do_action( "cmb2_init_{$this->cmb_id}", $this ); + + // Hook in the hookup... how meta. + add_action( "cmb2_init_hookup_{$this->cmb_id}", array( 'CMB2_hookup', 'maybe_init_and_hookup' ) ); + + // Hook in the rest api functionality. + add_action( "cmb2_init_hookup_{$this->cmb_id}", array( 'CMB2_REST', 'maybe_init_and_hookup' ) ); + } + + /** + * Loops through and displays fields + * + * @since 1.0.0 + * @param int $object_id Object ID. + * @param string $object_type Type of object being saved. (e.g., post, user, or comment). + * + * @return CMB2 + */ + public function show_form( $object_id = 0, $object_type = '' ) { + $this->render_form_open( $object_id, $object_type ); + + foreach ( $this->prop( 'fields' ) as $field_args ) { + $this->render_field( $field_args ); + } + + return $this->render_form_close( $object_id, $object_type ); + } + + /** + * Outputs the opening form markup and runs corresponding hooks: + * 'cmb2_before_form' and "cmb2_before_{$object_type}_form_{$this->cmb_id}" + * + * @since 2.2.0 + * @param integer $object_id Object ID. + * @param string $object_type Object type. + * + * @return CMB2 + */ + public function render_form_open( $object_id = 0, $object_type = '' ) { + $object_type = $this->object_type( $object_type ); + $object_id = $this->object_id( $object_id ); + + echo "\n\n"; + + $this->nonce_field(); + + /** + * Hook before form table begins + * + * @param array $cmb_id The current box ID. + * @param int $object_id The ID of the current object. + * @param string $object_type The type of object you are working with. + * Usually `post` (this applies to all post-types). + * Could also be `comment`, `user` or `options-page`. + * @param array $cmb This CMB2 object. + */ + do_action( 'cmb2_before_form', $this->cmb_id, $object_id, $object_type, $this ); + + /** + * Hook before form table begins + * + * The first dynamic portion of the hook name, $object_type, is the type of object + * you are working with. Usually `post` (this applies to all post-types). + * Could also be `comment`, `user` or `options-page`. + * + * The second dynamic portion of the hook name, $this->cmb_id, is the meta_box id. + * + * @param array $cmb_id The current box ID + * @param int $object_id The ID of the current object + * @param array $cmb This CMB2 object + */ + do_action( "cmb2_before_{$object_type}_form_{$this->cmb_id}", $object_id, $this ); + + echo '
            '; + + return $this; + } + + /** + * Defines the classes for the CMB2 form/wrap. + * + * @since 2.0.0 + * @return string Space concatenated list of classes + */ + public function box_classes() { + + $classes = array( 'cmb2-wrap', 'form-table' ); + + // Use the callback to fetch classes. + if ( $added_classes = $this->get_param_callback_result( 'classes_cb' ) ) { + $added_classes = is_array( $added_classes ) ? $added_classes : array( $added_classes ); + $classes = array_merge( $classes, $added_classes ); + } + + if ( $added_classes = $this->prop( 'classes' ) ) { + $added_classes = is_array( $added_classes ) ? $added_classes : array( $added_classes ); + $classes = array_merge( $classes, $added_classes ); + } + + /** + * Add our context classes for non-standard metaboxes. + * + * @since 2.2.4 + */ + if ( $this->is_alternate_context_box() ) { + $context = array(); + + // Include custom class if requesting no title. + if ( ! $this->prop( 'title' ) && ! $this->prop( 'remove_box_wrap' ) ) { + $context[] = 'cmb2-context-wrap-no-title'; + } + + // Include a generic context wrapper. + $context[] = 'cmb2-context-wrap'; + + // Include a context-type based context wrapper. + $context[] = 'cmb2-context-wrap-' . $this->prop( 'context' ); + + // Include an ID based context wrapper as well. + $context[] = 'cmb2-context-wrap-' . $this->prop( 'id' ); + + // And merge all the classes back into the array. + $classes = array_merge( $classes, $context ); + } + + /** + * Globally filter box wrap classes + * + * @since 2.2.2 + * + * @param string $classes Array of classes for the cmb2-wrap. + * @param CMB2 $cmb This CMB2 object. + */ + $classes = apply_filters( 'cmb2_wrap_classes', $classes, $this ); + + // Clean up. + $classes = array_map( 'strip_tags', array_filter( $classes ) ); + + // Remove any duplicates. + $classes = array_unique( $classes ); + + // Make a string. + return implode( ' ', $classes ); + } + + /** + * Outputs the closing form markup and runs corresponding hooks: + * 'cmb2_after_form' and "cmb2_after_{$object_type}_form_{$this->cmb_id}" + * + * @since 2.2.0 + * @param integer $object_id Object ID. + * @param string $object_type Object type. + * + * @return CMB2 + */ + public function render_form_close( $object_id = 0, $object_type = '' ) { + $object_type = $this->object_type( $object_type ); + $object_id = $this->object_id( $object_id ); + + echo '
            '; + + $this->render_hidden_fields(); + + /** + * Hook after form form has been rendered + * + * The dynamic portion of the hook name, $this->cmb_id, is the meta_box id. + * + * The first dynamic portion of the hook name, $object_type, is the type of object + * you are working with. Usually `post` (this applies to all post-types). + * Could also be `comment`, `user` or `options-page`. + * + * @param int $object_id The ID of the current object + * @param array $cmb This CMB2 object + */ + do_action( "cmb2_after_{$object_type}_form_{$this->cmb_id}", $object_id, $this ); + + /** + * Hook after form form has been rendered + * + * @param array $cmb_id The current box ID. + * @param int $object_id The ID of the current object. + * @param string $object_type The type of object you are working with. + * Usually `post` (this applies to all post-types). + * Could also be `comment`, `user` or `options-page`. + * @param array $cmb This CMB2 object. + */ + do_action( 'cmb2_after_form', $this->cmb_id, $object_id, $object_type, $this ); + + echo "\n\n"; + + return $this; + } + + /** + * Renders a field based on the field type + * + * @since 2.2.0 + * @param array $field_args A field configuration array. + * @return mixed CMB2_Field object if successful. + */ + public function render_field( $field_args ) { + $field_args['context'] = $this->prop( 'context' ); + + if ( 'group' === $field_args['type'] ) { + + if ( ! isset( $field_args['show_names'] ) ) { + $field_args['show_names'] = $this->prop( 'show_names' ); + } + $field = $this->render_group( $field_args ); + + } elseif ( 'hidden' === $field_args['type'] && $this->get_field( $field_args )->should_show() ) { + // Save rendering for after the metabox. + $field = $this->add_hidden_field( $field_args ); + + } else { + + $field_args['show_names'] = $this->prop( 'show_names' ); + + // Render default fields. + $field = $this->get_field( $field_args )->render_field(); + } + + return $field; + } + + /** + * Render a group of fields. + * + * @param array|CMB2_Field $args Array of field arguments for a group field parent or the group parent field. + * @return CMB2_Field|null Group field object. + */ + public function render_group( $args ) { + $field_group = false; + + if ( $args instanceof CMB2_Field ) { + $field_group = 'group' === $args->type() ? $args : false; + } elseif ( isset( $args['id'], $args['fields'] ) && is_array( $args['fields'] ) ) { + $field_group = $this->get_field( $args ); + } + + if ( ! $field_group ) { + return; + } + + $field_group->render_context = 'edit'; + $field_group->peform_param_callback( 'render_row_cb' ); + + return $field_group; + } + + /** + * The default callback to render a group of fields. + * + * @since 2.2.6 + * + * @param array $field_args Array of field arguments for the group field parent. + * @param CMB2_Field $field_group The CMB2_Field group object. + * + * @return CMB2_Field|null Group field object. + */ + public function render_group_callback( $field_args, $field_group ) { + + // If field is requesting to be conditionally shown. + if ( ! $field_group || ! $field_group->should_show() ) { + return; + } + + $field_group->index = 0; + + $field_group->peform_param_callback( 'before_group' ); + + $desc = $field_group->args( 'description' ); + $label = $field_group->args( 'name' ); + $group_val = (array) $field_group->value(); + + echo '
            group_wrap_attributes( $field_group ), '>'; + + if ( $desc || $label ) { + $class = $desc ? ' cmb-group-description' : ''; + echo '
            '; + if ( $label ) { + echo '

            ', $label, '

            '; + } + if ( $desc ) { + echo '

            ', $desc, '

            '; + } + echo '
            '; + } + + if ( ! empty( $group_val ) ) { + foreach ( $group_val as $group_key => $field_id ) { + $this->render_group_row( $field_group ); + $field_group->index++; + } + } else { + $this->render_group_row( $field_group ); + } + + if ( $field_group->args( 'repeatable' ) ) { + echo '

            '; + } + + echo '
            '; + + $field_group->peform_param_callback( 'after_group' ); + + return $field_group; + } + + /** + * Get the group wrap attributes, which are passed through a filter. + * + * @since 2.2.3 + * @param CMB2_Field $field_group The group CMB2_Field object. + * @return string The attributes string. + */ + public function group_wrap_attributes( $field_group ) { + $classes = 'cmb-nested cmb-field-list cmb-repeatable-group'; + $classes .= $field_group->options( 'sortable' ) ? ' sortable' : ' non-sortable'; + $classes .= $field_group->args( 'repeatable' ) ? ' repeatable' : ' non-repeatable'; + + $group_wrap_attributes = array( + 'class' => $classes, + 'style' => 'width:100%;', + ); + + /** + * Allow for adding additional HTML attributes to a group wrapper. + * + * The attributes will be an array of key => value pairs for each attribute. + * + * @since 2.2.2 + * + * @param string $group_wrap_attributes Current attributes array. + * @param CMB2_Field $field_group The group CMB2_Field object. + */ + $group_wrap_attributes = apply_filters( 'cmb2_group_wrap_attributes', $group_wrap_attributes, $field_group ); + + $atts = array(); + foreach ( $group_wrap_attributes as $att => $att_value ) { + if ( ! CMB2_Utils::is_data_attribute( $att ) ) { + $att_value = htmlspecialchars( $att_value ); + } + + $atts[ sanitize_html_class( $att ) ] = sanitize_text_field( strip_tags( $att_value ) ); + } + + return CMB2_Utils::concat_attrs( $atts ); + } + + /** + * Render a repeatable group row + * + * @since 1.0.2 + * @param CMB2_Field $field_group CMB2_Field group field object. + * + * @return CMB2 + */ + public function render_group_row( $field_group ) { + + $field_group->peform_param_callback( 'before_group_row' ); + $closed_class = $field_group->options( 'closed' ) ? ' closed' : ''; + $confirm_deletion = $field_group->options( 'remove_confirm' ); + $confirm_deletion = ! empty( $confirm_deletion ) ? $confirm_deletion : ''; + + echo ' +
            '; + + if ( $field_group->args( 'repeatable' ) ) { + echo ''; + } + + echo ' +

            +

            ', $field_group->replace_hash( $field_group->options( 'group_title' ) ), '

            + +
            '; + // Loop and render repeatable group fields. + foreach ( array_values( $field_group->args( 'fields' ) ) as $field_args ) { + if ( 'hidden' === $field_args['type'] ) { + + // Save rendering for after the metabox. + $this->add_hidden_field( $field_args, $field_group ); + + } else { + + $field_args['show_names'] = $field_group->args( 'show_names' ); + $field_args['context'] = $field_group->args( 'context' ); + + $this->get_field( $field_args, $field_group )->render_field(); + } + } + + if ( $field_group->args( 'repeatable' ) ) { + echo ' +
            +
            + +
            +
            + '; + } + echo ' +
            +
            + '; + + $field_group->peform_param_callback( 'after_group_row' ); + + return $this; + } + + /** + * Add a hidden field to the list of hidden fields to be rendered later. + * + * @since 2.0.0 + * + * @param array $field_args Array of field arguments to be passed to CMB2_Field. + * @param CMB2_Field|null $field_group CMB2_Field group field object. + * @return CMB2_Field + */ + public function add_hidden_field( $field_args, $field_group = null ) { + if ( isset( $field_args['field_args'] ) ) { + // For back-compatibility. + $field = new CMB2_Field( $field_args ); + } else { + $field = $this->get_new_field( $field_args, $field_group ); + } + + $types = new CMB2_Types( $field ); + + if ( $field_group ) { + $types->iterator = $field_group->index; + } + + $this->hidden_fields[] = $types; + + return $field; + } + + /** + * Loop through and output hidden fields + * + * @since 2.0.0 + * + * @return CMB2 + */ + public function render_hidden_fields() { + if ( ! empty( $this->hidden_fields ) ) { + foreach ( $this->hidden_fields as $hidden ) { + $hidden->render(); + } + } + + return $this; + } + + /** + * Returns array of sanitized field values (without saving them) + * + * @since 2.0.3 + * @param array $data_to_sanitize Array of field_id => value data for sanitizing (likely $_POST data). + * @return mixed + */ + public function get_sanitized_values( array $data_to_sanitize ) { + $this->data_to_save = $data_to_sanitize; + $stored_id = $this->object_id(); + + // We do this So CMB will sanitize our data for us, but not save it. + $this->object_id( '_' ); + + // Ensure temp. data store is empty. + cmb2_options( 0 )->set(); + + // We want to get any taxonomy values back. + add_filter( "cmb2_return_taxonomy_values_{$this->cmb_id}", '__return_true' ); + + // Process/save fields. + $this->process_fields(); + + // Put things back the way they were. + remove_filter( "cmb2_return_taxonomy_values_{$this->cmb_id}", '__return_true' ); + + // Get data from temp. data store. + $sanitized_values = cmb2_options( 0 )->get_options(); + + // Empty out temp. data store again. + cmb2_options( 0 )->set(); + + // Reset the object id. + $this->object_id( $stored_id ); + + return $sanitized_values; + } + + /** + * Loops through and saves field data + * + * @since 1.0.0 + * @param int $object_id Object ID. + * @param string $object_type Type of object being saved. (e.g., post, user, or comment). + * @param array $data_to_save Array of key => value data for saving. Likely $_POST data. + * + * @return CMB2 + */ + public function save_fields( $object_id = 0, $object_type = '', $data_to_save = array() ) { + + // Fall-back to $_POST data. + $this->data_to_save = ! empty( $data_to_save ) ? $data_to_save : $_POST; + $object_id = $this->object_id( $object_id ); + $object_type = $this->object_type( $object_type ); + + $this->process_fields(); + + // If options page, save the updated options. + if ( 'options-page' === $object_type ) { + cmb2_options( $object_id )->set(); + } + + return $this->after_save(); + } + + /** + * Process and save form fields + * + * @since 2.0.0 + * + * @return CMB2 + */ + public function process_fields() { + + $this->pre_process(); + + // Remove the show_on properties so saving works. + $this->prop( 'show_on', array() ); + + // save field ids of those that are updated. + $this->updated = array(); + + foreach ( $this->prop( 'fields' ) as $field_args ) { + $this->process_field( $field_args ); + } + + return $this; + } + + /** + * Process and save a field + * + * @since 2.0.0 + * @param array $field_args Array of field arguments. + * + * @return CMB2 + */ + public function process_field( $field_args ) { + + switch ( $field_args['type'] ) { + + case 'group': + if ( $this->save_group( $field_args ) ) { + $this->updated[] = $field_args['id']; + } + + break; + + case 'title': + // Don't process title fields. + break; + + default: + $field = $this->get_new_field( $field_args ); + + if ( $field->save_field_from_data( $this->data_to_save ) ) { + $this->updated[] = $field->id(); + } + + break; + } + + return $this; + } + + /** + * Fires the "cmb2_{$object_type}_process_fields_{$cmb_id}" action hook. + * + * @since 2.2.2 + * + * @return CMB2 + */ + public function pre_process() { + $object_type = $this->object_type(); + + /** + * Fires before fields have been processed/saved. + * + * The dynamic portion of the hook name, $object_type, refers to the + * metabox/form's object type + * Usually `post` (this applies to all post-types). + * Could also be `comment`, `user` or `options-page`. + * + * The dynamic portion of the hook name, $this->cmb_id, is the meta_box id. + * + * @param array $cmb This CMB2 object + * @param int $object_id The ID of the current object + */ + do_action( "cmb2_{$object_type}_process_fields_{$this->cmb_id}", $this, $this->object_id() ); + + return $this; + } + + /** + * Fires the "cmb2_save_{$object_type}_fields" and + * "cmb2_save_{$object_type}_fields_{$cmb_id}" action hooks. + * + * @since 2.x.x + * + * @return CMB2 + */ + public function after_save() { + $object_type = $this->object_type(); + $object_id = $this->object_id(); + + /** + * Fires after all fields have been saved. + * + * The dynamic portion of the hook name, $object_type, refers to the metabox/form's object type + * Usually `post` (this applies to all post-types). + * Could also be `comment`, `user` or `options-page`. + * + * @param int $object_id The ID of the current object + * @param array $cmb_id The current box ID + * @param string $updated Array of field ids that were updated. + * Will only include field ids that had values change. + * @param array $cmb This CMB2 object + */ + do_action( "cmb2_save_{$object_type}_fields", $object_id, $this->cmb_id, $this->updated, $this ); + + /** + * Fires after all fields have been saved. + * + * The dynamic portion of the hook name, $this->cmb_id, is the meta_box id. + * + * The dynamic portion of the hook name, $object_type, refers to the metabox/form's object type + * Usually `post` (this applies to all post-types). + * Could also be `comment`, `user` or `options-page`. + * + * @param int $object_id The ID of the current object + * @param string $updated Array of field ids that were updated. + * Will only include field ids that had values change. + * @param array $cmb This CMB2 object + */ + do_action( "cmb2_save_{$object_type}_fields_{$this->cmb_id}", $object_id, $this->updated, $this ); + + return $this; + } + + /** + * Save a repeatable group + * + * @since 1.x.x + * @param array $args Field arguments array. + * @return mixed Return of CMB2_Field::update_data(). + */ + public function save_group( $args ) { + if ( ! isset( $args['id'], $args['fields'] ) || ! is_array( $args['fields'] ) ) { + return; + } + + return $this->save_group_field( $this->get_new_field( $args ) ); + } + + /** + * Save a repeatable group + * + * @since 1.x.x + * @param CMB2_Field $field_group CMB2_Field group field object. + * @return mixed Return of CMB2_Field::update_data(). + */ + public function save_group_field( $field_group ) { + $base_id = $field_group->id(); + + if ( ! isset( $this->data_to_save[ $base_id ] ) ) { + return; + } + + $old = $field_group->get_data(); + // Check if group field has sanitization_cb. + $group_vals = $field_group->sanitization_cb( $this->data_to_save[ $base_id ] ); + $saved = array(); + + $field_group->index = 0; + $field_group->data_to_save = $this->data_to_save; + + foreach ( array_values( $field_group->fields() ) as $field_args ) { + if ( 'title' === $field_args['type'] ) { + // Don't process title fields. + continue; + } + + $field = $this->get_new_field( $field_args, $field_group ); + $sub_id = $field->id( true ); + if ( empty( $saved[ $field_group->index ] ) ) { + $saved[ $field_group->index ] = array(); + } + + foreach ( (array) $group_vals as $field_group->index => $post_vals ) { + + // Get value. + $new_val = isset( $group_vals[ $field_group->index ][ $sub_id ] ) + ? $group_vals[ $field_group->index ][ $sub_id ] + : false; + + // Sanitize. + $new_val = $field->sanitization_cb( $new_val ); + + if ( is_array( $new_val ) && $field->args( 'has_supporting_data' ) ) { + if ( $field->args( 'repeatable' ) ) { + $_new_val = array(); + foreach ( $new_val as $group_index => $grouped_data ) { + // Add the supporting data to the $saved array stack. + $saved[ $field_group->index ][ $grouped_data['supporting_field_id'] ][] = $grouped_data['supporting_field_value']; + // Reset var to the actual value. + $_new_val[ $group_index ] = $grouped_data['value']; + } + $new_val = $_new_val; + } else { + // Add the supporting data to the $saved array stack. + $saved[ $field_group->index ][ $new_val['supporting_field_id'] ] = $new_val['supporting_field_value']; + // Reset var to the actual value. + $new_val = $new_val['value']; + } + } + + // Get old value. + $old_val = is_array( $old ) && isset( $old[ $field_group->index ][ $sub_id ] ) + ? $old[ $field_group->index ][ $sub_id ] + : false; + + $is_updated = ( ! CMB2_Utils::isempty( $new_val ) && $new_val !== $old_val ); + $is_removed = ( CMB2_Utils::isempty( $new_val ) && ! CMB2_Utils::isempty( $old_val ) ); + + // Compare values and add to `$updated` array. + if ( $is_updated || $is_removed ) { + $this->updated[] = $base_id . '::' . $field_group->index . '::' . $sub_id; + } + + // Add to `$saved` array. + $saved[ $field_group->index ][ $sub_id ] = $new_val; + + }// End foreach. + + $saved[ $field_group->index ] = CMB2_Utils::filter_empty( $saved[ $field_group->index ] ); + }// End foreach. + + $saved = CMB2_Utils::filter_empty( $saved ); + + return $field_group->update_data( $saved, true ); + } + + /** + * Get object id from global space if no id is provided + * + * @since 1.0.0 + * @param integer|string $object_id Object ID. + * @return integer|string $object_id Object ID. + */ + public function object_id( $object_id = 0 ) { + global $pagenow; + + if ( $object_id ) { + $this->object_id = $object_id; + return $this->object_id; + } + + if ( $this->object_id ) { + return $this->object_id; + } + + // Try to get our object ID from the global space. + switch ( $this->object_type() ) { + case 'user': + $object_id = isset( $_REQUEST['user_id'] ) ? wp_unslash( $_REQUEST['user_id'] ) : $object_id; + $object_id = ! $object_id && 'user-new.php' !== $pagenow && isset( $GLOBALS['user_ID'] ) ? $GLOBALS['user_ID'] : $object_id; + break; + + case 'comment': + $object_id = isset( $_REQUEST['c'] ) ? wp_unslash( $_REQUEST['c'] ) : $object_id; + $object_id = ! $object_id && isset( $GLOBALS['comments']->comment_ID ) ? $GLOBALS['comments']->comment_ID : $object_id; + break; + + case 'term': + $object_id = isset( $_REQUEST['tag_ID'] ) ? wp_unslash( $_REQUEST['tag_ID'] ) : $object_id; + break; + + case 'options-page': + $key = $this->doing_options_page(); + if ( ! empty( $key ) ) { + $object_id = $key; + } + break; + + default: + $object_id = isset( $GLOBALS['post']->ID ) ? $GLOBALS['post']->ID : $object_id; + $object_id = isset( $_REQUEST['post'] ) ? wp_unslash( $_REQUEST['post'] ) : $object_id; + break; + } + + // reset to id or 0. + $this->object_id = $object_id ? $object_id : 0; + + return $this->object_id; + } + + /** + * Sets the $object_type based on metabox settings + * + * @since 1.0.0 + * @return string Object type. + */ + public function mb_object_type() { + if ( null !== $this->mb_object_type ) { + return $this->mb_object_type; + } + + if ( $this->is_options_page_mb() ) { + $this->mb_object_type = 'options-page'; + return $this->mb_object_type; + } + + $registered_types = $this->box_types(); + + $type = ''; + + // if it's an array of one, extract it. + if ( 1 === count( $registered_types ) ) { + $last = end( $registered_types ); + if ( is_string( $last ) ) { + $type = $last; + } + } elseif ( ( $curr_type = $this->current_object_type() ) && in_array( $curr_type, $registered_types, true ) ) { + $type = $curr_type; + } + + // Get our object type. + switch ( $type ) { + + case 'user': + case 'comment': + case 'term': + $this->mb_object_type = $type; + break; + + default: + $this->mb_object_type = 'post'; + break; + } + + return $this->mb_object_type; + } + + /** + * Gets the box 'object_types' array based on box settings. + * + * @since 2.2.3 + * @param array $fallback Fallback value. + * + * @return array Object types. + */ + public function box_types( $fallback = array() ) { + return CMB2_Utils::ensure_array( $this->prop( 'object_types' ), $fallback ); + } + + /** + * Initates the object types and option key for an options page metabox. + * + * @since 2.2.5 + * + * @return void + */ + public function init_options_mb() { + $keys = $this->options_page_keys(); + $types = $this->box_types(); + + if ( empty( $keys ) ) { + $keys = ''; + $types = $this->deinit_options_mb( $types ); + } else { + + // Make sure 'options-page' is one of the object types. + $types[] = 'options-page'; + } + + // Set/Reset the option_key property. + $this->set_prop( 'option_key', $keys ); + + // Reset the object types. + $this->set_prop( 'object_types', array_unique( $types ) ); + } + + /** + * If object-page initiation failed, remove traces options page setup. + * + * @since 2.2.5 + * + * @param array $types Array of types. + * @return array + */ + protected function deinit_options_mb( $types ) { + if ( isset( $this->meta_box['show_on']['key'] ) && 'options-page' === $this->meta_box['show_on']['key'] ) { + unset( $this->meta_box['show_on']['key'] ); + } + + if ( array_key_exists( 'options-page', $this->meta_box['show_on'] ) ) { + unset( $this->meta_box['show_on']['options-page'] ); + } + + $index = array_search( 'options-page', $types ); + + if ( false !== $index ) { + unset( $types[ $index ] ); + } + + return $types; + } + + /** + * Determines if metabox is for an options page + * + * @since 1.0.1 + * @return boolean True/False. + */ + public function is_options_page_mb() { + return ( + // 'show_on' values checked for back-compatibility. + $this->is_old_school_options_page_mb() + || in_array( 'options-page', $this->box_types() ) + ); + } + + /** + * Determines if metabox uses old-schoold options page config. + * + * @since 2.2.5 + * @return boolean True/False. + */ + public function is_old_school_options_page_mb() { + return ( + // 'show_on' values checked for back-compatibility. + isset( $this->meta_box['show_on']['key'] ) && 'options-page' === $this->meta_box['show_on']['key'] + || array_key_exists( 'options-page', $this->meta_box['show_on'] ) + ); + } + + /** + * Determine if we are on an options page (or saving the options page). + * + * @since 2.2.5 + * + * @return bool + */ + public function doing_options_page() { + $found_key = false; + $keys = $this->options_page_keys(); + + if ( empty( $keys ) ) { + return $found_key; + } + + if ( ! empty( $_GET['page'] ) && in_array( $_GET['page'], $keys ) ) { + $found_key = sanitize_text_field( $_GET['page'] ); + } + + if ( ! empty( $_POST['action'] ) && in_array( $_POST['action'], $keys ) ) { + $found_key = sanitize_text_field( $_POST['action'] ); + } + + return $found_key ? $found_key : false; + } + + /** + * Get the options page key. + * + * @since 2.2.5 + * @return string|array + */ + public function options_page_keys() { + $key = ''; + if ( ! $this->is_options_page_mb() ) { + return $key; + } + + $values = null; + if ( ! empty( $this->meta_box['show_on']['value'] ) ) { + $values = $this->meta_box['show_on']['value']; + } elseif ( ! empty( $this->meta_box['show_on']['options-page'] ) ) { + $values = $this->meta_box['show_on']['options-page']; + } elseif ( $this->prop( 'option_key' ) ) { + $values = $this->prop( 'option_key' ); + } + + if ( $values ) { + $key = $values; + } + + if ( ! is_array( $key ) ) { + $key = array( $key ); + } + + return $key; + } + + /** + * Returns the object type + * + * @since 1.0.0 + * @param string $object_type Type of object being saved. (e.g., post, user, or comment). Optional. + * @return string Object type. + */ + public function object_type( $object_type = '' ) { + if ( $object_type ) { + $this->object_type = $object_type; + return $this->object_type; + } + + if ( $this->object_type ) { + return $this->object_type; + } + + $this->object_type = $this->current_object_type(); + + return $this->object_type; + } + + /** + * Get the object type for the current page, based on the $pagenow global. + * + * @since 2.2.2 + * @return string Page object type name. + */ + public function current_object_type() { + global $pagenow; + $type = 'post'; + + if ( in_array( $pagenow, array( 'user-edit.php', 'profile.php', 'user-new.php' ), true ) ) { + $type = 'user'; + } + + if ( in_array( $pagenow, array( 'edit-comments.php', 'comment.php' ), true ) ) { + $type = 'comment'; + } + + if ( in_array( $pagenow, array( 'edit-tags.php', 'term.php' ), true ) ) { + $type = 'term'; + } + + if ( defined( 'DOING_AJAX' ) && isset( $_POST['action'] ) && 'add-tag' === $_POST['action'] ) { + $type = 'term'; + } + + if ( + in_array( $pagenow, array( 'admin.php', 'admin-post.php' ), true ) + && $this->doing_options_page() + ) { + $type = 'options-page'; + } + + return $type; + } + + /** + * Set metabox property. + * + * @since 2.2.2 + * @param string $property Metabox config property to retrieve. + * @param mixed $value Value to set if no value found. + * @return mixed Metabox config property value or false. + */ + public function set_prop( $property, $value ) { + $this->meta_box[ $property ] = $value; + + return $this->prop( $property ); + } + + /** + * Get metabox property and optionally set a fallback + * + * @since 2.0.0 + * @param string $property Metabox config property to retrieve. + * @param mixed $fallback Fallback value to set if no value found. + * @return mixed Metabox config property value or false. + */ + public function prop( $property, $fallback = null ) { + if ( array_key_exists( $property, $this->meta_box ) ) { + return $this->meta_box[ $property ]; + } elseif ( $fallback ) { + return $this->meta_box[ $property ] = $fallback; + } + } + + /** + * Get a field object + * + * @since 2.0.3 + * @param string|array|CMB2_Field $field Metabox field id or field config array or CMB2_Field object. + * @param CMB2_Field|null $field_group (optional) CMB2_Field object (group parent). + * @param bool $reset_cached (optional) Reset the internal cache for this field object. + * Use sparingly. + * + * @return CMB2_Field|false CMB2_Field object (or false). + */ + public function get_field( $field, $field_group = null, $reset_cached = false ) { + if ( $field instanceof CMB2_Field ) { + return $field; + } + + $field_id = is_string( $field ) ? $field : $field['id']; + + $parent_field_id = ! empty( $field_group ) ? $field_group->id() : ''; + $ids = $this->get_field_ids( $field_id, $parent_field_id ); + + if ( ! $ids ) { + return false; + } + + list( $field_id, $sub_field_id ) = $ids; + + $index = implode( '', $ids ) . ( $field_group ? $field_group->index : '' ); + + if ( array_key_exists( $index, $this->fields ) && ! $reset_cached ) { + return $this->fields[ $index ]; + } + + $this->fields[ $index ] = new CMB2_Field( $this->get_field_args( $field_id, $field, $sub_field_id, $field_group ) ); + + return $this->fields[ $index ]; + } + + /** + * Handles determining which type of arguments to pass to CMB2_Field + * + * @since 2.0.7 + * @param mixed $field_id Field (or group field) ID. + * @param mixed $field_args Array of field arguments. + * @param mixed $sub_field_id Sub field ID (if field_group exists). + * @param CMB2_Field|null $field_group If a sub-field, will be the parent group CMB2_Field object. + * @return array Array of CMB2_Field arguments. + */ + public function get_field_args( $field_id, $field_args, $sub_field_id, $field_group ) { + + // Check if group is passed and if fields were added in the old-school fields array. + if ( $field_group && ( $sub_field_id || 0 === $sub_field_id ) ) { + + // Update the fields array w/ any modified properties inherited from the group field. + $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id ] = $field_args; + + return $this->get_default_args( $field_args, $field_group ); + } + + if ( is_array( $field_args ) ) { + $this->meta_box['fields'][ $field_id ] = array_merge( $field_args, $this->meta_box['fields'][ $field_id ] ); + } + + return $this->get_default_args( $this->meta_box['fields'][ $field_id ] ); + } + + /** + * Get default field arguments specific to this CMB2 object. + * + * @since 2.2.0 + * @param array $field_args Metabox field config array. + * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent). + * @return array Array of field arguments. + */ + protected function get_default_args( $field_args, $field_group = null ) { + if ( $field_group ) { + $args = array( + 'field_args' => $field_args, + 'group_field' => $field_group, + ); + } else { + $args = array( + 'field_args' => $field_args, + 'object_type' => $this->object_type(), + 'object_id' => $this->object_id(), + 'cmb_id' => $this->cmb_id, + ); + } + + return $args; + } + + /** + * When fields are added in the old-school way, intitate them as they should be + * + * @since 2.1.0 + * @param array $fields Array of fields to add. + * @param mixed $parent_field_id Parent field id or null. + * + * @return CMB2 + */ + protected function add_fields( $fields, $parent_field_id = null ) { + foreach ( $fields as $field ) { + + $sub_fields = false; + if ( array_key_exists( 'fields', $field ) ) { + $sub_fields = $field['fields']; + unset( $field['fields'] ); + } + + $field_id = $parent_field_id + ? $this->add_group_field( $parent_field_id, $field ) + : $this->add_field( $field ); + + if ( $sub_fields ) { + $this->add_fields( $sub_fields, $field_id ); + } + } + + return $this; + } + + /** + * Add a field to the metabox + * + * @since 2.0.0 + * @param array $field Metabox field config array. + * @param int $position (optional) Position of metabox. 1 for first, etc. + * @return string|false Field id or false. + */ + public function add_field( array $field, $position = 0 ) { + if ( ! array_key_exists( 'id', $field ) ) { + return false; + } + + // Perform some field-type-specific initiation actions. + switch ( $field['type'] ) { + case 'file': + case 'file_list': + // Initiate attachment JS hooks. + add_filter( 'wp_prepare_attachment_for_js', array( 'CMB2_Type_File_Base', 'prepare_image_sizes_for_js' ), 10, 3 ); + break; + + case 'oembed': + // Initiate oembed Ajax hooks. + cmb2_ajax(); + break; + + case 'group': + if ( empty( $field['render_row_cb'] ) ) { + $field['render_row_cb'] = array( $this, 'render_group_callback' ); + } + break; + case 'colorpicker': + // https://github.com/JayWood/CMB2_RGBa_Picker + // Dequeue the rgba_colorpicker custom field script if it is used, + // since we now enqueue our own more current version. + add_action( 'admin_enqueue_scripts', array( 'CMB2_Type_Colorpicker', 'dequeue_rgba_colorpicker_script' ), 99 ); + break; + } + + if ( isset( $field['column'] ) && false !== $field['column'] ) { + $field = $this->define_field_column( $field ); + } + + if ( isset( $field['taxonomy'] ) && ! empty( $field['remove_default'] ) ) { + $this->tax_metaboxes_to_remove[ $field['taxonomy'] ] = $field['taxonomy']; + } + + $this->_add_field_to_array( + $field, + $this->meta_box['fields'], + $position + ); + + return $field['id']; + } + + /** + * Defines a field's column if requesting to be show in admin columns. + * + * @since 2.2.3 + * @param array $field Metabox field config array. + * @return array Modified metabox field config array. + */ + protected function define_field_column( array $field ) { + $this->has_columns = true; + + $column = is_array( $field['column'] ) ? $field['column'] : array(); + + $field['column'] = wp_parse_args( $column, array( + 'name' => isset( $field['name'] ) ? $field['name'] : '', + 'position' => false, + ) ); + + return $field; + } + + /** + * Add a field to a group + * + * @since 2.0.0 + * @param string $parent_field_id The field id of the group field to add the field. + * @param array $field Metabox field config array. + * @param int $position (optional) Position of metabox. 1 for first, etc. + * @return mixed Array of parent/field ids or false. + */ + public function add_group_field( $parent_field_id, array $field, $position = 0 ) { + if ( ! array_key_exists( $parent_field_id, $this->meta_box['fields'] ) ) { + return false; + } + + $parent_field = $this->meta_box['fields'][ $parent_field_id ]; + + if ( 'group' !== $parent_field['type'] ) { + return false; + } + + if ( ! isset( $parent_field['fields'] ) ) { + $this->meta_box['fields'][ $parent_field_id ]['fields'] = array(); + } + + $this->_add_field_to_array( + $field, + $this->meta_box['fields'][ $parent_field_id ]['fields'], + $position + ); + + return array( $parent_field_id, $field['id'] ); + } + + /** + * Add a field array to a fields array in desired position + * + * @since 2.0.2 + * @param array $field Metabox field config array. + * @param array $fields Array (passed by reference) to append the field (array) to. + * @param integer $position Optionally specify a position in the array to be inserted. + */ + protected function _add_field_to_array( $field, &$fields, $position = 0 ) { + if ( $position ) { + CMB2_Utils::array_insert( $fields, array( $field['id'] => $field ), $position ); + } else { + $fields[ $field['id'] ] = $field; + } + } + + /** + * Remove a field from the metabox + * + * @since 2.0.0 + * @param string $field_id The field id of the field to remove. + * @param string $parent_field_id (optional) The field id of the group field to remove field from. + * @return bool True if field was removed. + */ + public function remove_field( $field_id, $parent_field_id = '' ) { + $ids = $this->get_field_ids( $field_id, $parent_field_id ); + + if ( ! $ids ) { + return false; + } + + list( $field_id, $sub_field_id ) = $ids; + + unset( $this->fields[ implode( '', $ids ) ] ); + + if ( ! $sub_field_id ) { + unset( $this->meta_box['fields'][ $field_id ] ); + return true; + } + + if ( isset( $this->fields[ $field_id ]->args['fields'][ $sub_field_id ] ) ) { + unset( $this->fields[ $field_id ]->args['fields'][ $sub_field_id ] ); + } + if ( isset( $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id ] ) ) { + unset( $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id ] ); + } + + return true; + } + + /** + * Update or add a property to a field + * + * @since 2.0.0 + * @param string $field_id Field id. + * @param string $property Field property to set/update. + * @param mixed $value Value to set the field property. + * @param string $parent_field_id (optional) The field id of the group field to remove field from. + * @return mixed Field id. Strict compare to false, as success can return a falsey value (like 0). + */ + public function update_field_property( $field_id, $property, $value, $parent_field_id = '' ) { + $ids = $this->get_field_ids( $field_id, $parent_field_id ); + + if ( ! $ids ) { + return false; + } + + list( $field_id, $sub_field_id ) = $ids; + + if ( ! $sub_field_id ) { + $this->meta_box['fields'][ $field_id ][ $property ] = $value; + return $field_id; + } + + $this->meta_box['fields'][ $field_id ]['fields'][ $sub_field_id ][ $property ] = $value; + return $field_id; + } + + /** + * Check if field ids match a field and return the index/field id + * + * @since 2.0.2 + * @param string $field_id Field id. + * @param string $parent_field_id (optional) Parent field id. + * @return mixed Array of field/parent ids, or false. + */ + public function get_field_ids( $field_id, $parent_field_id = '' ) { + $sub_field_id = $parent_field_id ? $field_id : ''; + $field_id = $parent_field_id ? $parent_field_id : $field_id; + $fields =& $this->meta_box['fields']; + + if ( ! array_key_exists( $field_id, $fields ) ) { + $field_id = $this->search_old_school_array( $field_id, $fields ); + } + + if ( false === $field_id ) { + return false; + } + + if ( ! $sub_field_id ) { + return array( $field_id, $sub_field_id ); + } + + if ( 'group' !== $fields[ $field_id ]['type'] ) { + return false; + } + + if ( ! array_key_exists( $sub_field_id, $fields[ $field_id ]['fields'] ) ) { + $sub_field_id = $this->search_old_school_array( $sub_field_id, $fields[ $field_id ]['fields'] ); + } + + return false === $sub_field_id ? false : array( $field_id, $sub_field_id ); + } + + /** + * When using the old array filter, it is unlikely field array indexes will be the field id. + * + * @since 2.0.2 + * @param string $field_id The field id. + * @param array $fields Array of fields to search. + * @return mixed Field index or false. + */ + public function search_old_school_array( $field_id, $fields ) { + $ids = wp_list_pluck( $fields, 'id' ); + $index = array_search( $field_id, $ids ); + return false !== $index ? $index : false; + } + + /** + * Handles metabox property callbacks, and passes this $cmb object as property. + * + * @since 2.2.3 + * @param callable $cb The callback method/function/closure. + * @param mixed $additional_params Any additoinal parameters which should be passed to the callback. + * @return mixed Return of the callback function. + */ + public function do_callback( $cb, $additional_params = null ) { + return call_user_func( $cb, $this, $additional_params ); + } + + /** + * Generate a unique nonce field for each registered meta_box + * + * @since 2.0.0 + * @return void + */ + public function nonce_field() { + wp_nonce_field( $this->nonce(), $this->nonce(), false, true ); + } + + /** + * Generate a unique nonce for each registered meta_box + * + * @since 2.0.0 + * @return string unique nonce string. + */ + public function nonce() { + if ( ! $this->generated_nonce ) { + $this->generated_nonce = sanitize_html_class( 'nonce_' . basename( __FILE__ ) . $this->cmb_id ); + } + + return $this->generated_nonce; + } + + /** + * Checks if field-saving updated any fields. + * + * @since 2.2.5 + * + * @return bool + */ + public function was_updated() { + return ! empty( $this->updated ); + } + + /** + * Whether this box is an "alternate context" box. This means the box has a 'context' property defined as: + * 'form_top', 'before_permalink', 'after_title', or 'after_editor'. + * + * @since 2.2.4 + * @return bool + */ + public function is_alternate_context_box() { + return $this->prop( 'context' ) && in_array( $this->prop( 'context' ), array( 'form_top', 'before_permalink', 'after_title', 'after_editor' ), true ); + } + + /** + * Magic getter for our object. + * + * @param string $property Object property. + * @throws Exception Throws an exception if the field is invalid. + * @return mixed + */ + public function __get( $property ) { + switch ( $property ) { + case 'updated': + case 'has_columns': + case 'tax_metaboxes_to_remove': + return $this->{$property}; + default: + return parent::__get( $property ); + } + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Ajax.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Ajax.php new file mode 100755 index 00000000..17c3f2cb --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Ajax.php @@ -0,0 +1,323 @@ +' . esc_html__( 'Please Try Again', 'cmb2' ) . '

            ' ); + } + + // Set width of embed. + $embed_width = isset( $_REQUEST['oembed_width'] ) && intval( $_REQUEST['oembed_width'] ) < 640 ? intval( $_REQUEST['oembed_width'] ) : '640'; + + // Set url. + $oembed_url = esc_url( $oembed_string ); + + // Set args. + $embed_args = array( + 'width' => $embed_width, + ); + + $this->ajax_update = true; + + // Get embed code (or fallback link). + $html = $this->get_oembed( array( + 'url' => $oembed_url, + 'object_id' => $_REQUEST['object_id'], + 'object_type' => isset( $_REQUEST['object_type'] ) ? sanitize_text_field( $_REQUEST['object_type'] ) : 'post', + 'oembed_args' => $embed_args, + 'field_id' => $_REQUEST['field_id'], + ) ); + + wp_send_json_success( $html ); + } + + /** + * Retrieves oEmbed from url/object ID + * + * @since 0.9.5 + * @param array $args Arguments for method. + * @return mixed HTML markup with embed or fallback. + */ + public function get_oembed_no_edit( $args ) { + global $wp_embed; + + $oembed_url = esc_url( $args['url'] ); + + // Sanitize object_id. + $this->object_id = is_numeric( $args['object_id'] ) ? absint( $args['object_id'] ) : sanitize_text_field( $args['object_id'] ); + + $args = wp_parse_args( $args, array( + 'object_type' => 'post', + 'oembed_args' => array(), + 'field_id' => false, + 'wp_error' => false, + ) ); + + $this->embed_args =& $args; + + /* + * Set the post_ID so oEmbed won't fail + * wp-includes/class-wp-embed.php, WP_Embed::shortcode() + */ + $wp_embed->post_ID = $this->object_id; + + // Special scenario if NOT a post object. + if ( isset( $args['object_type'] ) && 'post' != $args['object_type'] ) { + + if ( 'options-page' == $args['object_type'] ) { + + // Bogus id to pass some numeric checks. Issue with a VERY large WP install? + $wp_embed->post_ID = 1987645321; + } + + // Ok, we need to hijack the oembed cache system. + $this->hijack = true; + $this->object_type = $args['object_type']; + + // Gets ombed cache from our object's meta (vs postmeta). + add_filter( 'get_post_metadata', array( $this, 'hijack_oembed_cache_get' ), 10, 3 ); + + // Sets ombed cache in our object's meta (vs postmeta). + add_filter( 'update_post_metadata', array( $this, 'hijack_oembed_cache_set' ), 10, 4 ); + + } + + $embed_args = ''; + + foreach ( $args['oembed_args'] as $key => $val ) { + $embed_args .= " $key=\"$val\""; + } + + // Ping WordPress for an embed. + $embed = $wp_embed->run_shortcode( '[embed' . $embed_args . ']' . $oembed_url . '[/embed]' ); + + // Fallback that WordPress creates when no oEmbed was found. + $fallback = $wp_embed->maybe_make_link( $oembed_url ); + + return compact( 'embed', 'fallback', 'args' ); + } + + /** + * Retrieves oEmbed from url/object ID + * + * @since 0.9.5 + * @param array $args Arguments for method. + * @return string HTML markup with embed or fallback. + */ + public function get_oembed( $args ) { + $oembed = $this->get_oembed_no_edit( $args ); + + // Send back our embed. + if ( $oembed['embed'] && $oembed['embed'] != $oembed['fallback'] ) { + return ''; + } + + // Otherwise, send back error info that no oEmbeds were found. + return sprintf( + '

            %s

            ', + sprintf( + /* translators: 1: results for. 2: link to codex.wordpress.org/Embeds */ + esc_html__( 'No oEmbed Results Found for %1$s. View more info at %2$s.', 'cmb2' ), + $oembed['fallback'], + 'codex.wordpress.org/Embeds' + ) + ); + } + + /** + * Hijacks retrieving of cached oEmbed. + * Returns cached data from relevant object metadata (vs postmeta) + * + * @since 0.9.5 + * @param boolean $check Whether to retrieve postmeta or override. + * @param int $object_id Object ID. + * @param string $meta_key Object metakey. + * @return mixed Object's oEmbed cached data. + */ + public function hijack_oembed_cache_get( $check, $object_id, $meta_key ) { + if ( ! $this->hijack || ( $this->object_id != $object_id && 1987645321 !== $object_id ) ) { + return $check; + } + + if ( $this->ajax_update ) { + return false; + } + + return $this->cache_action( $meta_key ); + } + + /** + * Hijacks saving of cached oEmbed. + * Saves cached data to relevant object metadata (vs postmeta) + * + * @since 0.9.5 + * @param boolean $check Whether to continue setting postmeta. + * @param int $object_id Object ID to get postmeta from. + * @param string $meta_key Postmeta's key. + * @param mixed $meta_value Value of the postmeta to be saved. + * @return boolean Whether to continue setting. + */ + public function hijack_oembed_cache_set( $check, $object_id, $meta_key, $meta_value ) { + + if ( + ! $this->hijack + || ( $this->object_id != $object_id && 1987645321 !== $object_id ) + // Only want to hijack oembed meta values. + || 0 !== strpos( $meta_key, '_oembed_' ) + ) { + return $check; + } + + $this->cache_action( $meta_key, $meta_value ); + + // Anything other than `null` to cancel saving to postmeta. + return true; + } + + /** + * Gets/updates the cached oEmbed value from/to relevant object metadata (vs postmeta). + * + * @since 1.3.0 + * + * @param string $meta_key Postmeta's key. + * @return mixed + */ + protected function cache_action( $meta_key ) { + $func_args = func_get_args(); + $action = isset( $func_args[1] ) ? 'update' : 'get'; + + if ( 'options-page' === $this->object_type ) { + + $args = array( $meta_key ); + + if ( 'update' === $action ) { + $args[] = $func_args[1]; + $args[] = true; + } + + // Cache the result to our options. + $status = call_user_func_array( array( cmb2_options( $this->object_id ), $action ), $args ); + } else { + + $args = array( $this->object_type, $this->object_id, $meta_key ); + $args[] = 'update' === $action ? $func_args[1] : true; + + // Cache the result to our metadata. + $status = call_user_func_array( $action . '_metadata', $args ); + } + + return $status; + } + + /** + * Hooks in when options-page data is saved to clean stale + * oembed cache data from the option value. + * + * @since 2.2.0 + * @param string $option_key The options-page option key. + * @return void + */ + public static function clean_stale_options_page_oembeds( $option_key ) { + $options = cmb2_options( $option_key )->get_options(); + $modified = false; + if ( is_array( $options ) ) { + + $ttl = apply_filters( 'oembed_ttl', DAY_IN_SECONDS, '', array(), 0 ); + $now = time(); + + foreach ( $options as $key => $value ) { + // Check for cached oembed data. + if ( 0 === strpos( $key, '_oembed_time_' ) ) { + $cached_recently = ( $now - $value ) < $ttl; + + if ( ! $cached_recently ) { + $modified = true; + // Remove the the cached ttl expiration, and the cached oembed value. + unset( $options[ $key ] ); + unset( $options[ str_replace( '_oembed_time_', '_oembed_', $key ) ] ); + } + } // End if. + // Remove the cached unknown values. + elseif ( '{{unknown}}' === $value ) { + $modified = true; + unset( $options[ $key ] ); + } + } + } + + // Update the option and remove stale cache data. + if ( $modified ) { + $updated = cmb2_options( $option_key )->set( $options ); + } + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Base.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Base.php new file mode 100755 index 00000000..e84ce4b0 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Base.php @@ -0,0 +1,533 @@ + value data for saving. Likely $_POST data. + * + * @var array + * @since 2.2.3 + */ + public $data_to_save = array(); + + /** + * Array of field param callback results + * + * @var array + * @since 2.0.0 + */ + protected $callback_results = array(); + + /** + * The deprecated_param method deprecated param message signature. + */ + const DEPRECATED_PARAM = 1; + + /** + * The deprecated_param method deprecated callback param message signature. + */ + const DEPRECATED_CB_PARAM = 2; + + /** + * Get started + * + * @since 2.2.3 + * @param array $args Object properties array. + */ + public function __construct( $args = array() ) { + if ( ! empty( $args ) ) { + foreach ( array( + 'cmb_id', + 'properties_name', + 'object_id', + 'object_type', + 'data_to_save', + ) as $object_prop ) { + if ( isset( $args[ $object_prop ] ) ) { + $this->{$object_prop} = $args[ $object_prop ]; + } + } + } + } + + /** + * Returns the object ID + * + * @since 2.2.3 + * @param integer $object_id Object ID. + * @return integer Object ID + */ + public function object_id( $object_id = 0 ) { + if ( $object_id ) { + $this->object_id = $object_id; + } + + return $this->object_id; + } + + /** + * Returns the object type + * + * @since 2.2.3 + * @param string $object_type Object Type. + * @return string Object type + */ + public function object_type( $object_type = '' ) { + if ( $object_type ) { + $this->object_type = $object_type; + } + + return $this->object_type; + } + + /** + * Get the object type for the current page, based on the $pagenow global. + * + * @since 2.2.2 + * @return string Page object type name. + */ + public function current_object_type() { + global $pagenow; + $type = 'post'; + + if ( in_array( $pagenow, array( 'user-edit.php', 'profile.php', 'user-new.php' ), true ) ) { + $type = 'user'; + } + + if ( in_array( $pagenow, array( 'edit-comments.php', 'comment.php' ), true ) ) { + $type = 'comment'; + } + + if ( in_array( $pagenow, array( 'edit-tags.php', 'term.php' ), true ) ) { + $type = 'term'; + } + + return $type; + } + + /** + * Set object property. + * + * @since 2.2.2 + * @param string $property Metabox config property to retrieve. + * @param mixed $value Value to set if no value found. + * @return mixed Metabox config property value or false. + */ + public function set_prop( $property, $value ) { + $this->{$this->properties_name}[ $property ] = $value; + + return $this->prop( $property ); + } + + /** + * Get object property and optionally set a fallback + * + * @since 2.0.0 + * @param string $property Metabox config property to retrieve. + * @param mixed $fallback Fallback value to set if no value found. + * @return mixed Metabox config property value or false + */ + public function prop( $property, $fallback = null ) { + if ( array_key_exists( $property, $this->{$this->properties_name} ) ) { + return $this->{$this->properties_name}[ $property ]; + } elseif ( $fallback ) { + return $this->{$this->properties_name}[ $property ] = $fallback; + } + } + + /** + * Get default field arguments specific to this CMB2 object. + * + * @since 2.2.0 + * @param array $field_args Metabox field config array. + * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent). + * @return array Array of field arguments. + */ + protected function get_default_args( $field_args, $field_group = null ) { + if ( $field_group ) { + $args = array( + 'field_args' => $field_args, + 'group_field' => $field_group, + ); + } else { + $args = array( + 'field_args' => $field_args, + 'object_type' => $this->object_type(), + 'object_id' => $this->object_id(), + 'cmb_id' => $this->cmb_id, + ); + } + + return $args; + } + + /** + * Get a new field object specific to this CMB2 object. + * + * @since 2.2.0 + * @param array $field_args Metabox field config array. + * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent). + * @return CMB2_Field CMB2_Field object + */ + protected function get_new_field( $field_args, $field_group = null ) { + return new CMB2_Field( $this->get_default_args( $field_args, $field_group ) ); + } + + /** + * Determine whether this cmb object should show, based on the 'show_on_cb' callback. + * + * @since 2.0.9 + * + * @return bool Whether this cmb should be shown. + */ + public function should_show() { + // Default to showing this cmb + $show = true; + + // Use the callback to determine showing the cmb, if it exists. + if ( is_callable( $this->prop( 'show_on_cb' ) ) ) { + $show = (bool) call_user_func( $this->prop( 'show_on_cb' ), $this ); + } + + return $show; + } + + /** + * Displays the results of the param callbacks. + * + * @since 2.0.0 + * @param string $param Field parameter. + */ + public function peform_param_callback( $param ) { + echo $this->get_param_callback_result( $param ); + } + + /** + * Store results of the param callbacks for continual access + * + * @since 2.0.0 + * @param string $param Field parameter. + * @return mixed Results of param/param callback + */ + public function get_param_callback_result( $param ) { + + // If we've already retrieved this param's value. + if ( array_key_exists( $param, $this->callback_results ) ) { + + // Send it back. + return $this->callback_results[ $param ]; + } + + // Check if parameter has registered a callback. + if ( $cb = $this->maybe_callback( $param ) ) { + + // Ok, callback is good, let's run it and store the result. + ob_start(); + $returned = $this->do_callback( $cb ); + + // Grab the result from the output buffer and store it. + $echoed = ob_get_clean(); + + // This checks if the user returned or echoed their callback. + // Defaults to using the echoed value. + $this->callback_results[ $param ] = $echoed ? $echoed : $returned; + + } else { + + // Otherwise just get whatever is there. + $this->callback_results[ $param ] = isset( $this->{$this->properties_name}[ $param ] ) ? $this->{$this->properties_name}[ $param ] : false; + } + + return $this->callback_results[ $param ]; + } + + /** + * Unset the cached results of the param callback. + * + * @since 2.2.6 + * @param string $param Field parameter. + * @return CMB2_Base + */ + public function unset_param_callback_cache( $param ) { + if ( isset( $this->callback_results[ $param ] ) ) { + unset( $this->callback_results[ $param ] ); + } + + return $this; + } + + /** + * Handles the parameter callbacks, and passes this object as parameter. + * + * @since 2.2.3 + * @param callable $cb The callback method/function/closure. + * @param mixed $additional_params Any additoinal parameters which should be passed to the callback. + * @return mixed Return of the callback function. + */ + protected function do_callback( $cb, $additional_params = null ) { + return call_user_func( $cb, $this->{$this->properties_name}, $this, $additional_params ); + } + + /** + * Checks if field has a callback value + * + * @since 1.0.1 + * @param string $cb Callback string. + * @return mixed NULL, false for NO validation, or $cb string if it exists. + */ + public function maybe_callback( $cb ) { + $args = $this->{$this->properties_name}; + if ( ! isset( $args[ $cb ] ) ) { + return null; + } + + // Check if requesting explicitly false. + $cb = false !== $args[ $cb ] && 'false' !== $args[ $cb ] ? $args[ $cb ] : false; + + // If requesting NO validation, return false. + if ( ! $cb ) { + return false; + } + + if ( is_callable( $cb ) ) { + return $cb; + } + + return null; + } + + /** + * Checks if this object has parameter corresponding to the given filter + * which is callable. If so, it registers the callback, and if not, + * converts the maybe-modified $val to a boolean for return. + * + * The registered handlers will have a parameter name which matches the filter, except: + * - The 'cmb2_api' prefix will be removed + * - A '_cb' suffix will be added (to stay inline with other '*_cb' parameters). + * + * @since 2.2.3 + * + * @param string $hook_name The hook name. + * @param bool $val The default value. + * @param string $hook_function The hook function. Default: 'add_filter'. + * + * @return null|bool Null if hook is registered, or bool for value. + */ + public function maybe_hook_parameter( $hook_name, $val = null, $hook_function = 'add_filter' ) { + + // Remove filter prefix, add param suffix. + $parameter = substr( $hook_name, strlen( 'cmb2_api_' ) ) . '_cb'; + + return self::maybe_hook( + $this->prop( $parameter, $val ), + $hook_name, + $hook_function + ); + } + + /** + * Checks if given value is callable, and registers the callback. + * If is non-callable, converts the $val to a boolean for return. + * + * @since 2.2.3 + * + * @param bool $val The default value. + * @param string $hook_name The hook name. + * @param string $hook_function The hook function. + * + * @return null|bool Null if hook is registered, or bool for value. + */ + public static function maybe_hook( $val, $hook_name, $hook_function ) { + if ( is_callable( $val ) ) { + call_user_func( $hook_function, $hook_name, $val, 10, 2 ); + return null; + } + + // Cast to bool. + return ! ! $val; + } + + /** + * Mark a param as deprecated and inform when it has been used. + * + * There is a default WordPress hook deprecated_argument_run that will be called + * that can be used to get the backtrace up to what file and function used the + * deprecated argument. + * + * The current behavior is to trigger a user error if WP_DEBUG is true. + * + * @since 2.2.3 + * + * @param string $function The function that was called. + * @param string $version The version of CMB2 that deprecated the argument used. + * @param string $message Optional. A message regarding the change, or numeric + * key to generate message from additional arguments. + * Default null. + */ + protected function deprecated_param( $function, $version, $message = null ) { + + if ( is_numeric( $message ) ) { + $args = func_get_args(); + + switch ( $message ) { + + case self::DEPRECATED_PARAM: + $message = sprintf( esc_html__( 'The "%1$s" field parameter has been deprecated in favor of the "%2$s" parameter.', 'cmb2' ), $args[3], $args[4] ); + break; + + case self::DEPRECATED_CB_PARAM: + $message = sprintf( esc_html__( 'Using the "%1$s" field parameter as a callback has been deprecated in favor of the "%2$s" parameter.', 'cmb2' ), $args[3], $args[4] ); + break; + + default: + $message = null; + break; + } + } + + /** + * Fires when a deprecated argument is called. This is a WP core action. + * + * @since 2.2.3 + * + * @param string $function The function that was called. + * @param string $message A message regarding the change. + * @param string $version The version of CMB2 that deprecated the argument used. + */ + do_action( 'deprecated_argument_run', $function, $message, $version ); + + /** + * Filters whether to trigger an error for deprecated arguments. This is a WP core filter. + * + * @since 2.2.3 + * + * @param bool $trigger Whether to trigger the error for deprecated arguments. Default true. + */ + if ( defined( 'WP_DEBUG' ) && WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) { + if ( function_exists( '__' ) ) { + if ( ! is_null( $message ) ) { + trigger_error( sprintf( esc_html__( '%1$s was called with a parameter that is deprecated since version %2$s! %3$s', 'cmb2' ), $function, $version, $message ) ); + } else { + trigger_error( sprintf( esc_html__( '%1$s was called with a parameter that is deprecated since version %2$s with no alternative available.', 'cmb2' ), $function, $version ) ); + } + } else { + if ( ! is_null( $message ) ) { + trigger_error( sprintf( '%1$s was called with a parameter that is deprecated since version %2$s! %3$s', $function, $version, $message ) ); + } else { + trigger_error( sprintf( '%1$s was called with a parameter that is deprecated since version %2$s with no alternative available.', $function, $version ) ); + } + } + } + } + + /** + * Magic getter for our object. + * + * @param string $field Requested property. + * @throws Exception Throws an exception if the field is invalid. + * @return mixed + */ + public function __get( $field ) { + switch ( $field ) { + case 'args': + case 'meta_box': + if ( $field === $this->properties_name ) { + return $this->{$this->properties_name}; + } + case 'properties': + return $this->{$this->properties_name}; + case 'cmb_id': + case 'object_id': + case 'object_type': + return $this->{$field}; + default: + throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) ); + } + } + + /** + * Allows overloading the object with methods... Whooaaa oooh it's magic, y'knoooow. + * + * @since 1.0.0 + * @throws Exception Invalid method exception. + * + * @param string $method Non-existent method. + * @param array $args All arguments passed to the method. + * @return mixed + */ + public function __call( $method, $args ) { + $object_class = strtolower( get_class( $this ) ); + + if ( ! has_filter( "{$object_class}_inherit_{$method}" ) ) { + throw new Exception( sprintf( esc_html__( 'Invalid %1$s method: %2$s', 'cmb2' ), get_class( $this ), $method ) ); + } + + array_unshift( $args, $this ); + + /** + * Allows overloading the object (CMB2 or CMB2_Field) with additional capabilities + * by registering hook callbacks. + * + * The first dynamic portion of the hook name, $object_class, refers to the object class, + * either cmb2 or cmb2_field. + * + * The second dynamic portion of the hook name, $method, is the non-existent method being + * called on the object. To avoid possible future methods encroaching on your hooks, + * use a unique method (aka, $cmb->prefix_my_method()). + * + * When registering your callback, you will need to ensure that you register the correct + * number of `$accepted_args`, accounting for this object instance being the first argument. + * + * @param array $args The arguments to be passed to the hook. + * The first argument will always be this object instance. + */ + return apply_filters_ref_array( "{$object_class}_inherit_{$method}", $args ); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Boxes.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Boxes.php new file mode 100755 index 00000000..4bee566d --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Boxes.php @@ -0,0 +1,139 @@ +cmb_id ] = $cmb_instance; + } + + /** + * Remove a CMB2 instance object from the registry. + * + * @since 1.X.X + * + * @param string $cmb_id A CMB2 instance id. + */ + public static function remove( $cmb_id ) { + if ( array_key_exists( $cmb_id, self::$cmb2_instances ) ) { + unset( self::$cmb2_instances[ $cmb_id ] ); + } + } + + /** + * Retrieve a CMB2 instance by cmb id. + * + * @since 1.X.X + * + * @param string $cmb_id A CMB2 instance id. + * + * @return CMB2|bool False or CMB2 object instance. + */ + public static function get( $cmb_id ) { + if ( empty( self::$cmb2_instances ) || empty( self::$cmb2_instances[ $cmb_id ] ) ) { + return false; + } + + return self::$cmb2_instances[ $cmb_id ]; + } + + /** + * Retrieve all CMB2 instances registered. + * + * @since 1.X.X + * @return CMB2[] Array of all registered cmb2 instances. + */ + public static function get_all() { + return self::$cmb2_instances; + } + + /** + * Retrieve all CMB2 instances that have the specified property set. + * + * @since 2.4.0 + * @param string $property Property name. + * @param mixed $compare (Optional) The value to compare. + * @return CMB2[] Array of matching cmb2 instances. + */ + public static function get_by( $property, $compare = 'nocompare' ) { + $boxes = array(); + + foreach ( self::$cmb2_instances as $cmb_id => $cmb ) { + $prop = $cmb->prop( $property ); + + if ( 'nocompare' === $compare ) { + if ( ! empty( $prop ) ) { + $boxes[ $cmb_id ] = $cmb; + } + continue; + } + + if ( $compare === $prop ) { + $boxes[ $cmb_id ] = $cmb; + } + } + + return $boxes; + } + + /** + * Retrieve all CMB2 instances as long as they do not include the ignored property. + * + * @since 2.4.0 + * @param string $property Property name. + * @param mixed $to_ignore The value to ignore. + * @return CMB2[] Array of matching cmb2 instances. + */ + public static function filter_by( $property, $to_ignore = null ) { + $boxes = array(); + + foreach ( self::$cmb2_instances as $cmb_id => $cmb ) { + + if ( $to_ignore === $cmb->prop( $property ) ) { + continue; + } + + $boxes[ $cmb_id ] = $cmb; + } + + return $boxes; + } + + /** + * Deprecated and left for back-compatibility. The original `get_by_property` + * method was misnamed and never actually used by CMB2 core. + * + * @since 2.2.3 + * + * @param string $property Property name. + * @param mixed $to_ignore The value to ignore. + * @return CMB2[] Array of matching cmb2 instances. + */ + public static function get_by_property( $property, $to_ignore = null ) { + _deprecated_function( __METHOD__, '2.4.0', 'CMB2_Boxes::filter_by()' ); + return self::filter_by( $property ); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Field.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Field.php new file mode 100755 index 00000000..273592b4 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Field.php @@ -0,0 +1,1618 @@ +group = $args['group_field']; + $this->object_id = $this->group->object_id; + $this->object_type = $this->group->object_type; + $this->cmb_id = $this->group->cmb_id; + } else { + $this->object_id = isset( $args['object_id'] ) && '_' !== $args['object_id'] ? $args['object_id'] : 0; + $this->object_type = isset( $args['object_type'] ) ? $args['object_type'] : 'post'; + + if ( isset( $args['cmb_id'] ) ) { + $this->cmb_id = $args['cmb_id']; + } + } + + $this->args = $this->_set_field_defaults( $args['field_args'] ); + + if ( $this->object_id ) { + $this->value = $this->get_data(); + } + } + + /** + * Non-existent methods fallback to checking for field arguments of the same name + * + * @since 1.1.0 + * @param string $name Method name. + * @param array $arguments Array of passed-in arguments. + * @return mixed Value of field argument + */ + public function __call( $name, $arguments ) { + if ( 'string' === $name ) { + return call_user_func_array( array( $this, 'get_string' ), $arguments ); + } + + $key = isset( $arguments[0] ) ? $arguments[0] : ''; + return $this->args( $name, $key ); + } + + /** + * Retrieves the field id + * + * @since 1.1.0 + * @param boolean $raw Whether to retrieve pre-modidifed id. + * @return string Field id + */ + public function id( $raw = false ) { + $id = $raw ? '_id' : 'id'; + return $this->args( $id ); + } + + /** + * Get a field argument + * + * @since 1.1.0 + * @param string $key Argument to check. + * @param string $_key Sub argument to check. + * @return mixed Argument value or false if non-existent + */ + public function args( $key = '', $_key = '' ) { + $arg = $this->_data( 'args', $key ); + + if ( in_array( $key, array( 'default', 'default_cb' ), true ) ) { + + $arg = $this->get_default(); + + } elseif ( $_key ) { + + $arg = isset( $arg[ $_key ] ) ? $arg[ $_key ] : false; + } + + return $arg; + } + + /** + * Retrieve a portion of a field property + * + * @since 1.1.0 + * @param string $var Field property to check. + * @param string $key Field property array key to check. + * @return mixed Queried property value or false + */ + public function _data( $var, $key = '' ) { + $vars = $this->{$var}; + if ( $key ) { + return array_key_exists( $key, $vars ) ? $vars[ $key ] : false; + } + return $vars; + } + + /** + * Get Field's value + * + * @since 1.1.0 + * @param string $key If value is an array, is used to get array key->value. + * @return mixed Field value or false if non-existent + */ + public function value( $key = '' ) { + return $this->_data( 'value', $key ); + } + + /** + * Retrieves metadata/option data + * + * @since 1.0.1 + * @param string $field_id Meta key/Option array key. + * @param array $args Override arguments. + * @return mixed Meta/Option value + */ + public function get_data( $field_id = '', $args = array() ) { + if ( $field_id ) { + $args['field_id'] = $field_id; + } elseif ( $this->group ) { + $args['field_id'] = $this->group->id(); + } + + $a = $this->data_args( $args ); + + /** + * Filter whether to override getting of meta value. + * Returning a non 'cmb2_field_no_override_val' value + * will effectively short-circuit the value retrieval. + * + * @since 2.0.0 + * + * @param mixed $value The value get_metadata() should + * return - a single metadata value, + * or an array of values. + * + * @param int $object_id Object ID. + * + * @param array $args { + * An array of arguments for retrieving data + * + * @type string $type The current object type + * @type int $id The current object ID + * @type string $field_id The ID of the field being requested + * @type bool $repeat Whether current field is repeatable + * @type bool $single Whether current field is a single database row + * } + * + * @param CMB2_Field object $field This field object + */ + $data = apply_filters( 'cmb2_override_meta_value', 'cmb2_field_no_override_val', $this->object_id, $a, $this ); + + /** + * Filter and parameters are documented for 'cmb2_override_meta_value' filter (above). + * + * The dynamic portion of the hook, $field_id, refers to the current + * field id paramater. Returning a non 'cmb2_field_no_override_val' value + * will effectively short-circuit the value retrieval. + * + * @since 2.0.0 + */ + $data = apply_filters( "cmb2_override_{$a['field_id']}_meta_value", $data, $this->object_id, $a, $this ); + + // If no override, get value normally. + if ( 'cmb2_field_no_override_val' === $data ) { + $data = 'options-page' === $a['type'] + ? cmb2_options( $a['id'] )->get( $a['field_id'] ) + : get_metadata( $a['type'], $a['id'], $a['field_id'], ( $a['single'] || $a['repeat'] ) ); + } + + if ( $this->group ) { + + $data = is_array( $data ) && isset( $data[ $this->group->index ][ $this->args( '_id' ) ] ) + ? $data[ $this->group->index ][ $this->args( '_id' ) ] + : false; + } + + return $data; + } + + /** + * Updates metadata/option data. + * + * @since 1.0.1 + * @param mixed $new_value Value to update data with. + * @param bool $single Whether data is an array (add_metadata). + * @return mixed + */ + public function update_data( $new_value, $single = true ) { + $a = $this->data_args( array( + 'single' => $single, + ) ); + + $a['value'] = $a['repeat'] ? array_values( $new_value ) : $new_value; + + /** + * Filter whether to override saving of meta value. + * Returning a non-null value will effectively short-circuit the function. + * + * @since 2.0.0 + * + * @param null|bool $check Whether to allow updating metadata for the given type. + * + * @param array $args { + * Array of data about current field including: + * + * @type string $value The value to set + * @type string $type The current object type + * @type int $id The current object ID + * @type string $field_id The ID of the field being updated + * @type bool $repeat Whether current field is repeatable + * @type bool $single Whether current field is a single database row + * } + * + * @param array $field_args All field arguments + * + * @param CMB2_Field object $field This field object + */ + $override = apply_filters( 'cmb2_override_meta_save', null, $a, $this->args(), $this ); + + /** + * Filter and parameters are documented for 'cmb2_override_meta_save' filter (above). + * + * The dynamic portion of the hook, $a['field_id'], refers to the current + * field id paramater. Returning a non-null value + * will effectively short-circuit the function. + * + * @since 2.0.0 + */ + $override = apply_filters( "cmb2_override_{$a['field_id']}_meta_save", $override, $a, $this->args(), $this ); + + // If override, return that. + if ( null !== $override ) { + return $override; + } + + // Options page handling (or temp data store). + if ( 'options-page' === $a['type'] || empty( $a['id'] ) ) { + return cmb2_options( $a['id'] )->update( $a['field_id'], $a['value'], false, $a['single'] ); + } + + // Add metadata if not single. + if ( ! $a['single'] ) { + return add_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'], false ); + } + + // Delete meta if we have an empty array. + if ( is_array( $a['value'] ) && empty( $a['value'] ) ) { + return delete_metadata( $a['type'], $a['id'], $a['field_id'], $this->value ); + } + + // Update metadata. + return update_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'] ); + } + + /** + * Removes/updates metadata/option data. + * + * @since 1.0.1 + * @param string $old Old value. + * @return mixed + */ + public function remove_data( $old = '' ) { + $a = $this->data_args( array( + 'old' => $old, + ) ); + + /** + * Filter whether to override removing of meta value. + * Returning a non-null value will effectively short-circuit the function. + * + * @since 2.0.0 + * + * @param null|bool $delete Whether to allow metadata deletion of the given type. + * @param array $args Array of data about current field including: + * 'type' : Current object type + * 'id' : Current object ID + * 'field_id' : Current Field ID + * 'repeat' : Whether current field is repeatable + * 'single' : Whether to save as a + * single meta value + * @param array $field_args All field arguments + * @param CMB2_Field object $field This field object + */ + $override = apply_filters( 'cmb2_override_meta_remove', null, $a, $this->args(), $this ); + + /** + * Filter whether to override removing of meta value. + * + * The dynamic portion of the hook, $a['field_id'], refers to the current + * field id paramater. Returning a non-null value + * will effectively short-circuit the function. + * + * @since 2.0.0 + * + * @param null|bool $delete Whether to allow metadata deletion of the given type. + * @param array $args Array of data about current field including: + * 'type' : Current object type + * 'id' : Current object ID + * 'field_id' : Current Field ID + * 'repeat' : Whether current field is repeatable + * 'single' : Whether to save as a + * single meta value + * @param array $field_args All field arguments + * @param CMB2_Field object $field This field object + */ + $override = apply_filters( "cmb2_override_{$a['field_id']}_meta_remove", $override, $a, $this->args(), $this ); + + // If no override, remove as usual. + if ( null !== $override ) { + return $override; + } // End if. + // Option page handling. + elseif ( 'options-page' === $a['type'] || empty( $a['id'] ) ) { + return cmb2_options( $a['id'] )->remove( $a['field_id'] ); + } + + // Remove metadata. + return delete_metadata( $a['type'], $a['id'], $a['field_id'], $old ); + } + + /** + * Data variables for get/set data methods + * + * @since 1.1.0 + * @param array $args Override arguments. + * @return array Updated arguments + */ + public function data_args( $args = array() ) { + $args = wp_parse_args( $args, array( + 'type' => $this->object_type, + 'id' => $this->object_id, + 'field_id' => $this->id( true ), + 'repeat' => $this->args( 'repeatable' ), + 'single' => ! $this->args( 'multiple' ), + ) ); + return $args; + } + + /** + * Checks if field has a registered sanitization callback + * + * @since 1.0.1 + * @param mixed $meta_value Meta value. + * @return mixed Possibly sanitized meta value + */ + public function sanitization_cb( $meta_value ) { + + if ( $this->args( 'repeatable' ) && is_array( $meta_value ) ) { + // Remove empties. + $meta_value = array_filter( $meta_value ); + } + + // Check if the field has a registered validation callback. + $cb = $this->maybe_callback( 'sanitization_cb' ); + if ( false === $cb ) { + // If requesting NO validation, return meta value. + return $meta_value; + } elseif ( $cb ) { + // Ok, callback is good, let's run it. + return call_user_func( $cb, $meta_value, $this->args(), $this ); + } + + $sanitizer = new CMB2_Sanitize( $this, $meta_value ); + $field_type = $this->type(); + + /** + * Filter the value before it is saved. + * + * The dynamic portion of the hook name, $field_type, refers to the field type. + * + * Passing a non-null value to the filter will short-circuit saving + * the field value, saving the passed value instead. + * + * @param bool|mixed $override_value Sanitization/Validation override value to return. + * Default: null. false to skip it. + * @param mixed $value The value to be saved to this field. + * @param int $object_id The ID of the object where the value will be saved + * @param array $field_args The current field's arguments + * @param object $sanitizer This `CMB2_Sanitize` object + */ + $override_value = apply_filters( "cmb2_sanitize_{$field_type}", null, $sanitizer->value, $this->object_id, $this->args(), $sanitizer ); + + if ( null !== $override_value ) { + return $override_value; + } + + // Sanitization via 'CMB2_Sanitize'. + return $sanitizer->{$field_type}(); + } + + /** + * Process $_POST data to save this field's value + * + * @since 2.0.3 + * @param array $data_to_save $_POST data to check. + * @return array|int|bool Result of save, false on failure + */ + public function save_field_from_data( array $data_to_save ) { + $this->data_to_save = $data_to_save; + + $meta_value = isset( $this->data_to_save[ $this->id( true ) ] ) + ? $this->data_to_save[ $this->id( true ) ] + : null; + + return $this->save_field( $meta_value ); + } + + /** + * Sanitize/store a value to this field + * + * @since 2.0.0 + * @param array $meta_value Desired value to sanitize/store. + * @return array|int|bool Result of save. false on failure + */ + public function save_field( $meta_value ) { + + $updated = false; + $action = ''; + $new_value = $this->sanitization_cb( $meta_value ); + + if ( ! $this->args( 'save_field' ) ) { + + // Nothing to see here. + $action = 'disabled'; + + } elseif ( $this->args( 'multiple' ) && ! $this->args( 'repeatable' ) && ! $this->group ) { + + $this->remove_data(); + $count = 0; + + if ( ! empty( $new_value ) ) { + foreach ( $new_value as $add_new ) { + if ( $this->update_data( $add_new, false ) ) { + $count++; + } + } + } + + $updated = $count ? $count : false; + $action = 'repeatable'; + + } elseif ( ! CMB2_Utils::isempty( $new_value ) && $new_value !== $this->get_data() ) { + $updated = $this->update_data( $new_value ); + $action = 'updated'; + } elseif ( CMB2_Utils::isempty( $new_value ) ) { + $updated = $this->remove_data(); + $action = 'removed'; + } + + if ( $updated ) { + $this->value = $this->get_data(); + $this->escaped_value = null; + } + + $field_id = $this->id( true ); + + /** + * Hooks after save field action. + * + * @since 2.2.0 + * + * @param string $field_id the current field id paramater. + * @param bool $updated Whether the metadata update action occurred. + * @param string $action Action performed. Could be "repeatable", "updated", or "removed". + * @param CMB2_Field object $field This field object + */ + do_action( 'cmb2_save_field', $field_id, $updated, $action, $this ); + + /** + * Hooks after save field action. + * + * The dynamic portion of the hook, $field_id, refers to the + * current field id paramater. + * + * @since 2.2.0 + * + * @param bool $updated Whether the metadata update action occurred. + * @param string $action Action performed. Could be "repeatable", "updated", or "removed". + * @param CMB2_Field object $field This field object + */ + do_action( "cmb2_save_field_{$field_id}", $updated, $action, $this ); + + return $updated; + } + + /** + * Determine if current type is exempt from escaping + * + * @since 1.1.0 + * @return bool True if exempt + */ + public function escaping_exception() { + // These types cannot be escaped. + return in_array( $this->type(), array( + 'file_list', + 'multicheck', + 'text_datetime_timestamp_timezone', + ) ); + } + + /** + * Determine if current type cannot be repeatable + * + * @since 1.1.0 + * @param string $type Field type to check. + * @return bool True if type cannot be repeatable + */ + public function repeatable_exception( $type ) { + // These types cannot be repeatable. + $internal_fields = array( + // Use file_list instead. + 'file' => 1, + 'radio' => 1, + 'title' => 1, + 'wysiwyg' => 1, + 'checkbox' => 1, + 'radio_inline' => 1, + 'taxonomy_radio' => 1, + 'taxonomy_radio_inline' => 1, + 'taxonomy_radio_hierarchical' => 1, + 'taxonomy_select' => 1, + 'taxonomy_multicheck' => 1, + 'taxonomy_multicheck_inline' => 1, + 'taxonomy_multicheck_hierarchical' => 1, + + ); + + /** + * Filter field types that are non-repeatable. + * + * Note that this does *not* allow overriding the default non-repeatable types. + * + * @since 2.1.1 + * + * @param array $fields Array of fields designated as non-repeatable. Note that the field names are *keys*, + * and not values. The value can be anything, because it is meaningless. Example: + * array( 'my_custom_field' => 1 ) + */ + $all_fields = array_merge( apply_filters( 'cmb2_non_repeatable_fields', array() ), $internal_fields ); + return isset( $all_fields[ $type ] ); + } + + /** + * Determine if current type has its own defaults field-arguments method. + * + * @since 2.2.6 + * @param string $type Field type to check. + * @return bool True if has own method. + */ + public function has_args_method( $type ) { + + // These types have their own arguments parser. + $type_methods = array( + 'group' => 'set_field_defaults_group', + 'wysiwyg' => 'set_field_defaults_wysiwyg', + ); + + if ( isset( $type_methods[ $type ] ) ) { + return $type_methods[ $type ]; + } + + $all_or_nothing_types = array_flip( apply_filters( 'cmb2_all_or_nothing_types', array( + 'select', + 'radio', + 'radio_inline', + 'taxonomy_select', + 'taxonomy_radio', + 'taxonomy_radio_inline', + 'taxonomy_radio_hierarchical', + ), $this ) ); + + if ( isset( $all_or_nothing_types[ $type ] ) ) { + return 'set_field_defaults_all_or_nothing_types'; + } + + return false; + } + + /** + * Escape the value before output. Defaults to 'esc_attr()' + * + * @since 1.0.1 + * @param callable|string $func Escaping function (if not esc_attr()). + * @param mixed $meta_value Meta value. + * @return mixed Final value. + */ + public function escaped_value( $func = 'esc_attr', $meta_value = '' ) { + + if ( null !== $this->escaped_value ) { + return $this->escaped_value; + } + + $meta_value = $meta_value ? $meta_value : $this->value(); + + // Check if the field has a registered escaping callback. + if ( $cb = $this->maybe_callback( 'escape_cb' ) ) { + // Ok, callback is good, let's run it. + return call_user_func( $cb, $meta_value, $this->args(), $this ); + } + + $field_type = $this->type(); + + /** + * Filter the value for escaping before it is ouput. + * + * The dynamic portion of the hook name, $field_type, refers to the field type. + * + * Passing a non-null value to the filter will short-circuit the built-in + * escaping for this field. + * + * @param bool|mixed $override_value Escaping override value to return. + * Default: null. false to skip it. + * @param mixed $meta_value The value to be output. + * @param array $field_args The current field's arguments. + * @param object $field This `CMB2_Field` object. + */ + $esc = apply_filters( "cmb2_types_esc_{$field_type}", null, $meta_value, $this->args(), $this ); + if ( null !== $esc ) { + return $esc; + } + + if ( false === $cb || $this->escaping_exception() ) { + // If requesting NO escaping, return meta value. + return $this->val_or_default( $meta_value ); + } + + // escaping function passed in? + $func = $func ? $func : 'esc_attr'; + $meta_value = $this->val_or_default( $meta_value ); + + if ( is_array( $meta_value ) ) { + foreach ( $meta_value as $key => $value ) { + $meta_value[ $key ] = call_user_func( $func, $value ); + } + } else { + $meta_value = call_user_func( $func, $meta_value ); + } + + $this->escaped_value = $meta_value; + return $this->escaped_value; + } + + /** + * Return non-empty value or field default if value IS empty + * + * @since 2.0.0 + * @param mixed $meta_value Field value. + * @return mixed Field value, or default value + */ + public function val_or_default( $meta_value ) { + return ! CMB2_Utils::isempty( $meta_value ) ? $meta_value : $this->get_default(); + } + + /** + * Offset a time value based on timezone + * + * @since 1.0.0 + * @return string Offset time string + */ + public function field_timezone_offset() { + return CMB2_Utils::timezone_offset( $this->field_timezone() ); + } + + /** + * Return timezone string + * + * @since 1.0.0 + * @return string Timezone string + */ + public function field_timezone() { + $value = ''; + + // Is timezone arg set? + if ( $this->args( 'timezone' ) ) { + $value = $this->args( 'timezone' ); + } // End if. + // Is there another meta key with a timezone stored as its value we should use? + elseif ( $this->args( 'timezone_meta_key' ) ) { + $value = $this->get_data( $this->args( 'timezone_meta_key' ) ); + } + + return $value; + } + + /** + * Format the timestamp field value based on the field date/time format arg + * + * @since 2.0.0 + * @param int $meta_value Timestamp. + * @param string $format Either date_format or time_format. + * @return string Formatted date + */ + public function format_timestamp( $meta_value, $format = 'date_format' ) { + return date( stripslashes( $this->args( $format ) ), $meta_value ); + } + + /** + * Return a formatted timestamp for a field + * + * @since 2.0.0 + * @param string $format Either date_format or time_format. + * @param string|int $meta_value Optional meta value to check. + * @return string Formatted date + */ + public function get_timestamp_format( $format = 'date_format', $meta_value = 0 ) { + $meta_value = $meta_value ? $meta_value : $this->escaped_value(); + $meta_value = CMB2_Utils::make_valid_time_stamp( $meta_value ); + + if ( empty( $meta_value ) ) { + return ''; + } + + return is_array( $meta_value ) + ? array_map( array( $this, 'format_timestamp' ), $meta_value, $format ) + : $this->format_timestamp( $meta_value, $format ); + } + + /** + * Get timestamp from text date + * + * @since 2.2.0 + * @param string $value Date value. + * @return mixed Unix timestamp representing the date. + */ + public function get_timestamp_from_value( $value ) { + return CMB2_Utils::get_timestamp_from_value( $value, $this->args( 'date_format' ) ); + } + + /** + * Get field render callback and Render the field row + * + * @since 1.0.0 + */ + public function render_field() { + $this->render_context = 'edit'; + + $this->peform_param_callback( 'render_row_cb' ); + + // For chaining. + return $this; + } + + /** + * Default field render callback + * + * @since 2.1.1 + */ + public function render_field_callback() { + + // If field is requesting to not be shown on the front-end. + if ( ! is_admin() && ! $this->args( 'on_front' ) ) { + return; + } + + // If field is requesting to be conditionally shown. + if ( ! $this->should_show() ) { + return; + } + + $field_type = $this->type(); + + /** + * Hook before field row begins. + * + * @param CMB2_Field $field The current field object. + */ + do_action( 'cmb2_before_field_row', $this ); + + /** + * Hook before field row begins. + * + * The dynamic portion of the hook name, $field_type, refers to the field type. + * + * @param CMB2_Field $field The current field object. + */ + do_action( "cmb2_before_{$field_type}_field_row", $this ); + + $this->peform_param_callback( 'before_row' ); + + printf( "
            \n", $this->row_classes(), $field_type ); + + if ( ! $this->args( 'show_names' ) ) { + echo "\n\t
            \n"; + + $this->peform_param_callback( 'label_cb' ); + + } else { + + if ( $this->get_param_callback_result( 'label_cb' ) ) { + echo '
            ', $this->peform_param_callback( 'label_cb' ), '
            '; + } + + echo "\n\t
            \n"; + } + + $this->peform_param_callback( 'before' ); + + $types = new CMB2_Types( $this ); + $types->render(); + + $this->peform_param_callback( 'after' ); + + echo "\n\t
            \n
            "; + + $this->peform_param_callback( 'after_row' ); + + /** + * Hook after field row ends. + * + * The dynamic portion of the hook name, $field_type, refers to the field type. + * + * @param CMB2_Field $field The current field object. + */ + do_action( "cmb2_after_{$field_type}_field_row", $this ); + + /** + * Hook after field row ends. + * + * @param CMB2_Field $field The current field object. + */ + do_action( 'cmb2_after_field_row', $this ); + + // For chaining. + return $this; + } + + /** + * The default label_cb callback (if not a title field) + * + * @since 2.1.1 + * @return string Label html markup. + */ + public function label() { + if ( ! $this->args( 'name' ) ) { + return ''; + } + + $style = ! $this->args( 'show_names' ) ? ' style="display:none;"' : ''; + + return sprintf( "\n" . '%3$s' . "\n", $style, $this->id(), $this->args( 'name' ) ); + } + + /** + * Defines the classes for the current CMB2 field row + * + * @since 2.0.0 + * @return string Space concatenated list of classes + */ + public function row_classes() { + + $classes = array(); + + /** + * By default, 'text_url' and 'text' fields get table-like styling + * + * @since 2.0.0 + * + * @param array $field_types The types of fields which should get the 'table-layout' class + */ + $repeat_table_rows_types = apply_filters( 'cmb2_repeat_table_row_types', array( + 'text_url', + 'text', + ) ); + + $conditional_classes = array( + 'cmb-type-' . str_replace( '_', '-', sanitize_html_class( $this->type() ) ) => true, + 'cmb2-id-' . str_replace( '_', '-', sanitize_html_class( $this->id() ) ) => true, + 'cmb-repeat' => $this->args( 'repeatable' ), + 'cmb-repeat-group-field' => $this->group, + 'cmb-inline' => $this->args( 'inline' ), + 'table-layout' => 'edit' === $this->render_context && in_array( $this->type(), $repeat_table_rows_types ), + ); + + foreach ( $conditional_classes as $class => $condition ) { + if ( $condition ) { + $classes[] = $class; + } + } + + if ( $added_classes = $this->args( 'classes' ) ) { + $added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes; + } elseif ( $added_classes = $this->get_param_callback_result( 'classes_cb' ) ) { + $added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes; + } + + if ( $added_classes ) { + $classes[] = esc_attr( $added_classes ); + } + + /** + * Globally filter row classes + * + * @since 2.0.0 + * + * @param string $classes Space-separated list of row classes + * @param CMB2_Field object $field This field object + */ + return apply_filters( 'cmb2_row_classes', implode( ' ', $classes ), $this ); + } + + /** + * Get field display callback and render the display value in the column. + * + * @since 2.2.2 + */ + public function render_column() { + $this->render_context = 'display'; + + $this->peform_param_callback( 'display_cb' ); + + // For chaining. + return $this; + } + + /** + * The method to fetch the value for this field for the REST API. + * + * @since 2.5.0 + */ + public function get_rest_value() { + $field_type = $this->type(); + $field_id = $this->id( true ); + + if ( $cb = $this->maybe_callback( 'rest_value_cb' ) ) { + add_filter( "cmb2_get_rest_value_for_{$field_id}", $cb, 99 ); + } + + $value = $this->get_data(); + + /** + * Filter the value before it is sent to the REST request. + * + * @since 2.5.0 + * + * @param mixed $value The value from CMB2_Field::get_data() + * @param CMB2_Field $field This field object. + */ + $value = apply_filters( 'cmb2_get_rest_value', $value, $this ); + + /** + * Filter the value before it is sent to the REST request. + * + * The dynamic portion of the hook name, $field_type, refers to the field type. + * + * @since 2.5.0 + * + * @param mixed $value The value from CMB2_Field::get_data() + * @param CMB2_Field $field This field object. + */ + $value = apply_filters( "cmb2_get_rest_value_{$field_type}", $value, $this ); + + /** + * Filter the value before it is sent to the REST request. + * + * The dynamic portion of the hook name, $field_id, refers to the field id. + * + * @since 2.5.0 + * + * @param mixed $value The value from CMB2_Field::get_data() + * @param CMB2_Field $field This field object. + */ + return apply_filters( "cmb2_get_rest_value_for_{$field_id}", $value, $this ); + } + + /** + * Default callback to outputs field value in a display format. + * + * @since 2.2.2 + */ + public function display_value_callback() { + // If field is requesting to be conditionally shown. + if ( ! $this->should_show() ) { + return; + } + + $display = new CMB2_Field_Display( $this ); + $field_type = $this->type(); + + /** + * A filter to bypass the default display. + * + * The dynamic portion of the hook name, $field_type, refers to the field type. + * + * Passing a non-null value to the filter will short-circuit the default display. + * + * @param bool|mixed $pre_output Default null value. + * @param CMB2_Field $field This field object. + * @param CMB2_Field_Display $display The `CMB2_Field_Display` object. + */ + $pre_output = apply_filters( "cmb2_pre_field_display_{$field_type}", null, $this, $display ); + + if ( null !== $pre_output ) { + echo $pre_output; + return; + } + + $this->peform_param_callback( 'before_display_wrap' ); + + printf( "
            \n", $this->row_classes(), $field_type ); + + $this->peform_param_callback( 'before_display' ); + + CMB2_Field_Display::get( $this )->display(); + + $this->peform_param_callback( 'after_display' ); + + echo "\n
            "; + + $this->peform_param_callback( 'after_display_wrap' ); + + // For chaining. + return $this; + } + + /** + * Replaces a hash key - {#} - with the repeatable index + * + * @since 1.2.0 + * @param string $value Value to update. + * @return string Updated value + */ + public function replace_hash( $value ) { + // Replace hash with 1 based count. + return str_replace( '{#}', ( $this->index + 1 ), $value ); + } + + /** + * Retrieve text parameter from field's text array (if it has one), or use fallback text + * For back-compatibility, falls back to checking the options array. + * + * @since 2.2.2 + * @param string $text_key Key in field's text array. + * @param string $fallback Fallback text. + * @return string Text + */ + public function get_string( $text_key, $fallback ) { + // If null, populate with our field strings values. + if ( null === $this->strings ) { + $this->strings = (array) $this->args['text']; + + if ( is_callable( $this->args['text_cb'] ) ) { + $strings = call_user_func( $this->args['text_cb'], $this ); + + if ( $strings && is_array( $strings ) ) { + $this->strings += $strings; + } + } + } + + // If we have that string value, send it back. + if ( isset( $this->strings[ $text_key ] ) ) { + return $this->strings[ $text_key ]; + } + + // Check options for back-compat. + $string = $this->options( $text_key ); + + return $string ? $string : $fallback; + } + + /** + * Retrieve options args. + * + * @since 2.0.0 + * @param string $key Specific option to retrieve. + * @return array|mixed Array of options or specific option. + */ + public function options( $key = '' ) { + if ( empty( $this->field_options ) ) { + $this->set_options(); + } + + if ( $key ) { + return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false; + } + + return $this->field_options; + } + + /** + * Generates/sets options args. Calls options_cb if it exists. + * + * @since 2.2.5 + * + * @return array Array of options + */ + public function set_options() { + $this->field_options = (array) $this->args['options']; + + if ( is_callable( $this->args['options_cb'] ) ) { + $options = call_user_func( $this->args['options_cb'], $this ); + + if ( $options && is_array( $options ) ) { + $this->field_options = $options + $this->field_options; + } + } + + return $this->field_options; + } + + /** + * Store JS dependencies as part of the field args. + * + * @since 2.2.0 + * @param array $dependencies Dependies to register for this field. + */ + public function add_js_dependencies( $dependencies = array() ) { + foreach ( (array) $dependencies as $dependency ) { + $this->args['js_dependencies'][ $dependency ] = $dependency; + } + + CMB2_JS::add_dependencies( $dependencies ); + } + + /** + * Send field data to JS. + * + * @since 2.2.0 + */ + public function register_js_data() { + if ( $this->group ) { + CMB2_JS::add_field_data( $this->group ); + } + + return CMB2_JS::add_field_data( $this ); + } + + /** + * Get an array of some of the field data to be used in the Javascript. + * + * @since 2.2.4 + * + * @return array + */ + public function js_data() { + return array( + 'label' => $this->args( 'name' ), + 'id' => $this->id( true ), + 'type' => $this->type(), + 'hash' => $this->hash_id(), + 'box' => $this->cmb_id, + 'id_attr' => $this->id(), + 'name_attr' => $this->args( '_name' ), + 'default' => $this->get_default(), + 'group' => $this->group_id(), + 'index' => $this->group ? $this->group->index : null, + ); + } + + /** + * Returns a unique hash representing this field. + * + * @since 2.2.4 + * + * @return string + */ + public function hash_id() { + if ( '' === $this->hash_id ) { + $this->hash_id = CMB2_Utils::generate_hash( $this->cmb_id . '||' . $this->id() ); + } + + return $this->hash_id; + } + + /** + * Gets the id of the group field if this field is part of a group. + * + * @since 2.2.4 + * + * @return string + */ + public function group_id() { + return $this->group ? $this->group->id( true ) : ''; + } + + /** + * Get CMB2_Field default value, either from default param or default_cb param. + * + * @since 0.2.2 + * + * @return mixed Default field value + */ + public function get_default() { + $default = $this->args['default']; + + if ( null !== $default ) { + return apply_filters( 'cmb2_default_filter', $default, $this ); + } + + $param = is_callable( $this->args['default_cb'] ) ? 'default_cb' : 'default'; + $default = $this->args['default'] = $this->get_param_callback_result( $param ); + + // Allow a filter override of the default value. + return apply_filters( 'cmb2_default_filter', $this->args['default'], $this ); + } + + /** + * Fills in empty field parameters with defaults + * + * @since 1.1.0 + * + * @param array $args Field config array. + * @return array Modified field config array. + */ + public function _set_field_defaults( $args ) { + $defaults = $this->get_default_field_args( $args ); + + /** + * Filter the CMB2 Field defaults. + * + * @since 2.6.0 + * @param array $defaults Metabox field config array defaults. + * @param string $id Field id for the current field to allow for selective filtering. + * @param string $type Field type for the current field to allow for selective filtering. + * @param CMB2_Field object $field This field object. + */ + $defaults = apply_filters( 'cmb2_field_defaults', $defaults, $args['id'], $args['type'], $this ); + + // Set up blank or default values for empty ones. + $args = wp_parse_args( $args, $defaults ); + + /** + * Filtering the CMB2 Field arguments once merged with the defaults, but before further processing. + * + * @since 2.6.0 + * @param array $args Metabox field config array defaults. + * @param CMB2_Field object $field This field object. + */ + $args = apply_filters( 'cmb2_field_arguments_raw', $args, $this ); + + /* + * Deprecated usage: + * + * 'std' -- use 'default' (no longer works) + * 'row_classes' -- use 'class', or 'class_cb' + * 'default' -- as callback (use default_cb) + */ + $args = $this->convert_deprecated_params( $args ); + + $args['repeatable'] = $args['repeatable'] && ! $this->repeatable_exception( $args['type'] ); + $args['inline'] = $args['inline'] || false !== stripos( $args['type'], '_inline' ); + $args['_id'] = $args['id']; + $args['_name'] = $args['id']; + + if ( $method = $this->has_args_method( $args['type'] ) ) { + $args = $this->{$method}( $args ); + } + + if ( $this->group ) { + $args = $this->set_group_sub_field_defaults( $args ); + } + + $args['has_supporting_data'] = in_array( + $args['type'], + array( + // CMB2_Sanitize::_save_file_id_value()/CMB2_Sanitize::_get_group_file_value_array(). + 'file', + // See CMB2_Sanitize::_save_utc_value(). + 'text_datetime_timestamp_timezone', + ), + true + ); + + // Repeatable fields require jQuery sortable library. + if ( ! empty( $args['repeatable'] ) ) { + CMB2_JS::add_dependencies( 'jquery-ui-sortable' ); + } + + /** + * Filter the CMB2 Field arguments after processing. + * + * @since 2.6.0 + * @param array $args Metabox field config array after processing. + * @param CMB2_Field object $field This field object. + */ + return apply_filters( 'cmb2_field_arguments', $args, $this ); + } + + /** + * Sets default arguments for the group field types. + * + * @since 2.2.6 + * + * @param array $args Field config array. + * @return array Modified field config array. + */ + protected function set_field_defaults_group( $args ) { + $args['options'] = wp_parse_args( $args['options'], array( + 'add_button' => esc_html__( 'Add Group', 'cmb2' ), + 'remove_button' => esc_html__( 'Remove Group', 'cmb2' ), + 'remove_confirm' => '', + ) ); + + return $args; + } + + /** + * Sets default arguments for the wysiwyg field types. + * + * @since 2.2.6 + * + * @param array $args Field config array. + * @return array Modified field config array. + */ + protected function set_field_defaults_wysiwyg( $args ) { + $args['id'] = strtolower( str_ireplace( '-', '_', $args['id'] ) ); + $args['options']['textarea_name'] = $args['_name']; + + return $args; + } + + /** + * Sets default arguments for the all-or-nothing field types. + * + * @since 2.2.6 + * + * @param array $args Field config array. + * @return array Modified field config array. + */ + protected function set_field_defaults_all_or_nothing_types( $args ) { + $args['show_option_none'] = isset( $args['show_option_none'] ) ? $args['show_option_none'] : null; + $args['show_option_none'] = true === $args['show_option_none'] ? esc_html__( 'None', 'cmb2' ) : $args['show_option_none']; + + if ( null === $args['show_option_none'] ) { + $off_by_default = in_array( $args['type'], array( 'select', 'radio', 'radio_inline' ), true ); + $args['show_option_none'] = $off_by_default ? false : esc_html__( 'None', 'cmb2' ); + } + + return $args; + } + + /** + * Sets default arguments for group sub-fields. + * + * @since 2.2.6 + * + * @param array $args Field config array. + * @return array Modified field config array. + */ + protected function set_group_sub_field_defaults( $args ) { + $args['id'] = $this->group->args( 'id' ) . '_' . $this->group->index . '_' . $args['id']; + $args['_name'] = $this->group->args( 'id' ) . '[' . $this->group->index . '][' . $args['_name'] . ']'; + + return $args; + } + + /** + * Gets the default arguments for all fields. + * + * @since 2.2.6 + * + * @param array $args Field config array. + * @return array Field defaults. + */ + protected function get_default_field_args( $args ) { + $type = isset( $args['type'] ) ? $args['type'] : ''; + + return array( + 'type' => $type, + 'name' => '', + 'desc' => '', + 'before' => '', + 'after' => '', + 'options' => array(), + 'options_cb' => '', + 'text' => array(), + 'text_cb' => '', + 'attributes' => array(), + 'protocols' => null, + 'default' => null, + 'default_cb' => '', + 'classes' => null, + 'classes_cb' => '', + 'select_all_button' => true, + 'multiple' => false, + 'repeatable' => 'group' === $type, + 'inline' => false, + 'on_front' => true, + 'show_names' => true, + 'save_field' => true, // Will not save if false. + 'date_format' => 'm\/d\/Y', + 'time_format' => 'h:i A', + 'description' => isset( $args['desc'] ) ? $args['desc'] : '', + 'preview_size' => 'file' === $type ? array( 350, 350 ) : array( 50, 50 ), + 'render_row_cb' => array( $this, 'render_field_callback' ), + 'display_cb' => array( $this, 'display_value_callback' ), + 'label_cb' => 'title' !== $type ? array( $this, 'label' ) : '', + 'column' => false, + 'js_dependencies' => array(), + 'show_in_rest' => null, + ); + } + + /** + * Get default field arguments specific to this CMB2 object. + * + * @since 2.2.0 + * @param array $field_args Metabox field config array. + * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent). + * @return array Array of field arguments. + */ + protected function get_default_args( $field_args, $field_group = null ) { + $args = parent::get_default_args( array(), $this->group ); + + if ( isset( $field_args['field_args'] ) ) { + $args = wp_parse_args( $field_args, $args ); + } else { + $args['field_args'] = wp_parse_args( $field_args, $this->args ); + } + + return $args; + } + + /** + * Returns a cloned version of this field object, but with + * modified/overridden field arguments. + * + * @since 2.2.2 + * @param array $field_args Array of field arguments, or entire array of + * arguments for CMB2_Field. + * + * @return CMB2_Field The new CMB2_Field instance. + */ + public function get_field_clone( $field_args ) { + return $this->get_new_field( $field_args ); + } + + /** + * Returns the CMB2 instance this field is registered to. + * + * @since 2.2.2 + * + * @return CMB2|WP_Error If new CMB2_Field is called without cmb_id arg, returns error. + */ + public function get_cmb() { + if ( ! $this->cmb_id ) { + return new WP_Error( 'no_cmb_id', esc_html__( 'Sorry, this field does not have a cmb_id specified.', 'cmb2' ) ); + } + + return cmb2_get_metabox( $this->cmb_id, $this->object_id, $this->object_type ); + } + + /** + * Converts deprecated field parameters to the current/proper parameter, and throws a deprecation notice. + * + * @since 2.2.3 + * @param array $args Metabox field config array. + * @return array Modified field config array. + */ + protected function convert_deprecated_params( $args ) { + + if ( isset( $args['row_classes'] ) ) { + + // We'll let this one be. + // $this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_PARAM, 'row_classes', 'classes' ); + // row_classes param could be a callback. This is definitely deprecated. + if ( is_callable( $args['row_classes'] ) ) { + + $this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'row_classes', 'classes_cb' ); + + $args['classes_cb'] = $args['row_classes']; + $args['classes'] = null; + } else { + + $args['classes'] = $args['row_classes']; + } + + unset( $args['row_classes'] ); + } + + // default param can be passed a callback as well. + if ( is_callable( $args['default'] ) ) { + + $this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'default', 'default_cb' ); + + $args['default_cb'] = $args['default']; + $args['default'] = null; + } + + // options param can be passed a callback as well. + if ( is_callable( $args['options'] ) ) { + + $this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'options', 'options_cb' ); + + $args['options_cb'] = $args['options']; + $args['options'] = array(); + } + + return $args; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Field_Display.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Field_Display.php new file mode 100755 index 00000000..442e9518 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Field_Display.php @@ -0,0 +1,484 @@ +type() ) { + case 'text_url': + $type = new CMB2_Display_Text_Url( $field ); + break; + case 'text_money': + $type = new CMB2_Display_Text_Money( $field ); + break; + case 'colorpicker': + $type = new CMB2_Display_Colorpicker( $field ); + break; + case 'checkbox': + $type = new CMB2_Display_Checkbox( $field ); + break; + case 'wysiwyg': + case 'textarea_small': + $type = new CMB2_Display_Textarea( $field ); + break; + case 'textarea_code': + $type = new CMB2_Display_Textarea_Code( $field ); + break; + case 'text_time': + $type = new CMB2_Display_Text_Time( $field ); + break; + case 'text_date': + case 'text_date_timestamp': + case 'text_datetime_timestamp': + $type = new CMB2_Display_Text_Date( $field ); + break; + case 'text_datetime_timestamp_timezone': + $type = new CMB2_Display_Text_Date_Timezone( $field ); + break; + case 'select': + case 'radio': + case 'radio_inline': + $type = new CMB2_Display_Select( $field ); + break; + case 'multicheck': + case 'multicheck_inline': + $type = new CMB2_Display_Multicheck( $field ); + break; + case 'taxonomy_radio': + case 'taxonomy_radio_inline': + case 'taxonomy_select': + case 'taxonomy_radio_hierarchical': + $type = new CMB2_Display_Taxonomy_Radio( $field ); + break; + case 'taxonomy_multicheck': + case 'taxonomy_multicheck_inline': + case 'taxonomy_multicheck_hierarchical': + $type = new CMB2_Display_Taxonomy_Multicheck( $field ); + break; + case 'file': + $type = new CMB2_Display_File( $field ); + break; + case 'file_list': + $type = new CMB2_Display_File_List( $field ); + break; + case 'oembed': + $type = new CMB2_Display_oEmbed( $field ); + break; + default: + $type = new self( $field ); + break; + }// End switch. + + return $type; + } + + /** + * Setup our class vars + * + * @since 2.2.2 + * @param CMB2_Field $field A CMB2 field object. + */ + public function __construct( CMB2_Field $field ) { + $this->field = $field; + $this->value = $this->field->value; + } + + /** + * Catchall method if field's 'display_cb' is NOT defined, or field type does + * not have a corresponding display method + * + * @since 2.2.2 + */ + public function display() { + // If repeatable. + if ( $this->field->args( 'repeatable' ) ) { + + // And has a repeatable value. + if ( is_array( $this->field->value ) ) { + + // Then loop and output. + echo '
              '; + foreach ( $this->field->value as $val ) { + $this->value = $val; + echo '
            • ', $this->_display(), '
            • '; + ; + } + echo '
            '; + } + } else { + $this->_display(); + } + } + + /** + * Default fallback display method. + * + * @since 2.2.2 + */ + protected function _display() { + print_r( $this->value ); + } +} + +class CMB2_Display_Text_Url extends CMB2_Field_Display { + /** + * Display url value. + * + * @since 2.2.2 + */ + protected function _display() { + echo make_clickable( esc_url( $this->value ) ); + } +} + +class CMB2_Display_Text_Money extends CMB2_Field_Display { + /** + * Display text_money value. + * + * @since 2.2.2 + */ + protected function _display() { + $this->value = $this->value ? $this->value : '0'; + echo ( ! $this->field->get_param_callback_result( 'before_field' ) ? '$' : ' ' ), $this->value; + } +} + +class CMB2_Display_Colorpicker extends CMB2_Field_Display { + /** + * Display color picker value. + * + * @since 2.2.2 + */ + protected function _display() { + echo ' ', esc_html( $this->value ), ''; + } +} + +class CMB2_Display_Checkbox extends CMB2_Field_Display { + /** + * Display multicheck value. + * + * @since 2.2.2 + */ + protected function _display() { + echo $this->value === 'on' ? 'on' : 'off'; + } +} + +class CMB2_Display_Select extends CMB2_Field_Display { + /** + * Display select value. + * + * @since 2.2.2 + */ + protected function _display() { + $options = $this->field->options(); + + $fallback = $this->field->args( 'show_option_none' ); + if ( ! $fallback && isset( $options[''] ) ) { + $fallback = $options['']; + } + if ( ! $this->value && $fallback ) { + echo $fallback; + } elseif ( isset( $options[ $this->value ] ) ) { + echo $options[ $this->value ]; + } else { + echo esc_attr( $this->value ); + } + } +} + +class CMB2_Display_Multicheck extends CMB2_Field_Display { + /** + * Display multicheck value. + * + * @since 2.2.2 + */ + protected function _display() { + if ( empty( $this->value ) || ! is_array( $this->value ) ) { + return; + } + + $options = $this->field->options(); + + $output = array(); + foreach ( $this->value as $val ) { + if ( isset( $options[ $val ] ) ) { + $output[] = $options[ $val ]; + } else { + $output[] = esc_attr( $val ); + } + } + + echo implode( ', ', $output ); + } +} + +class CMB2_Display_Textarea extends CMB2_Field_Display { + /** + * Display textarea value. + * + * @since 2.2.2 + */ + protected function _display() { + echo wpautop( wp_kses_post( $this->value ) ); + } +} + +class CMB2_Display_Textarea_Code extends CMB2_Field_Display { + /** + * Display textarea_code value. + * + * @since 2.2.2 + */ + protected function _display() { + echo '' . print_r( $this->value, true ) . ''; + } +} + +class CMB2_Display_Text_Time extends CMB2_Field_Display { + /** + * Display text_time value. + * + * @since 2.2.2 + */ + protected function _display() { + echo $this->field->get_timestamp_format( 'time_format', $this->value ); + } +} + +class CMB2_Display_Text_Date extends CMB2_Field_Display { + /** + * Display text_date value. + * + * @since 2.2.2 + */ + protected function _display() { + echo $this->field->get_timestamp_format( 'date_format', $this->value ); + } +} + +class CMB2_Display_Text_Date_Timezone extends CMB2_Field_Display { + /** + * Display text_datetime_timestamp_timezone value. + * + * @since 2.2.2 + */ + protected function _display() { + $field = $this->field; + + if ( empty( $this->value ) ) { + return; + } + + $datetime = maybe_unserialize( $this->value ); + $this->value = $tzstring = ''; + + if ( $datetime && $datetime instanceof DateTime ) { + $tz = $datetime->getTimezone(); + $tzstring = $tz->getName(); + $this->value = $datetime->getTimestamp(); + } + + $date = $this->field->get_timestamp_format( 'date_format', $this->value ); + $time = $this->field->get_timestamp_format( 'time_format', $this->value ); + + echo $date, ( $time ? ' ' . $time : '' ), ( $tzstring ? ', ' . $tzstring : '' ); + } +} + +class CMB2_Display_Taxonomy_Radio extends CMB2_Field_Display { + /** + * Display single taxonomy value. + * + * @since 2.2.2 + */ + protected function _display() { + $taxonomy = $this->field->args( 'taxonomy' ); + $types = new CMB2_Types( $this->field ); + $type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_Taxonomy_Radio' ); + $terms = $type->get_object_terms(); + $term = false; + + if ( is_wp_error( $terms ) || empty( $terms ) && ( $default = $this->field->get_default() ) ) { + $term = get_term_by( 'slug', $default, $taxonomy ); + } elseif ( ! empty( $terms ) ) { + $term = $terms[ key( $terms ) ]; + } + + if ( $term ) { + $link = get_edit_term_link( $term->term_id, $taxonomy ); + echo '', esc_html( $term->name ), ''; + } + } +} + +class CMB2_Display_Taxonomy_Multicheck extends CMB2_Field_Display { + /** + * Display taxonomy values. + * + * @since 2.2.2 + */ + protected function _display() { + $taxonomy = $this->field->args( 'taxonomy' ); + $types = new CMB2_Types( $this->field ); + $type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_Taxonomy_Multicheck' ); + $terms = $type->get_object_terms(); + + if ( is_wp_error( $terms ) || empty( $terms ) && ( $default = $this->field->get_default() ) ) { + $terms = array(); + if ( is_array( $default ) ) { + foreach ( $default as $slug ) { + $terms[] = get_term_by( 'slug', $slug, $taxonomy ); + } + } else { + $terms[] = get_term_by( 'slug', $default, $taxonomy ); + } + } + + if ( is_array( $terms ) ) { + + $links = array(); + foreach ( $terms as $term ) { + $link = get_edit_term_link( $term->term_id, $taxonomy ); + $links[] = '' . esc_html( $term->name ) . ''; + } + // Then loop and output. + echo '
            '; + echo implode( ', ', $links ); + echo '
            '; + } + } +} + +class CMB2_Display_File extends CMB2_Field_Display { + /** + * Display file value. + * + * @since 2.2.2 + */ + protected function _display() { + if ( empty( $this->value ) ) { + return; + } + + $this->value = esc_url_raw( $this->value ); + + $types = new CMB2_Types( $this->field ); + $type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_File_Base' ); + + $id = $this->field->get_field_clone( array( + 'id' => $this->field->_id() . '_id', + ) )->escaped_value( 'absint' ); + + $this->file_output( $this->value, $id, $type ); + } + + protected function file_output( $url_value, $id, CMB2_Type_File_Base $field_type ) { + // If there is no ID saved yet, try to get it from the url. + if ( $url_value && ! $id ) { + $id = CMB2_Utils::image_id_from_url( esc_url_raw( $url_value ) ); + } + + if ( $field_type->is_valid_img_ext( $url_value ) ) { + $img_size = $this->field->args( 'preview_size' ); + + if ( $id ) { + $image = wp_get_attachment_image( $id, $img_size, null, array( + 'class' => 'cmb-image-display', + ) ); + } else { + $size = is_array( $img_size ) ? $img_size[0] : 200; + $image = ''; + } + + echo $image; + + } else { + + printf( '
            %1$s %3$s
            ', + esc_html( $field_type->_text( 'file_text', esc_html__( 'File:', 'cmb2' ) ) ), + $url_value, + CMB2_Utils::get_file_name_from_path( $url_value ) + ); + + } + } +} + +class CMB2_Display_File_List extends CMB2_Display_File { + /** + * Display file_list value. + * + * @since 2.2.2 + */ + protected function _display() { + if ( empty( $this->value ) || ! is_array( $this->value ) ) { + return; + } + + $types = new CMB2_Types( $this->field ); + $type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_File_Base' ); + + echo '
              '; + foreach ( $this->value as $id => $fullurl ) { + echo '
            • ', $this->file_output( esc_url_raw( $fullurl ), $id, $type ), '
            • '; + } + echo '
            '; + } +} + +class CMB2_Display_oEmbed extends CMB2_Field_Display { + /** + * Display oembed value. + * + * @since 2.2.2 + */ + protected function _display() { + if ( ! $this->value ) { + return; + } + + cmb2_do_oembed( array( + 'url' => $this->value, + 'object_id' => $this->field->object_id, + 'object_type' => $this->field->object_type, + 'oembed_args' => array( + 'width' => '300', + ), + 'field_id' => $this->field->id(), + ) ); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Hookup_Base.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Hookup_Base.php new file mode 100755 index 00000000..7a847819 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Hookup_Base.php @@ -0,0 +1,105 @@ +cmb = $cmb; + $this->object_type = $this->cmb->mb_object_type(); + } + + abstract public function universal_hooks(); + + /** + * Ensures WordPress hook only gets fired once per object. + * + * @since 2.0.0 + * @param string $action The name of the filter to hook the $hook callback to. + * @param callback $hook The callback to be run when the filter is applied. + * @param integer $priority Order the functions are executed. + * @param int $accepted_args The number of arguments the function accepts. + */ + public function once( $action, $hook, $priority = 10, $accepted_args = 1 ) { + static $hooks_completed = array(); + + $args = func_get_args(); + + // Get object hash.. This bypasses issues with serializing closures. + if ( is_object( $hook ) ) { + $args[1] = spl_object_hash( $args[1] ); + } elseif ( is_array( $hook ) && is_object( $hook[0] ) ) { + $args[1][0] = spl_object_hash( $hook[0] ); + } + + $key = md5( serialize( $args ) ); + + if ( ! isset( $hooks_completed[ $key ] ) ) { + $hooks_completed[ $key ] = 1; + add_filter( $action, $hook, $priority, $accepted_args ); + } + } + + /** + * Magic getter for our object. + * + * @param string $field Property to return. + * @throws Exception Throws an exception if the field is invalid. + * @return mixed + */ + public function __get( $field ) { + switch ( $field ) { + case 'object_type': + case 'cmb': + return $this->{$field}; + default: + throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) ); + } + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_JS.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_JS.php new file mode 100755 index 00000000..ff4e2eea --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_JS.php @@ -0,0 +1,245 @@ + 'jquery', + ); + + /** + * Array of CMB2 fields model data for JS. + * + * @var array + * @since 2.4.0 + */ + protected static $fields = array(); + + /** + * Add a dependency to the array of CMB2 JS dependencies + * + * @since 2.0.7 + * @param array|string $dependencies Array (or string) of dependencies to add. + */ + public static function add_dependencies( $dependencies ) { + foreach ( (array) $dependencies as $dependency ) { + self::$dependencies[ $dependency ] = $dependency; + } + } + + /** + * Add field model data to the array for JS. + * + * @since 2.4.0 + * + * @param CMB2_Field $field Field object. + */ + public static function add_field_data( CMB2_Field $field ) { + $hash = $field->hash_id(); + if ( ! isset( self::$fields[ $hash ] ) ) { + self::$fields[ $hash ] = $field->js_data(); + } + } + + /** + * Enqueue the CMB2 JS + * + * @since 2.0.7 + */ + public static function enqueue() { + // Filter required script dependencies. + $dependencies = self::$dependencies = apply_filters( 'cmb2_script_dependencies', self::$dependencies ); + + // Only use minified files if SCRIPT_DEBUG is off. + $debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG; + + $min = $debug ? '' : '.min'; + + // if colorpicker. + if ( isset( $dependencies['wp-color-picker'] ) ) { + if ( ! is_admin() ) { + self::colorpicker_frontend(); + } + + if ( isset( $dependencies['wp-color-picker-alpha'] ) ) { + self::register_colorpicker_alpha(); + } + } + + // if file/file_list. + if ( isset( $dependencies['media-editor'] ) ) { + wp_enqueue_media(); + CMB2_Type_File_Base::output_js_underscore_templates(); + } + + // if timepicker. + if ( isset( $dependencies['jquery-ui-datetimepicker'] ) ) { + self::register_datetimepicker(); + } + + // if cmb2-wysiwyg. + $enqueue_wysiwyg = isset( $dependencies['cmb2-wysiwyg'] ) && $debug; + unset( $dependencies['cmb2-wysiwyg'] ); + + // Enqueue cmb JS. + wp_enqueue_script( self::$handle, CMB2_Utils::url( "js/cmb2{$min}.js" ), $dependencies, CMB2_VERSION, true ); + + // if SCRIPT_DEBUG, we need to enqueue separately. + if ( $enqueue_wysiwyg ) { + wp_enqueue_script( 'cmb2-wysiwyg', CMB2_Utils::url( 'js/cmb2-wysiwyg.js' ), array( 'jquery', 'wp-util' ), CMB2_VERSION ); + } + + self::localize( $debug ); + + do_action( 'cmb2_footer_enqueue' ); + } + + /** + * Register or enqueue the wp-color-picker-alpha script. + * + * @since 2.2.7 + * + * @param boolean $enqueue Whether or not to enqueue. + * + * @return void + */ + public static function register_colorpicker_alpha( $enqueue = false ) { + // Only use minified files if SCRIPT_DEBUG is off. + $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + $func = $enqueue ? 'wp_enqueue_script' : 'wp_register_script'; + $func( 'wp-color-picker-alpha', CMB2_Utils::url( "js/wp-color-picker-alpha{$min}.js" ), array( 'wp-color-picker' ), '2.1.3' ); + } + + /** + * Register or enqueue the jquery-ui-datetimepicker script. + * + * @since 2.2.7 + * + * @param boolean $enqueue Whether or not to enqueue. + * + * @return void + */ + public static function register_datetimepicker( $enqueue = false ) { + $func = $enqueue ? 'wp_enqueue_script' : 'wp_register_script'; + $func( 'jquery-ui-datetimepicker', CMB2_Utils::url( 'js/jquery-ui-timepicker-addon.min.js' ), array( 'jquery-ui-slider' ), '1.5.0' ); + } + + /** + * We need to register colorpicker on the front-end + * + * @since 2.0.7 + */ + protected static function colorpicker_frontend() { + wp_register_script( 'iris', admin_url( 'js/iris.min.js' ), array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), CMB2_VERSION ); + wp_register_script( 'wp-color-picker', admin_url( 'js/color-picker.min.js' ), array( 'iris' ), CMB2_VERSION ); + wp_localize_script( 'wp-color-picker', 'wpColorPickerL10n', array( + 'clear' => esc_html__( 'Clear', 'cmb2' ), + 'defaultString' => esc_html__( 'Default', 'cmb2' ), + 'pick' => esc_html__( 'Select Color', 'cmb2' ), + 'current' => esc_html__( 'Current Color', 'cmb2' ), + ) ); + } + + /** + * Localize the php variables for CMB2 JS + * + * @since 2.0.7 + * + * @param mixed $debug Whether or not we are debugging. + */ + protected static function localize( $debug ) { + static $localized = false; + if ( $localized ) { + return; + } + + $localized = true; + $l10n = array( + 'fields' => self::$fields, + 'ajax_nonce' => wp_create_nonce( 'ajax_nonce' ), + 'ajaxurl' => admin_url( '/admin-ajax.php' ), + 'script_debug' => $debug, + 'up_arrow_class' => 'dashicons dashicons-arrow-up-alt2', + 'down_arrow_class' => 'dashicons dashicons-arrow-down-alt2', + 'user_can_richedit' => user_can_richedit(), + 'defaults' => array( + 'code_editor' => false, + 'color_picker' => false, + 'date_picker' => array( + 'changeMonth' => true, + 'changeYear' => true, + 'dateFormat' => _x( 'mm/dd/yy', 'Valid formatDate string for jquery-ui datepicker', 'cmb2' ), + 'dayNames' => explode( ',', esc_html__( 'Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday', 'cmb2' ) ), + 'dayNamesMin' => explode( ',', esc_html__( 'Su, Mo, Tu, We, Th, Fr, Sa', 'cmb2' ) ), + 'dayNamesShort' => explode( ',', esc_html__( 'Sun, Mon, Tue, Wed, Thu, Fri, Sat', 'cmb2' ) ), + 'monthNames' => explode( ',', esc_html__( 'January, February, March, April, May, June, July, August, September, October, November, December', 'cmb2' ) ), + 'monthNamesShort' => explode( ',', esc_html__( 'Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec', 'cmb2' ) ), + 'nextText' => esc_html__( 'Next', 'cmb2' ), + 'prevText' => esc_html__( 'Prev', 'cmb2' ), + 'currentText' => esc_html__( 'Today', 'cmb2' ), + 'closeText' => esc_html__( 'Done', 'cmb2' ), + 'clearText' => esc_html__( 'Clear', 'cmb2' ), + ), + 'time_picker' => array( + 'timeOnlyTitle' => esc_html__( 'Choose Time', 'cmb2' ), + 'timeText' => esc_html__( 'Time', 'cmb2' ), + 'hourText' => esc_html__( 'Hour', 'cmb2' ), + 'minuteText' => esc_html__( 'Minute', 'cmb2' ), + 'secondText' => esc_html__( 'Second', 'cmb2' ), + 'currentText' => esc_html__( 'Now', 'cmb2' ), + 'closeText' => esc_html__( 'Done', 'cmb2' ), + 'timeFormat' => _x( 'hh:mm TT', 'Valid formatting string, as per http://trentrichardson.com/examples/timepicker/', 'cmb2' ), + 'controlType' => 'select', + 'stepMinute' => 5, + ), + ), + 'strings' => array( + 'upload_file' => esc_html__( 'Use this file', 'cmb2' ), + 'upload_files' => esc_html__( 'Use these files', 'cmb2' ), + 'remove_image' => esc_html__( 'Remove Image', 'cmb2' ), + 'remove_file' => esc_html__( 'Remove', 'cmb2' ), + 'file' => esc_html__( 'File:', 'cmb2' ), + 'download' => esc_html__( 'Download', 'cmb2' ), + 'check_toggle' => esc_html__( 'Select / Deselect All', 'cmb2' ), + ), + ); + + if ( isset( self::$dependencies['code-editor'] ) && function_exists( 'wp_enqueue_code_editor' ) ) { + $l10n['defaults']['code_editor'] = wp_enqueue_code_editor( array( + 'type' => 'text/html', + ) ); + } + + wp_localize_script( self::$handle, self::$js_variable, apply_filters( 'cmb2_localized_data', $l10n ) ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Options.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Options.php new file mode 100755 index 00000000..3aa18ce2 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Options.php @@ -0,0 +1,250 @@ +key = ! empty( $option_key ) ? $option_key : ''; + } + + /** + * Delete the option from the db + * + * @since 2.0.0 + * @return mixed Delete success or failure + */ + public function delete_option() { + $deleted = $this->key ? delete_option( $this->key ) : true; + $this->options = $deleted ? array() : $this->options; + return $this->options; + } + + /** + * Removes an option from an option array + * + * @since 1.0.1 + * @param string $field_id Option array field key. + * @param bool $resave Whether or not to resave. + * @return array Modified options + */ + public function remove( $field_id, $resave = false ) { + + $this->get_options(); + + if ( isset( $this->options[ $field_id ] ) ) { + unset( $this->options[ $field_id ] ); + } + + if ( $resave ) { + $this->set(); + } + + return $this->options; + } + + /** + * Retrieves an option from an option array + * + * @since 1.0.1 + * @param string $field_id Option array field key. + * @param mixed $default Fallback value for the option. + * @return array Requested field or default + */ + public function get( $field_id, $default = false ) { + $opts = $this->get_options(); + + if ( 'all' == $field_id ) { + return $opts; + } elseif ( array_key_exists( $field_id, $opts ) ) { + return false !== $opts[ $field_id ] ? $opts[ $field_id ] : $default; + } + + return $default; + } + + /** + * Updates Option data + * + * @since 1.0.1 + * @param string $field_id Option array field key. + * @param mixed $value Value to update data with. + * @param bool $resave Whether to re-save the data. + * @param bool $single Whether data should not be an array. + * @return boolean Return status of update. + */ + public function update( $field_id, $value = '', $resave = false, $single = true ) { + $this->get_options(); + + if ( true !== $field_id ) { + + if ( ! $single ) { + // If multiple, add to array. + $this->options[ $field_id ][] = $value; + } else { + $this->options[ $field_id ] = $value; + } + } + + if ( $resave || true === $field_id ) { + return $this->set(); + } + + return true; + } + + /** + * Saves the option array + * Needs to be run after finished using remove/update_option + * + * @uses apply_filters() Calls 'cmb2_override_option_save_{$this->key}' hook + * to allow overwriting the option value to be stored. + * + * @since 1.0.1 + * @param array $options Optional options to override. + * @return bool Success/Failure + */ + public function set( $options = array() ) { + if ( ! empty( $options ) || empty( $options ) && empty( $this->key ) ) { + $this->options = $options; + } + + $this->options = wp_unslash( $this->options ); // get rid of those evil magic quotes. + + if ( empty( $this->key ) ) { + return false; + } + + $test_save = apply_filters( "cmb2_override_option_save_{$this->key}", 'cmb2_no_override_option_save', $this->options, $this ); + + if ( 'cmb2_no_override_option_save' !== $test_save ) { + // If override, do not proceed to update the option, just return result. + return $test_save; + } + + /** + * Whether to auto-load the option when WordPress starts up. + * + * The dynamic portion of the hook name, $this->key, refers to the option key. + * + * @since 2.4.0 + * + * @param bool $autoload Whether to load the option when WordPress starts up. + * @param CMB2_Option $cmb_option This object. + */ + $autoload = apply_filters( "cmb2_should_autoload_{$this->key}", true, $this ); + + return update_option( + $this->key, + $this->options, + ! $autoload || 'no' === $autoload ? false : true + ); + } + + /** + * Retrieve option value based on name of option. + * + * @uses apply_filters() Calls 'cmb2_override_option_get_{$this->key}' hook to allow + * overwriting the option value to be retrieved. + * + * @since 1.0.1 + * @param mixed $default Optional. Default value to return if the option does not exist. + * @return mixed Value set for the option. + */ + public function get_options( $default = null ) { + if ( empty( $this->options ) && ! empty( $this->key ) ) { + + $test_get = apply_filters( "cmb2_override_option_get_{$this->key}", 'cmb2_no_override_option_get', $default, $this ); + + if ( 'cmb2_no_override_option_get' !== $test_get ) { + $this->options = $test_get; + } else { + // If no override, get the option. + $this->options = get_option( $this->key, $default ); + } + } + + $this->options = (array) $this->options; + + return $this->options; + } + + /** + * Magic getter for our object. + * + * @since 2.6.0 + * + * @param string $field Requested property. + * @throws Exception Throws an exception if the field is invalid. + * @return mixed + */ + public function __get( $field ) { + switch ( $field ) { + case 'options': + case 'key': + return $this->{$field}; + default: + throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) ); + } + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Options_Hookup.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Options_Hookup.php new file mode 100755 index 00000000..8eacca31 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Options_Hookup.php @@ -0,0 +1,360 @@ +cmb = $cmb; + $this->option_key = $option_key; + } + + public function hooks() { + if ( empty( $this->option_key ) ) { + return; + } + + if ( ! $this->cmb->prop( 'autoload', true ) ) { + // Disable option autoload if requested. + add_filter( "cmb2_should_autoload_{$this->option_key}", '__return_false' ); + } + + /** + * For WP < 4.7. Ensure the register_setting function exists. + */ + if ( ! CMB2_Utils::wp_at_least( '4.7' ) && ! function_exists( 'register_setting' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + // Register setting to cmb2 group. + register_setting( 'cmb2', $this->option_key ); + + // Handle saving the data. + add_action( 'admin_post_' . $this->option_key, array( $this, 'save_options' ) ); + + // Optionally network_admin_menu. + $hook = $this->cmb->prop( 'admin_menu_hook' ); + + // Hook in to add our menu. + add_action( $hook, array( $this, 'options_page_menu_hooks' ) ); + + // If in the network admin, need to use get/update_site_option. + if ( 'network_admin_menu' === $hook ) { + // Override CMB's getter. + add_filter( "cmb2_override_option_get_{$this->option_key}", array( $this, 'network_get_override' ), 10, 2 ); + // Override CMB's setter. + add_filter( "cmb2_override_option_save_{$this->option_key}", array( $this, 'network_update_override' ), 10, 2 ); + } + } + + /** + * Hook up our admin menu item and admin page. + * + * @since 2.2.5 + * + * @return void + */ + public function options_page_menu_hooks() { + $parent_slug = $this->cmb->prop( 'parent_slug' ); + $title = $this->cmb->prop( 'title' ); + $menu_title = $this->cmb->prop( 'menu_title', $title ); + $capability = $this->cmb->prop( 'capability' ); + $callback = array( $this, 'options_page_output' ); + + if ( $parent_slug ) { + $page_hook = add_submenu_page( + $parent_slug, + $title, + $menu_title, + $capability, + $this->option_key, + $callback + ); + } else { + $page_hook = add_menu_page( + $title, + $menu_title, + $capability, + $this->option_key, + $callback, + $this->cmb->prop( 'icon_url' ), + $this->cmb->prop( 'position' ) + ); + } + + if ( $this->cmb->prop( 'cmb_styles' ) ) { + // Include CMB CSS in the head to avoid FOUC. + add_action( "admin_print_styles-{$page_hook}", array( 'CMB2_hookup', 'enqueue_cmb_css' ) ); + } + + $this->maybe_register_message(); + } + + /** + * If there is a message callback, let it determine how to register the message, + * else add a settings message if on this settings page. + * + * @since 2.2.6 + * + * @return void + */ + public function maybe_register_message() { + $is_options_page = self::is_page( $this->option_key ); + $should_notify = ! $this->cmb->prop( 'disable_settings_errors' ) && isset( $_GET['settings-updated'] ) && $is_options_page; + $is_updated = $should_notify && 'true' === $_GET['settings-updated']; + $setting = "{$this->option_key}-notices"; + $code = ''; + $message = esc_html__( 'Nothing to update.', 'cmb2' ); + $type = 'notice-warning'; + + if ( $is_updated ) { + $message = esc_html__( 'Settings updated.', 'cmb2' ); + $type = 'updated'; + } + + // Check if parameter has registered a callback. + if ( $cb = $this->cmb->maybe_callback( 'message_cb' ) ) { + + /** + * The 'message_cb' callback will receive the following parameters. + * Unless there are other reasons for notifications, the callback should only + * `add_settings_error()` if `$args['should_notify']` is truthy. + * + * @param CMB2 $cmb The CMB2 object. + * @param array $args { + * An array of message arguments + * + * @type bool $is_options_page Whether current page is this options page. + * @type bool $should_notify Whether options were saved and we should be notified. + * @type bool $is_updated Whether options were updated with save (or stayed the same). + * @type string $setting For add_settings_error(), Slug title of the setting to which + * this error applies. + * @type string $code For add_settings_error(), Slug-name to identify the error. + * Used as part of 'id' attribute in HTML output. + * @type string $message For add_settings_error(), The formatted message text to display + * to the user (will be shown inside styled `
            ` and `

            ` tags). + * Will be 'Settings updated.' if $is_updated is true, else 'Nothing to update.' + * @type string $type For add_settings_error(), Message type, controls HTML class. + * Accepts 'error', 'updated', '', 'notice-warning', etc. + * Will be 'updated' if $is_updated is true, else 'notice-warning'. + * } + */ + $args = compact( 'is_options_page', 'should_notify', 'is_updated', 'setting', 'code', 'message', 'type' ); + + $this->cmb->do_callback( $cb, $args ); + + } elseif ( $should_notify ) { + + add_settings_error( $setting, $code, $message, $type ); + } + } + + /** + * Display options-page output. To override, set 'display_cb' box property. + * + * @since 2.2.5 + */ + public function options_page_output() { + $this->maybe_output_settings_notices(); + + $callback = $this->cmb->prop( 'display_cb' ); + if ( is_callable( $callback ) ) { + return call_user_func( $callback, $this ); + } + + $tabs = $this->get_tab_group_tabs(); + ?> +

            + cmb->prop( 'title' ) ) : ?> +

            cmb->prop( 'title' ) ); ?>

            + + + + +
            + + options_page_metabox(); ?> + cmb->prop( 'save_button' ) ), 'primary', 'submit-cmb' ); ?> +
            +
            + option_key}-notices" ); + } + } + + /** + * Gets navigation tabs array for CMB2 options pages which share the + * same tab_group property. + * + * @since 2.4.0 + * @return array Array of tab information ($option_key => $tab_title) + */ + public function get_tab_group_tabs() { + $tab_group = $this->cmb->prop( 'tab_group' ); + $tabs = array(); + + if ( $tab_group ) { + $boxes = CMB2_Boxes::get_by( 'tab_group', $tab_group ); + + foreach ( $boxes as $cmb_id => $cmb ) { + $option_key = $cmb->options_page_keys(); + + // Must have an option key, must be an options page box. + if ( ! isset( $option_key[0] ) || 'options-page' !== $cmb->mb_object_type() ) { + continue; + } + + $tabs[ $option_key[0] ] = $cmb->prop( 'tab_title', $cmb->prop( 'title' ) ); + } + } + + return $tabs; + } + + /** + * Display metaboxes for an options-page object. + * + * @since 2.2.5 + */ + public function options_page_metabox() { + $this->show_form_for_type( 'options-page' ); + } + + /** + * Save data from options page, then redirects back. + * + * @since 2.2.5 + * @return void + */ + public function save_options() { + $url = wp_get_referer(); + if ( ! $url ) { + $url = admin_url(); + } + + if ( + $this->can_save( 'options-page' ) + // check params. + && isset( $_POST['submit-cmb'], $_POST['action'] ) + && $this->option_key === $_POST['action'] + ) { + + $updated = $this->cmb + ->save_fields( $this->option_key, $this->cmb->object_type(), $_POST ) + ->was_updated(); // Will be false if no values were changed/updated. + + $url = add_query_arg( 'settings-updated', $updated ? 'true' : 'false', $url ); + } + + wp_safe_redirect( esc_url_raw( $url ), 303 /* WP_Http::SEE_OTHER */ ); + exit; + } + + /** + * Replaces get_option with get_site_option. + * + * @since 2.2.5 + * + * @param mixed $test Not used. + * @param mixed $default Default value to use. + * @return mixed Value set for the network option. + */ + public function network_get_override( $test, $default = false ) { + return get_site_option( $this->option_key, $default ); + } + + /** + * Replaces update_option with update_site_option. + * + * @since 2.2.5 + * + * @param mixed $test Not used. + * @param mixed $option_value Value to use. + * @return bool Success/Failure + */ + public function network_update_override( $test, $option_value ) { + return update_site_option( $this->option_key, $option_value ); + } + + /** + * Determines if given page slug matches the 'page' GET query variable. + * + * @since 2.4.0 + * + * @param string $page Page slug. + * @return boolean + */ + public static function is_page( $page ) { + return isset( $_GET['page'] ) && $page === $_GET['page']; + } + + /** + * Magic getter for our object. + * + * @param string $field Property to retrieve. + * + * @throws Exception Throws an exception if the field is invalid. + * @return mixed + */ + public function __get( $field ) { + switch ( $field ) { + case 'object_type': + case 'option_key': + case 'cmb': + return $this->{$field}; + default: + throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) ); + } + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Sanitize.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Sanitize.php new file mode 100755 index 00000000..b5ef8567 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Sanitize.php @@ -0,0 +1,587 @@ +field = $field; + $this->value = $value; + } + + /** + * Catchall method if field's 'sanitization_cb' is NOT defined, + * or field type does not have a corresponding validation method. + * + * @since 1.0.0 + * + * @param string $name Non-existent method name. + * @param array $arguments All arguments passed to the method. + * @return mixed + */ + public function __call( $name, $arguments ) { + return $this->default_sanitization(); + } + + /** + * Default fallback sanitization method. Applies filters. + * + * @since 1.0.2 + */ + public function default_sanitization() { + $field_type = $this->field->type(); + + /** + * This exists for back-compatibility, but validation + * is not what happens here. + * + * @deprecated See documentation for "cmb2_sanitize_{$field_type}". + */ + if ( function_exists( 'apply_filters_deprecated' ) ) { + $override_value = apply_filters_deprecated( "cmb2_validate_{$field_type}", array( null, $this->value, $this->field->object_id, $this->field->args(), $this ), '2.0.0', "cmb2_sanitize_{$field_type}" ); + } else { + $override_value = apply_filters( "cmb2_validate_{$field_type}", null, $this->value, $this->field->object_id, $this->field->args(), $this ); + } + + if ( null !== $override_value ) { + return $override_value; + } + + $sanitized_value = ''; + switch ( $field_type ) { + case 'wysiwyg': + case 'textarea_small': + case 'oembed': + $sanitized_value = $this->textarea(); + break; + case 'taxonomy_select': + case 'taxonomy_radio': + case 'taxonomy_radio_inline': + case 'taxonomy_radio_hierarchical': + case 'taxonomy_multicheck': + case 'taxonomy_multicheck_hierarchical': + case 'taxonomy_multicheck_inline': + $sanitized_value = $this->taxonomy(); + break; + case 'multicheck': + case 'multicheck_inline': + case 'file_list': + case 'group': + // no filtering + $sanitized_value = $this->value; + break; + default: + // Handle repeatable fields array + // We'll fallback to 'sanitize_text_field' + $sanitized_value = $this->_default_sanitization(); + break; + } + + return $this->_is_empty_array( $sanitized_value ) ? '' : $sanitized_value; + } + + /** + * Default sanitization method, sanitize_text_field. Checks if value is array. + * + * @since 2.2.4 + * @return mixed Sanitized value. + */ + protected function _default_sanitization() { + // Handle repeatable fields array. + return is_array( $this->value ) ? array_map( 'sanitize_text_field', $this->value ) : sanitize_text_field( $this->value ); + } + + /** + * Sets the object terms to the object (if not options-page) and optionally returns the sanitized term values. + * + * @since 2.2.4 + * @return mixed Blank value, or sanitized term values if "cmb2_return_taxonomy_values_{$cmb_id}" is true. + */ + public function taxonomy() { + $sanitized_value = ''; + + if ( ! $this->field->args( 'taxonomy' ) ) { + CMB2_Utils::log_if_debug( __METHOD__, __LINE__, "{$this->field->type()} {$this->field->_id()} is missing the 'taxonomy' parameter." ); + } else { + + if ( in_array( $this->field->object_type, array( 'options-page', 'term' ), true ) ) { + $return_values = true; + } else { + wp_set_object_terms( $this->field->object_id, $this->value, $this->field->args( 'taxonomy' ) ); + $return_values = false; + } + + $cmb_id = $this->field->cmb_id; + + /** + * Filter whether 'taxonomy_*' fields should return their value when being sanitized. + * + * By default, these fields do not return a value as we do not want them stored to meta + * (as they are stored as terms). This allows overriding that and is used by CMB2::get_sanitized_values(). + * + * The dynamic portion of the hook, $cmb_id, refers to the this field's CMB2 box id. + * + * @since 2.2.4 + * + * @param bool $return_values By default, this is only true for 'options-page' boxes. To enable: + * `add_filter( "cmb2_return_taxonomy_values_{$cmb_id}", '__return_true' );` + * @param CMB2_Sanitize $sanitizer This object. + */ + if ( apply_filters( "cmb2_return_taxonomy_values_{$cmb_id}", $return_values, $this ) ) { + $sanitized_value = $this->_default_sanitization(); + } + } + + return $sanitized_value; + } + + /** + * Simple checkbox validation + * + * @since 1.0.1 + * @return string|false 'on' or false + */ + public function checkbox() { + return $this->value === 'on' ? 'on' : false; + } + + /** + * Validate url in a meta value. + * + * @since 1.0.1 + * @return string Empty string or escaped url + */ + public function text_url() { + $protocols = $this->field->args( 'protocols' ); + // for repeatable. + if ( is_array( $this->value ) ) { + foreach ( $this->value as $key => $val ) { + $this->value[ $key ] = $val ? esc_url_raw( $val, $protocols ) : $this->field->get_default(); + } + } else { + $this->value = $this->value ? esc_url_raw( $this->value, $protocols ) : $this->field->get_default(); + } + + return $this->value; + } + + public function colorpicker() { + // for repeatable. + if ( is_array( $this->value ) ) { + $check = $this->value; + $this->value = array(); + foreach ( $check as $key => $val ) { + if ( $val && '#' != $val ) { + $this->value[ $key ] = esc_attr( $val ); + } + } + } else { + $this->value = ! $this->value || '#' == $this->value ? '' : esc_attr( $this->value ); + } + return $this->value; + } + + /** + * Validate email in a meta value + * + * @since 1.0.1 + * @return string Empty string or sanitized email + */ + public function text_email() { + // for repeatable. + if ( is_array( $this->value ) ) { + foreach ( $this->value as $key => $val ) { + $val = trim( $val ); + $this->value[ $key ] = is_email( $val ) ? $val : ''; + } + } else { + $this->value = trim( $this->value ); + $this->value = is_email( $this->value ) ? $this->value : ''; + } + + return $this->value; + } + + /** + * Validate money in a meta value + * + * @since 1.0.1 + * @return string Empty string or sanitized money value + */ + public function text_money() { + if ( ! $this->value ) { + return ''; + } + + global $wp_locale; + + $search = array( $wp_locale->number_format['thousands_sep'], $wp_locale->number_format['decimal_point'] ); + $replace = array( '', '.' ); + + // Strip slashes. Example: 2\'180.00. + // See https://github.com/CMB2/CMB2/issues/1014. + $this->value = wp_unslash( $this->value ); + + // for repeatable. + if ( is_array( $this->value ) ) { + foreach ( $this->value as $key => $val ) { + if ( $val ) { + $this->value[ $key ] = number_format_i18n( (float) str_ireplace( $search, $replace, $val ), 2 ); + } + } + } else { + $this->value = number_format_i18n( (float) str_ireplace( $search, $replace, $this->value ), 2 ); + } + + return $this->value; + } + + /** + * Converts text date to timestamp + * + * @since 1.0.2 + * @return string Timestring + */ + public function text_date_timestamp() { + // date_create_from_format if there is a slash in the value. + $this->value = wp_unslash( $this->value ); + + return is_array( $this->value ) + ? array_map( array( $this->field, 'get_timestamp_from_value' ), $this->value ) + : $this->field->get_timestamp_from_value( $this->value ); + } + + /** + * Datetime to timestamp + * + * @since 1.0.1 + * + * @param bool $repeat Whether or not to repeat. + * @return string|array Timestring + */ + public function text_datetime_timestamp( $repeat = false ) { + // date_create_from_format if there is a slash in the value. + $this->value = wp_unslash( $this->value ); + + $test = is_array( $this->value ) ? array_filter( $this->value ) : ''; + if ( empty( $test ) ) { + return ''; + } + + $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ); + if ( false !== $repeat_value ) { + return $repeat_value; + } + + if ( isset( $this->value['date'], $this->value['time'] ) ) { + $this->value = $this->field->get_timestamp_from_value( $this->value['date'] . ' ' . $this->value['time'] ); + } + + if ( $tz_offset = $this->field->field_timezone_offset() ) { + $this->value += (int) $tz_offset; + } + + return $this->value; + } + + /** + * Datetime to timestamp with timezone + * + * @since 1.0.1 + * + * @param bool $repeat Whether or not to repeat. + * @return string Timestring + */ + public function text_datetime_timestamp_timezone( $repeat = false ) { + static $utc_values = array(); + + $test = is_array( $this->value ) ? array_filter( $this->value ) : ''; + if ( empty( $test ) ) { + return ''; + } + + // date_create_from_format if there is a slash in the value. + $this->value = wp_unslash( $this->value ); + + $utc_key = $this->field->_id() . '_utc'; + + $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ); + if ( false !== $repeat_value ) { + if ( ! empty( $utc_values[ $utc_key ] ) ) { + $this->_save_utc_value( $utc_key, $utc_values[ $utc_key ] ); + unset( $utc_values[ $utc_key ] ); + } + + return $repeat_value; + } + + $tzstring = null; + + if ( is_array( $this->value ) && array_key_exists( 'timezone', $this->value ) ) { + $tzstring = $this->value['timezone']; + } + + if ( empty( $tzstring ) ) { + $tzstring = CMB2_Utils::timezone_string(); + } + + $offset = CMB2_Utils::timezone_offset( $tzstring ); + + if ( 'UTC' === substr( $tzstring, 0, 3 ) ) { + $tzstring = timezone_name_from_abbr( '', $offset, 0 ); + /** + * The timezone_name_from_abbr() returns false if not found based on offset. + * Since there are currently some invalid timezones in wp_timezone_dropdown(), + * fallback to an offset of 0 (UTC+0) + * https://core.trac.wordpress.org/ticket/29205 + */ + $tzstring = false !== $tzstring ? $tzstring : timezone_name_from_abbr( '', 0, 0 ); + } + + $full_format = $this->field->args['date_format'] . ' ' . $this->field->args['time_format']; + $full_date = $this->value['date'] . ' ' . $this->value['time']; + + try { + + $datetime = date_create_from_format( $full_format, $full_date ); + + if ( ! is_object( $datetime ) ) { + $this->value = $utc_stamp = ''; + } else { + $datetime->setTimezone( new DateTimeZone( $tzstring ) ); + $utc_stamp = date_timestamp_get( $datetime ) - $offset; + $this->value = serialize( $datetime ); + } + + if ( $this->field->group ) { + $this->value = array( + 'supporting_field_value' => $utc_stamp, + 'supporting_field_id' => $utc_key, + 'value' => $this->value, + ); + } else { + // Save the utc timestamp supporting field. + if ( $repeat ) { + $utc_values[ $utc_key ][] = $utc_stamp; + } else { + $this->_save_utc_value( $utc_key, $utc_stamp ); + } + } + } catch ( Exception $e ) { + $this->value = ''; + CMB2_Utils::log_if_debug( __METHOD__, __LINE__, $e->getMessage() ); + } + + return $this->value; + } + + /** + * Sanitize textareas and wysiwyg fields + * + * @since 1.0.1 + * @return string Sanitized data + */ + public function textarea() { + return is_array( $this->value ) ? array_map( 'wp_kses_post', $this->value ) : wp_kses_post( $this->value ); + } + + /** + * Sanitize code textareas + * + * @since 1.0.2 + * + * @param bool $repeat Whether or not to repeat. + * @return string Sanitized data + */ + public function textarea_code( $repeat = false ) { + $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ); + if ( false !== $repeat_value ) { + return $repeat_value; + } + + return htmlspecialchars_decode( stripslashes( $this->value ) ); + } + + /** + * Handles saving of attachment post ID and sanitizing file url + * + * @since 1.1.0 + * @return string Sanitized url + */ + public function file() { + $file_id_key = $this->field->_id() . '_id'; + + if ( $this->field->group ) { + // Return an array with url/id if saving a group field. + $this->value = $this->_get_group_file_value_array( $file_id_key ); + } else { + $this->_save_file_id_value( $file_id_key ); + $this->text_url(); + } + + return $this->value; + } + + /** + * Gets the values for the `file` field type from the data being saved. + * + * @since 2.2.0 + * + * @param mixed $id_key ID key to use. + * @return array + */ + public function _get_group_file_value_array( $id_key ) { + $alldata = $this->field->group->data_to_save; + $base_id = $this->field->group->_id(); + $i = $this->field->group->index; + + // Check group $alldata data. + $id_val = isset( $alldata[ $base_id ][ $i ][ $id_key ] ) + ? absint( $alldata[ $base_id ][ $i ][ $id_key ] ) + : ''; + + // We don't want to save 0 to the DB for file fields. + if ( 0 === $id_val ) { + $id_val = ''; + } + + return array( + 'value' => $this->text_url(), + 'supporting_field_value' => $id_val, + 'supporting_field_id' => $id_key, + ); + } + + /** + * Peforms saving of `file` attachement's ID + * + * @since 1.1.0 + * + * @param mixed $file_id_key ID key to use. + * @return mixed + */ + public function _save_file_id_value( $file_id_key ) { + $id_field = $this->_new_supporting_field( $file_id_key ); + + // Check standard data_to_save data. + $id_val = isset( $this->field->data_to_save[ $file_id_key ] ) + ? $this->field->data_to_save[ $file_id_key ] + : null; + + // If there is no ID saved yet, try to get it from the url. + if ( $this->value && ! $id_val ) { + $id_val = CMB2_Utils::image_id_from_url( $this->value ); + + // If there is an ID but user emptied the input value, remove the ID. + } elseif ( ! $this->value && $id_val ) { + $id_val = null; + } + + return $id_field->save_field( $id_val ); + } + + /** + * Peforms saving of `text_datetime_timestamp_timezone` utc timestamp + * + * @since 2.2.0 + * + * @param mixed $utc_key UTC key. + * @param mixed $utc_stamp UTC timestamp. + * @return mixed + */ + public function _save_utc_value( $utc_key, $utc_stamp ) { + return $this->_new_supporting_field( $utc_key )->save_field( $utc_stamp ); + } + + /** + * Returns a new, supporting, CMB2_Field object based on a new field id. + * + * @since 2.2.0 + * + * @param mixed $new_field_id New field ID. + * @return CMB2_Field + */ + public function _new_supporting_field( $new_field_id ) { + return $this->field->get_field_clone( array( + 'id' => $new_field_id, + 'sanitization_cb' => false, + ) ); + } + + /** + * If repeating, loop through and re-apply sanitization method + * + * @since 1.1.0 + * @param string $method Class method. + * @param bool $repeat Whether repeating or not. + * @return mixed Sanitized value + */ + public function _check_repeat( $method, $repeat ) { + if ( $repeat || ! $this->field->args( 'repeatable' ) ) { + return false; + } + + $values_array = $this->value; + + $new_value = array(); + foreach ( $values_array as $iterator => $this->value ) { + if ( $this->value ) { + $val = $this->$method( true ); + if ( ! empty( $val ) ) { + $new_value[] = $val; + } + } + } + + $this->value = $new_value; + + return empty( $this->value ) ? null : $this->value; + } + + /** + * Determine if passed value is an empty array + * + * @since 2.0.6 + * @param mixed $to_check Value to check. + * @return boolean Whether value is an array that's empty + */ + public function _is_empty_array( $to_check ) { + if ( is_array( $to_check ) ) { + $cleaned_up = array_filter( $to_check ); + return empty( $cleaned_up ); + } + return false; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Show_Filters.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Show_Filters.php new file mode 100755 index 00000000..5fb257e6 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Show_Filters.php @@ -0,0 +1,179 @@ +object_id() : get_the_ID(); + + if ( ! $object_id ) { + return false; + } + + // If current page id is in the included array, display the metabox. + return in_array( $object_id, (array) self::get_show_on_value( $meta_box_args ) ); + } + + /** + * Add metaboxes for an specific Page Template + * + * @since 1.0.0 + * @param bool $display To display or not. + * @param array $meta_box_args Metabox config array. + * @param CMB2 $cmb CMB2 object. + * @return bool Whether to display this metabox on the current page. + */ + public static function check_page_template( $display, $meta_box_args, $cmb ) { + + $key = self::get_show_on_key( $meta_box_args ); + if ( ! $key || 'page-template' !== $key ) { + return $display; + } + + $object_id = $cmb->object_id(); + + if ( ! $object_id || 'post' !== $cmb->object_type() ) { + return false; + } + + // Get current template. + $current_template = get_post_meta( $object_id, '_wp_page_template', true ); + + // See if there's a match. + if ( $current_template && in_array( $current_template, (array) self::get_show_on_value( $meta_box_args ) ) ) { + return true; + } + + return false; + } + + /** + * Only show options-page metaboxes on their options page (but only enforce on the admin side) + * + * @since 1.0.0 + * @param bool $display To display or not. + * @param array $meta_box_args Metabox config array. + * @return bool Whether to display this metabox on the current page. + */ + public static function check_admin_page( $display, $meta_box_args ) { + + $key = self::get_show_on_key( $meta_box_args ); + // check if this is a 'options-page' metabox. + if ( ! $key || 'options-page' !== $key ) { + return $display; + } + + // Enforce 'show_on' filter in the admin. + if ( is_admin() ) { + + // If there is no 'page' query var, our filter isn't applicable. + if ( ! isset( $_GET['page'] ) ) { + return $display; + } + + $show_on = self::get_show_on_value( $meta_box_args ); + + if ( empty( $show_on ) ) { + return false; + } + + if ( is_array( $show_on ) ) { + foreach ( $show_on as $page ) { + if ( $_GET['page'] == $page ) { + return true; + } + } + } else { + if ( $_GET['page'] == $show_on ) { + return true; + } + } + + return false; + + } + + // Allow options-page metaboxes to be displayed anywhere on the front-end. + return true; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Types.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Types.php new file mode 100755 index 00000000..aaeed6e8 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Types.php @@ -0,0 +1,662 @@ +field = $field; + } + + /** + * Default fallback. Allows rendering fields via "cmb2_render_$fieldtype" hook + * + * @since 1.0.0 + * @param string $fieldtype Non-existent field type name + * @param array $arguments All arguments passed to the method + */ + public function __call( $fieldtype, $arguments ) { + + // Check for methods to be proxied to the CMB2_Type_Base object. + if ( $exists = $this->maybe_proxy_method( $fieldtype, $arguments ) ) { + return $exists['value']; + } + + // Check for custom field type class. + if ( $object = $this->maybe_custom_field_object( $fieldtype, $arguments ) ) { + return $object->render(); + } + + /** + * Pass non-existent field types through an action. + * + * The dynamic portion of the hook name, $fieldtype, refers to the field type. + * + * @param array $field The passed in `CMB2_Field` object + * @param mixed $escaped_value The value of this field escaped. + * It defaults to `sanitize_text_field`. + * If you need the unescaped value, you can access it + * via `$field->value()` + * @param int $object_id The ID of the current object + * @param string $object_type The type of object you are working with. + * Most commonly, `post` (this applies to all post-types), + * but could also be `comment`, `user` or `options-page`. + * @param object $field_type_object This `CMB2_Types` object + */ + do_action( "cmb2_render_{$fieldtype}", $this->field, $this->field->escaped_value(), $this->field->object_id, $this->field->object_type, $this ); + } + + /** + * Render a field (and handle repeatable) + * + * @since 1.1.0 + */ + public function render() { + if ( $this->field->args( 'repeatable' ) ) { + $this->render_repeatable_field(); + } else { + $this->_render(); + } + } + + /** + * Render a field type + * + * @since 1.1.0 + */ + protected function _render() { + $this->field->peform_param_callback( 'before_field' ); + echo $this->{$this->field->type()}(); + $this->field->peform_param_callback( 'after_field' ); + } + + /** + * Proxies the method call to the CMB2_Type_Base object, if it exists, otherwise returns a default fallback value. + * + * @since 2.2.2 + * + * @param string $method Method to call on the CMB2_Type_Base object. + * @param mixed $default Default fallback value if method is not found. + * @param array $args Optional arguments to pass to proxy method. + * + * @return mixed Results from called method. + */ + protected function proxy_method( $method, $default, $args = array() ) { + if ( ! is_object( $this->type ) ) { + $this->guess_type_object( $method ); + } + + if ( is_object( $this->type ) && method_exists( $this->type, $method ) ) { + + return empty( $args ) + ? $this->type->$method() + : call_user_func_array( array( $this->type, $method ), $args ); + } + + return $default; + } + + /** + * If no CMB2_Types::$type object is initiated when a proxy method is called, it means + * it's a custom field type (which SHOULD be instantiating a Type), but let's try and + * guess the type object for them and instantiate it. + * + * @since 2.2.3 + * + * @param string $method Method attempting to be called on the CMB2_Type_Base object. + * @return bool + */ + protected function guess_type_object( $method ) { + $fieldtype = $this->field->type(); + + // Try to "guess" the Type object based on the method requested. + switch ( $method ) { + case 'select_option': + case 'list_input': + case 'list_input_checkbox': + case 'concat_items': + $this->get_new_render_type( $fieldtype, 'CMB2_Type_Select' ); + break; + case 'is_valid_img_ext': + case 'img_status_output': + case 'file_status_output': + $this->get_new_render_type( $fieldtype, 'CMB2_Type_File_Base' ); + break; + case 'parse_picker_options': + $this->get_new_render_type( $fieldtype, 'CMB2_Type_Text_Date' ); + break; + case 'get_object_terms': + case 'get_terms': + $this->get_new_render_type( $fieldtype, 'CMB2_Type_Taxonomy_Multicheck' ); + break; + case 'date_args': + case 'time_args': + $this->get_new_render_type( $fieldtype, 'CMB2_Type_Text_Datetime_Timestamp' ); + break; + case 'parse_args': + $this->get_new_render_type( $fieldtype, 'CMB2_Type_Text' ); + break; + } + + return null !== $this->type; + } + + /** + * Check for methods to be proxied to the CMB2_Type_Base object. + * + * @since 2.2.4 + * @param string $method The possible method to proxy. + * @param array $arguments All arguments passed to the method. + * @return bool|array False if not proxied, else array with 'value' key being the return of the method. + */ + public function maybe_proxy_method( $method, $arguments ) { + $exists = false; + + $proxied = array( + 'get_object_terms' => array(), + 'is_valid_img_ext' => false, + 'parse_args' => array(), + 'concat_items' => '', + 'select_option' => '', + 'list_input' => '', + 'list_input_checkbox' => '', + 'img_status_output' => '', + 'file_status_output' => '', + 'parse_picker_options' => array(), + ); + if ( isset( $proxied[ $method ] ) ) { + $exists = array( + // Ok, proxy the method call to the CMB2_Type_Base object. + 'value' => $this->proxy_method( $method, $proxied[ $method ], $arguments ), + ); + } + + return $exists; + } + + /** + * Checks for a custom field CMB2_Type_Base class to use for rendering. + * + * @since 2.2.4 + * + * @param string $fieldtype Non-existent field type name. + * @param array $args Optional field arguments. + * + * @return bool|CMB2_Type_Base Type object if custom field is an object, false if field was added with + * `cmb2_render_{$field_type}` action. + * @throws Exception if custom field type class does not extend CMB2_Type_Base. + */ + public function maybe_custom_field_object( $fieldtype, $args = array() ) { + if ( $render_class_name = $this->get_render_type_class( $fieldtype ) ) { + $this->type = new $render_class_name( $this, $args ); + + if ( ! ( $this->type instanceof CMB2_Type_Base ) ) { + throw new Exception( esc_html__( 'Custom CMB2 field type classes must extend CMB2_Type_Base.', 'cmb2' ) ); + } + + return $this->type; + } + + return false; + } + + /** + * Gets the render type CMB2_Type_Base object to use for rendering the field. + * + * @since 2.2.4 + * @param string $fieldtype The type of field being rendered. + * @param string $render_class_name The default field type class to use. Defaults to null. + * @param array $args Optional arguments to pass to type class. + * @param mixed $additional Optional additional argument to pass to type class. + * @return CMB2_Type_Base Type object. + */ + public function get_new_render_type( $fieldtype, $render_class_name = null, $args = array(), $additional = '' ) { + $render_class_name = $this->get_render_type_class( $fieldtype, $render_class_name ); + $this->type = new $render_class_name( $this, $args, $additional ); + + return $this->type; + } + + /** + * Checks for the render type class to use for rendering the field. + * + * @since 2.2.4 + * @param string $fieldtype The type of field being rendered. + * @param string $render_class_name The default field type class to use. Defaults to null. + * @return string The field type class to use. + */ + public function get_render_type_class( $fieldtype, $render_class_name = null ) { + $render_class_name = $this->field->args( 'render_class' ) ? $this->field->args( 'render_class' ) : $render_class_name; + + if ( has_action( "cmb2_render_class_{$fieldtype}" ) ) { + + /** + * Filters the custom field type class used for rendering the field. Class is required to extend CMB2_Type_Base. + * + * The dynamic portion of the hook name, $fieldtype, refers to the (custom) field type. + * + * @since 2.2.4 + * + * @param string $render_class_name The custom field type class to use. Default null. + * @param object $field_type_object This `CMB2_Types` object. + */ + $render_class_name = apply_filters( "cmb2_render_class_{$fieldtype}", $render_class_name, $this ); + } + + return $render_class_name && class_exists( $render_class_name ) ? $render_class_name : false; + } + + /** + * Retrieve text parameter from field's options array (if it has one), or use fallback text + * + * @since 2.0.0 + * @param string $text_key Key in field's options array. + * @param string $fallback Fallback text. + * @return string + */ + public function _text( $text_key, $fallback = '' ) { + return $this->field->get_string( $text_key, $fallback ); + } + + /** + * Determine a file's extension + * + * @since 1.0.0 + * @param string $file File url + * @return string|false File extension or false + */ + public function get_file_ext( $file ) { + return CMB2_Utils::get_file_ext( $file ); + } + + /** + * Get the file name from a url + * + * @since 2.0.0 + * @param string $value File url or path + * @return string File name + */ + public function get_file_name_from_path( $value ) { + return CMB2_Utils::get_file_name_from_path( $value ); + } + + /** + * Combines attributes into a string for a form element + * + * @since 1.1.0 + * @param array $attrs Attributes to concatenate + * @param array $attr_exclude Attributes that should NOT be concatenated + * @return string String of attributes for form element + */ + public function concat_attrs( $attrs, $attr_exclude = array() ) { + return CMB2_Utils::concat_attrs( $attrs, $attr_exclude ); + } + + /** + * Generates repeatable field table markup + * + * @since 1.0.0 + */ + public function render_repeatable_field() { + $table_id = $this->field->id() . '_repeat'; + + $this->_desc( true, true, true ); + ?> + +
            +
            + repeatable_rows(); ?> +
            +
            +

            + +

            + + iterator = 0; + } + + /** + * Generates repeatable field rows + * + * @since 1.1.0 + */ + public function repeatable_rows() { + $meta_value = array_filter( (array) $this->field->escaped_value() ); + // check for default content + $default = $this->field->get_default(); + + // check for saved data + if ( ! empty( $meta_value ) ) { + $meta_value = is_array( $meta_value ) ? array_filter( $meta_value ) : $meta_value; + $meta_value = ! empty( $meta_value ) ? $meta_value : $default; + } else { + $meta_value = $default; + } + + // Loop value array and add a row + if ( ! empty( $meta_value ) ) { + foreach ( (array) $meta_value as $val ) { + $this->field->escaped_value = $val; + $this->repeat_row(); + $this->iterator++; + } + } else { + + // If value is empty (including empty array), then clear the value. + $this->field->escaped_value = $this->field->value = null; + + // Otherwise add one row + $this->repeat_row(); + } + + // Then add an empty row + $this->field->escaped_value = $default; + $this->iterator = $this->iterator ? $this->iterator : 1; + $this->repeat_row( 'empty-row hidden' ); + } + + /** + * Generates a repeatable row's markup + * + * @since 1.1.0 + * @param string $class Repeatable table row's class + */ + protected function repeat_row( $class = 'cmb-repeat-row' ) { + ?> + +
            +
            + _render(); ?> +
            +
            + +
            +
            + + field->args( 'repeatable' ) || $this->iterator > 0 ) ) { + return ''; + } + + $desc = $this->field->args( 'description' ); + + if ( ! $desc ) { + return; + } + + $tag = $paragraph ? 'p' : 'span'; + $desc = sprintf( "\n" . '<%1$s class="cmb2-metabox-description">%2$s' . "\n", $tag, $desc ); + + if ( $echo ) { + echo $desc; + } + + return $desc; + } + + /** + * Generate field name attribute + * + * @since 1.1.0 + * @param string $suffix For multi-part fields + * @return string Name attribute + */ + public function _name( $suffix = '' ) { + return $this->field->args( '_name' ) . ( $this->field->args( 'repeatable' ) ? '[' . $this->iterator . ']' : '' ) . $suffix; + } + + /** + * Generate field id attribute + * + * @since 1.1.0 + * @param string $suffix For multi-part fields + * @return string Id attribute + */ + public function _id( $suffix = '' ) { + return $this->field->id() . $suffix . ( $this->field->args( 'repeatable' ) ? '_' . $this->iterator . '" data-iterator="' . $this->iterator : '' ); + } + + /** + * Handles outputting an 'input' element + * + * @since 1.1.0 + * @param array $args Override arguments + * @param string $type Field type + * @return string Form input element + */ + public function input( $args = array(), $type = __FUNCTION__ ) { + return $this->get_new_render_type( 'text', 'CMB2_Type_Text', $args, $type )->render(); + } + + /** + * Handles outputting an 'textarea' element + * + * @since 1.1.0 + * @param array $args Override arguments + * @return string Form textarea element + */ + public function textarea( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Textarea', $args )->render(); + } + + /** + * Begin Field Types + */ + + public function text() { + return $this->input(); + } + + public function hidden() { + $args = array( + 'type' => 'hidden', + 'desc' => '', + 'class' => 'cmb2-hidden', + ); + if ( $this->field->group ) { + $args['data-groupid'] = $this->field->group->id(); + $args['data-iterator'] = $this->iterator; + } + + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text', $args, 'input' )->render(); + } + + public function text_small() { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text', array( + 'class' => 'cmb2-text-small', + 'desc' => $this->_desc(), + ), 'input' )->render(); + } + + public function text_medium() { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text', array( + 'class' => 'cmb2-text-medium', + 'desc' => $this->_desc(), + ), 'input' )->render(); + } + + public function text_email() { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text', array( + 'class' => 'cmb2-text-email cmb2-text-medium', + 'type' => 'email', + ), 'input' )->render(); + } + + public function text_url() { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text', array( + 'class' => 'cmb2-text-url cmb2-text-medium regular-text', + 'value' => $this->field->escaped_value( 'esc_url' ), + ), 'input' )->render(); + } + + public function text_money() { + $input = $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text', array( + 'class' => 'cmb2-text-money', + 'desc' => $this->_desc(), + ), 'input' )->render(); + return ( ! $this->field->get_param_callback_result( 'before_field' ) ? '$ ' : ' ' ) . $input; + } + + public function textarea_small() { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Textarea', array( + 'class' => 'cmb2-textarea-small', + 'rows' => 4, + ) )->render(); + } + + public function textarea_code( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Textarea_Code', $args )->render(); + } + + public function wysiwyg( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Wysiwyg', $args )->render(); + } + + public function text_date( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text_Date', $args )->render(); + } + + // Alias for text_date + public function text_date_timestamp( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text_Date', $args )->render(); + } + + public function text_time( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text_Time', $args )->render(); + } + + public function text_datetime_timestamp( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text_Datetime_Timestamp', $args )->render(); + } + + public function text_datetime_timestamp_timezone( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Text_Datetime_Timestamp_Timezone', $args )->render(); + } + + public function select_timezone( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Select_Timezone', $args )->render(); + } + + public function colorpicker( $args = array(), $meta_value = '' ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Colorpicker', $args, $meta_value )->render(); + } + + public function title( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Title', $args )->render(); + } + + public function select( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Select', $args )->render(); + } + + public function taxonomy_select( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Taxonomy_Select', $args )->render(); + } + + public function radio( $args = array(), $type = __FUNCTION__ ) { + return $this->get_new_render_type( $type, 'CMB2_Type_Radio', $args, $type )->render(); + } + + public function radio_inline( $args = array() ) { + return $this->radio( $args, __FUNCTION__ ); + } + + public function multicheck( $type = 'checkbox' ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Multicheck', array(), $type )->render(); + } + + public function multicheck_inline() { + return $this->multicheck( 'multicheck_inline' ); + } + + public function checkbox( $args = array(), $is_checked = null ) { + // Avoid get_new_render_type since we need a different default for the 3rd argument than ''. + $render_class_name = $this->get_render_type_class( __FUNCTION__, 'CMB2_Type_Checkbox' ); + $this->type = new $render_class_name( $this, $args, $is_checked ); + return $this->type->render(); + } + + public function taxonomy_radio( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Taxonomy_Radio', $args )->render(); + } + + public function taxonomy_radio_hierarchical( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Taxonomy_Radio_Hierarchical', $args )->render(); + } + + public function taxonomy_radio_inline( $args = array() ) { + return $this->taxonomy_radio( $args ); + } + + public function taxonomy_multicheck( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Taxonomy_Multicheck', $args )->render(); + } + + public function taxonomy_multicheck_hierarchical( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Taxonomy_Multicheck_Hierarchical', $args )->render(); + } + + public function taxonomy_multicheck_inline( $args = array() ) { + return $this->taxonomy_multicheck( $args ); + } + + public function oembed( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_Oembed', $args )->render(); + } + + public function file_list( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_File_List', $args )->render(); + } + + public function file( $args = array() ) { + return $this->get_new_render_type( __FUNCTION__, 'CMB2_Type_File', $args )->render(); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Utils.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Utils.php new file mode 100755 index 00000000..b7b00a46 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_Utils.php @@ -0,0 +1,669 @@ + 'attachment', + 'post_status' => 'inherit', + 'fields' => 'ids', + 'meta_query' => array( + array( + 'value' => $file, + 'compare' => 'LIKE', + 'key' => '_wp_attachment_metadata', + ), + ), + ); + + $query = new WP_Query( $query_args ); + + if ( $query->have_posts() ) { + + foreach ( $query->posts as $post_id ) { + $meta = wp_get_attachment_metadata( $post_id ); + $original_file = basename( $meta['file'] ); + $cropped_image_files = isset( $meta['sizes'] ) ? wp_list_pluck( $meta['sizes'], 'file' ) : array(); + if ( $original_file === $file || in_array( $file, $cropped_image_files ) ) { + $attachment_id = $post_id; + break; + } + } + } + + return 0 === $attachment_id ? false : $attachment_id; + } + + /** + * Utility method to get a combined list of default and custom registered image sizes + * + * @since 2.2.4 + * @link http://core.trac.wordpress.org/ticket/18947 + * @global array $_wp_additional_image_sizes + * @return array The image sizes + */ + public static function get_available_image_sizes() { + global $_wp_additional_image_sizes; + + $default_image_sizes = array( 'thumbnail', 'medium', 'large' ); + foreach ( $default_image_sizes as $size ) { + $image_sizes[ $size ] = array( + 'height' => intval( get_option( "{$size}_size_h" ) ), + 'width' => intval( get_option( "{$size}_size_w" ) ), + 'crop' => get_option( "{$size}_crop" ) ? get_option( "{$size}_crop" ) : false, + ); + } + + if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) ) { + $image_sizes = array_merge( $image_sizes, $_wp_additional_image_sizes ); + } + + return $image_sizes; + } + + /** + * Utility method to return the closest named size from an array of values + * + * Based off of WordPress's image_get_intermediate_size() + * If the size matches an existing size then it will be used. If there is no + * direct match, then the nearest image size larger than the specified size + * will be used. If nothing is found, then the function will return false. + * Uses get_available_image_sizes() to get all available sizes. + * + * @since 2.2.4 + * @param array|string $size Image size. Accepts an array of width and height (in that order). + * @return false|string Named image size e.g. 'thumbnail' + */ + public static function get_named_size( $size ) { + $data = array(); + + // Find the best match when '$size' is an array. + if ( is_array( $size ) ) { + $image_sizes = self::get_available_image_sizes(); + $candidates = array(); + + foreach ( $image_sizes as $_size => $data ) { + + // If there's an exact match to an existing image size, short circuit. + if ( $data['width'] == $size[0] && $data['height'] == $size[1] ) { + $candidates[ $data['width'] * $data['height'] ] = array( $_size, $data ); + break; + } + + // If it's not an exact match, consider larger sizes with the same aspect ratio. + if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) { + + /** + * To test for varying crops, we constrain the dimensions of the larger image + * to the dimensions of the smaller image and see if they match. + */ + if ( $data['width'] > $size[0] ) { + $constrained_size = wp_constrain_dimensions( $data['width'], $data['height'], $size[0] ); + $expected_size = array( $size[0], $size[1] ); + } else { + $constrained_size = wp_constrain_dimensions( $size[0], $size[1], $data['width'] ); + $expected_size = array( $data['width'], $data['height'] ); + } + + // If the image dimensions are within 1px of the expected size, we consider it a match. + $matched = ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 ); + + if ( $matched ) { + $candidates[ $data['width'] * $data['height'] ] = array( $_size, $data ); + } + } + } + + if ( ! empty( $candidates ) ) { + // Sort the array by size if we have more than one candidate. + if ( 1 < count( $candidates ) ) { + ksort( $candidates ); + } + + $data = array_shift( $candidates ); + $data = $data[0]; + } elseif ( ! empty( $image_sizes['thumbnail'] ) && $image_sizes['thumbnail']['width'] >= $size[0] && $image_sizes['thumbnail']['width'] >= $size[1] ) { + /* + * When the size requested is smaller than the thumbnail dimensions, we + * fall back to the thumbnail size. + */ + $data = 'thumbnail'; + } else { + return false; + } + } elseif ( ! empty( $image_sizes[ $size ] ) ) { + $data = $size; + }// End if. + + // If we still don't have a match at this point, return false. + if ( empty( $data ) ) { + return false; + } + + return $data; + } + + /** + * Utility method that returns time string offset by timezone + * + * @since 1.0.0 + * @param string $tzstring Time string. + * @return string Offset time string + */ + public static function timezone_offset( $tzstring ) { + $tz_offset = 0; + + if ( ! empty( $tzstring ) && is_string( $tzstring ) ) { + if ( 'UTC' === substr( $tzstring, 0, 3 ) ) { + $tzstring = str_replace( array( ':15', ':30', ':45' ), array( '.25', '.5', '.75' ), $tzstring ); + return intval( floatval( substr( $tzstring, 3 ) ) * HOUR_IN_SECONDS ); + } + + try { + $date_time_zone_selected = new DateTimeZone( $tzstring ); + $tz_offset = timezone_offset_get( $date_time_zone_selected, date_create() ); + } catch ( Exception $e ) { + self::log_if_debug( __METHOD__, __LINE__, $e->getMessage() ); + } + } + + return $tz_offset; + } + + /** + * Utility method that returns a timezone string representing the default timezone for the site. + * + * Roughly copied from WordPress, as get_option('timezone_string') will return + * an empty string if no value has been set on the options page. + * A timezone string is required by the wp_timezone_choice() used by the + * select_timezone field. + * + * @since 1.0.0 + * @return string Timezone string + */ + public static function timezone_string() { + $current_offset = get_option( 'gmt_offset' ); + $tzstring = get_option( 'timezone_string' ); + + // Remove old Etc mappings. Fallback to gmt_offset. + if ( false !== strpos( $tzstring, 'Etc/GMT' ) ) { + $tzstring = ''; + } + + if ( empty( $tzstring ) ) { // Create a UTC+- zone if no timezone string exists. + if ( 0 == $current_offset ) { + $tzstring = 'UTC+0'; + } elseif ( $current_offset < 0 ) { + $tzstring = 'UTC' . $current_offset; + } else { + $tzstring = 'UTC+' . $current_offset; + } + } + + return $tzstring; + } + + /** + * Returns a timestamp, first checking if value already is a timestamp. + * + * @since 2.0.0 + * @param string|int $string Possible timestamp string. + * @return int Time stamp. + */ + public static function make_valid_time_stamp( $string ) { + if ( ! $string ) { + return 0; + } + + return self::is_valid_time_stamp( $string ) + ? (int) $string : + strtotime( (string) $string ); + } + + /** + * Determine if a value is a valid timestamp + * + * @since 2.0.0 + * @param mixed $timestamp Value to check. + * @return boolean Whether value is a valid timestamp + */ + public static function is_valid_time_stamp( $timestamp ) { + return (string) (int) $timestamp === (string) $timestamp + && $timestamp <= PHP_INT_MAX + && $timestamp >= ~PHP_INT_MAX; + } + + /** + * Checks if a value is 'empty'. Still accepts 0. + * + * @since 2.0.0 + * @param mixed $value Value to check. + * @return bool True or false + */ + public static function isempty( $value ) { + return null === $value || '' === $value || false === $value || array() === $value; + } + + /** + * Checks if a value is not 'empty'. 0 doesn't count as empty. + * + * @since 2.2.2 + * @param mixed $value Value to check. + * @return bool True or false + */ + public static function notempty( $value ) { + return null !== $value && '' !== $value && false !== $value && array() !== $value; + } + + /** + * Filters out empty values (not including 0). + * + * @since 2.2.2 + * @param mixed $value Value to check. + * @return array True or false. + */ + public static function filter_empty( $value ) { + return array_filter( $value, array( __CLASS__, 'notempty' ) ); + } + + /** + * Insert a single array item inside another array at a set position + * + * @since 2.0.2 + * @param array $array Array to modify. Is passed by reference, and no return is needed. Passed by reference. + * @param array $new New array to insert. + * @param int $position Position in the main array to insert the new array. + */ + public static function array_insert( &$array, $new, $position ) { + $before = array_slice( $array, 0, $position - 1 ); + $after = array_diff_key( $array, $before ); + $array = array_merge( $before, $new, $after ); + } + + /** + * Defines the url which is used to load local resources. + * This may need to be filtered for local Window installations. + * If resources do not load, please check the wiki for details. + * + * @since 1.0.1 + * + * @param string $path URL path. + * @return string URL to CMB2 resources + */ + public static function url( $path = '' ) { + if ( self::$url ) { + return self::$url . $path; + } + + $cmb2_url = self::get_url_from_dir( cmb2_dir() ); + + /** + * Filter the CMB location url. + * + * @param string $cmb2_url Currently registered url. + */ + self::$url = trailingslashit( apply_filters( 'cmb2_meta_box_url', $cmb2_url, CMB2_VERSION ) ); + + return self::$url . $path; + } + + /** + * Converts a system path to a URL + * + * @since 2.2.2 + * @param string $dir Directory path to convert. + * @return string Converted URL. + */ + public static function get_url_from_dir( $dir ) { + $dir = self::normalize_path( $dir ); + + // Let's test if We are in the plugins or mu-plugins dir. + $test_dir = trailingslashit( $dir ) . 'unneeded.php'; + if ( + 0 === strpos( $test_dir, self::normalize_path( WPMU_PLUGIN_DIR ) ) + || 0 === strpos( $test_dir, self::normalize_path( WP_PLUGIN_DIR ) ) + ) { + // Ok, then use plugins_url, as it is more reliable. + return trailingslashit( plugins_url( '', $test_dir ) ); + } + + // Ok, now let's test if we are in the theme dir. + $theme_root = self::normalize_path( get_theme_root() ); + if ( 0 === strpos( $dir, $theme_root ) ) { + // Ok, then use get_theme_root_uri. + return set_url_scheme( + trailingslashit( + str_replace( + untrailingslashit( $theme_root ), + untrailingslashit( get_theme_root_uri() ), + $dir + ) + ) + ); + } + + // Check to see if it's anywhere in the root directory. + $site_dir = self::get_normalized_abspath(); + $site_url = trailingslashit( is_multisite() ? network_site_url() : site_url() ); + + $url = str_replace( + array( $site_dir, WP_PLUGIN_DIR ), + array( $site_url, WP_PLUGIN_URL ), + $dir + ); + + return set_url_scheme( $url ); + } + + /** + * Get the normalized absolute path defined by WordPress. + * + * @since 2.2.6 + * + * @return string Normalized absolute path. + */ + protected static function get_normalized_abspath() { + return self::normalize_path( self::$ABSPATH ); + } + + /** + * `wp_normalize_path` wrapper for back-compat. Normalize a filesystem path. + * + * On windows systems, replaces backslashes with forward slashes + * and forces upper-case drive letters. + * Allows for two leading slashes for Windows network shares, but + * ensures that all other duplicate slashes are reduced to a single. + * + * @since 2.2.0 + * + * @param string $path Path to normalize. + * @return string Normalized path. + */ + protected static function normalize_path( $path ) { + if ( function_exists( 'wp_normalize_path' ) ) { + return wp_normalize_path( $path ); + } + + // Replace newer WP's version of wp_normalize_path. + $path = str_replace( '\\', '/', $path ); + $path = preg_replace( '|(?<=.)/+|', '/', $path ); + if ( ':' === substr( $path, 1, 1 ) ) { + $path = ucfirst( $path ); + } + + return $path; + } + + /** + * Get timestamp from text date + * + * @since 2.2.0 + * @param string $value Date value. + * @param string $date_format Expected date format. + * @return mixed Unix timestamp representing the date. + */ + public static function get_timestamp_from_value( $value, $date_format ) { + $date_object = date_create_from_format( $date_format, $value ); + return $date_object ? $date_object->setTime( 0, 0, 0 )->getTimeStamp() : strtotime( $value ); + } + + /** + * Takes a php date() format string and returns a string formatted to suit for the date/time pickers + * It will work only with the following subset of date() options: + * + * Formats: d, l, j, z, m, F, n, y, and Y. + * + * A slight effort is made to deal with escaped characters. + * + * Other options are ignored, because they would either bring compatibility problems between PHP and JS, or + * bring even more translation troubles. + * + * @since 2.2.0 + * @param string $format PHP date format. + * @return string reformatted string + */ + public static function php_to_js_dateformat( $format ) { + + // order is relevant here, since the replacement will be done sequentially. + $supported_options = array( + 'd' => 'dd', // Day, leading 0. + 'j' => 'd', // Day, no 0. + 'z' => 'o', // Day of the year, no leading zeroes. + // 'D' => 'D', // Day name short, not sure how it'll work with translations. + 'l ' => 'DD ', // Day name full, idem before. + 'l, ' => 'DD, ', // Day name full, idem before. + 'm' => 'mm', // Month of the year, leading 0. + 'n' => 'm', // Month of the year, no leading 0. + // 'M' => 'M', // Month, Short name. + 'F ' => 'MM ', // Month, full name. + 'F, ' => 'MM, ', // Month, full name. + 'y' => 'y', // Year, two digit. + 'Y' => 'yy', // Year, full. + 'H' => 'HH', // Hour with leading 0 (24 hour). + 'G' => 'H', // Hour with no leading 0 (24 hour). + 'h' => 'hh', // Hour with leading 0 (12 hour). + 'g' => 'h', // Hour with no leading 0 (12 hour). + 'i' => 'mm', // Minute with leading 0. + 's' => 'ss', // Second with leading 0. + 'a' => 'tt', // am/pm. + 'A' => 'TT', // AM/PM. + ); + + foreach ( $supported_options as $php => $js ) { + // replaces every instance of a supported option, but skips escaped characters. + $format = preg_replace( "~(? 'DD', // Day name full, idem before. + 'F' => 'MM', // Month, full name. + ); + + if ( isset( $supported_options[ $format ] ) ) { + $format = $supported_options[ $format ]; + } + + $format = preg_replace_callback( '~(?:\\\.)+~', array( __CLASS__, 'wrap_escaped_chars' ), $format ); + + return $format; + } + + /** + * Helper function for CMB_Utils::php_to_js_dateformat(). + * + * @since 2.2.0 + * @param string $value Value to wrap/escape. + * @return string Modified value + */ + public static function wrap_escaped_chars( $value ) { + return ''' . str_replace( '\\', '', $value[0] ) . '''; + } + + /** + * Send to debug.log if WP_DEBUG is defined and true + * + * @since 2.2.0 + * + * @param string $function Function name. + * @param int $line Line number. + * @param mixed $msg Message to output. + * @param mixed $debug Variable to print_r. + */ + public static function log_if_debug( $function, $line, $msg, $debug = null ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( "In $function, $line:" . print_r( $msg, true ) . ( $debug ? print_r( $debug, true ) : '' ) ); + } + } + + /** + * Determine a file's extension + * + * @since 1.0.0 + * @param string $file File url. + * @return string|false File extension or false + */ + public static function get_file_ext( $file ) { + $parsed = parse_url( $file, PHP_URL_PATH ); + return $parsed ? strtolower( pathinfo( $parsed, PATHINFO_EXTENSION ) ) : false; + } + + /** + * Get the file name from a url + * + * @since 2.0.0 + * @param string $value File url or path. + * @return string File name + */ + public static function get_file_name_from_path( $value ) { + $parts = explode( '/', $value ); + return is_array( $parts ) ? end( $parts ) : $value; + } + + /** + * Check if WP version is at least $version. + * + * @since 2.2.2 + * @param string $version WP version string to compare. + * @return bool Result of comparison check. + */ + public static function wp_at_least( $version ) { + return version_compare( get_bloginfo( 'version' ), $version, '>=' ); + } + + /** + * Combines attributes into a string for a form element. + * + * @since 1.1.0 + * @param array $attrs Attributes to concatenate. + * @param array $attr_exclude Attributes that should NOT be concatenated. + * @return string String of attributes for form element. + */ + public static function concat_attrs( $attrs, $attr_exclude = array() ) { + $attr_exclude[] = 'rendered'; + $attr_exclude[] = 'js_dependencies'; + + $attributes = ''; + foreach ( $attrs as $attr => $val ) { + $excluded = in_array( $attr, (array) $attr_exclude, true ); + $empty = false === $val && 'value' !== $attr; + if ( ! $excluded && ! $empty ) { + // if data attribute, use single quote wraps, else double. + $quotes = self::is_data_attribute( $attr ) ? "'" : '"'; + $attributes .= sprintf( ' %1$s=%3$s%2$s%3$s', $attr, $val, $quotes ); + } + } + return $attributes; + } + + /** + * Check if given attribute is a data attribute. + * + * @since 2.2.5 + * + * @param string $att HTML attribute. + * @return boolean + */ + public static function is_data_attribute( $att ) { + return 0 === stripos( $att, 'data-' ); + } + + /** + * Ensures value is an array. + * + * @since 2.2.3 + * + * @param mixed $value Value to ensure is array. + * @param array $default Default array. Defaults to empty array. + * + * @return array The array. + */ + public static function ensure_array( $value, $default = array() ) { + if ( empty( $value ) ) { + return $default; + } + + if ( is_array( $value ) || is_object( $value ) ) { + return (array) $value; + } + + // Not sure anything would be non-scalar that is not an array or object? + if ( ! is_scalar( $value ) ) { + return $default; + } + + return (array) $value; + } + + /** + * If number is numeric, normalize it with floatval or intval, depending on if decimal is found. + * + * @since 2.2.6 + * + * @param mixed $value Value to normalize (if numeric). + * @return mixed Possibly normalized value. + */ + public static function normalize_if_numeric( $value ) { + if ( is_numeric( $value ) ) { + $value = false !== strpos( $value, '.' ) ? floatval( $value ) : intval( $value ); + } + + return $value; + } + + /** + * Generates a 12 character unique hash from a string. + * + * @since 2.4.0 + * + * @param string $string String to create a hash from. + * + * @return string + */ + public static function generate_hash( $string ) { + return substr( base_convert( md5( $string ), 16, 32 ), 0, 12 ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_hookup.php b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_hookup.php new file mode 100755 index 00000000..51a9be66 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/CMB2_hookup.php @@ -0,0 +1,933 @@ +prop( 'hookup' ) ) { + + $hookup = new self( $cmb ); + + // Hook in the hookup... how meta. + return $hookup->universal_hooks(); + } + + return false; + } + + public function universal_hooks() { + foreach ( get_class_methods( 'CMB2_Show_Filters' ) as $filter ) { + add_filter( 'cmb2_show_on', array( 'CMB2_Show_Filters', $filter ), 10, 3 ); + } + + if ( is_admin() ) { + // Register our scripts and styles for cmb. + $this->once( 'admin_enqueue_scripts', array( __CLASS__, 'register_scripts' ), 8 ); + $this->once( 'admin_enqueue_scripts', array( $this, 'do_scripts' ) ); + + $this->maybe_enqueue_column_display_styles(); + + switch ( $this->object_type ) { + case 'post': + return $this->post_hooks(); + case 'comment': + return $this->comment_hooks(); + case 'user': + return $this->user_hooks(); + case 'term': + return $this->term_hooks(); + case 'options-page': + return $this->options_page_hooks(); + } + } + + return $this; + } + + public function post_hooks() { + + // Fetch the context we set in our call. + $context = $this->cmb->prop( 'context' ) ? $this->cmb->prop( 'context' ) : 'normal'; + + // Call the proper hook based on the context provided. + switch ( $context ) { + + case 'form_top': + add_action( 'edit_form_top', array( $this, 'add_context_metaboxes' ) ); + break; + + case 'before_permalink': + add_action( 'edit_form_before_permalink', array( $this, 'add_context_metaboxes' ) ); + break; + + case 'after_title': + add_action( 'edit_form_after_title', array( $this, 'add_context_metaboxes' ) ); + break; + + case 'after_editor': + add_action( 'edit_form_after_editor', array( $this, 'add_context_metaboxes' ) ); + break; + + default: + add_action( 'add_meta_boxes', array( $this, 'add_metaboxes' ) ); + } + + add_action( 'add_meta_boxes', array( $this, 'remove_default_tax_metaboxes' ) ); + add_action( 'add_attachment', array( $this, 'save_post' ) ); + add_action( 'edit_attachment', array( $this, 'save_post' ) ); + add_action( 'save_post', array( $this, 'save_post' ), 10, 2 ); + + if ( $this->cmb->has_columns ) { + foreach ( $this->cmb->box_types() as $post_type ) { + add_filter( "manage_{$post_type}_posts_columns", array( $this, 'register_column_headers' ) ); + add_action( "manage_{$post_type}_posts_custom_column", array( $this, 'column_display' ), 10, 2 ); + } + } + + return $this; + } + + public function comment_hooks() { + add_action( 'add_meta_boxes_comment', array( $this, 'add_metaboxes' ) ); + add_action( 'edit_comment', array( $this, 'save_comment' ) ); + + if ( $this->cmb->has_columns ) { + add_filter( 'manage_edit-comments_columns', array( $this, 'register_column_headers' ) ); + add_action( 'manage_comments_custom_column', array( $this, 'column_display' ), 10, 3 ); + } + + return $this; + } + + public function user_hooks() { + $priority = $this->get_priority(); + + add_action( 'show_user_profile', array( $this, 'user_metabox' ), $priority ); + add_action( 'edit_user_profile', array( $this, 'user_metabox' ), $priority ); + add_action( 'user_new_form', array( $this, 'user_new_metabox' ), $priority ); + + add_action( 'personal_options_update', array( $this, 'save_user' ) ); + add_action( 'edit_user_profile_update', array( $this, 'save_user' ) ); + add_action( 'user_register', array( $this, 'save_user' ) ); + + if ( $this->cmb->has_columns ) { + add_filter( 'manage_users_columns', array( $this, 'register_column_headers' ) ); + add_filter( 'manage_users_custom_column', array( $this, 'return_column_display' ), 10, 3 ); + } + + return $this; + } + + public function term_hooks() { + if ( ! function_exists( 'get_term_meta' ) ) { + wp_die( esc_html__( 'Term Metadata is a WordPress 4.4+ feature. Please upgrade your WordPress install.', 'cmb2' ) ); + } + + if ( ! $this->cmb->prop( 'taxonomies' ) ) { + wp_die( esc_html__( 'Term metaboxes configuration requires a "taxonomies" parameter.', 'cmb2' ) ); + } + + $this->taxonomies = (array) $this->cmb->prop( 'taxonomies' ); + $show_on_term_add = $this->cmb->prop( 'new_term_section' ); + $priority = $this->get_priority( 8 ); + + foreach ( $this->taxonomies as $taxonomy ) { + // Display our form data. + add_action( "{$taxonomy}_edit_form", array( $this, 'term_metabox' ), $priority, 2 ); + + $show_on_add = is_array( $show_on_term_add ) + ? in_array( $taxonomy, $show_on_term_add ) + : (bool) $show_on_term_add; + + /** + * Filter to determine if the term's fields should show in the "Add term" section. + * + * The dynamic portion of the hook name, $cmb_id, is the metabox id. + * + * @param bool $show_on_add Default is the value of the new_term_section cmb parameter. + * @param object $cmb The CMB2 instance + */ + $show_on_add = apply_filters( "cmb2_show_on_term_add_form_{$this->cmb->cmb_id}", $show_on_add, $this->cmb ); + + // Display form in add-new section (unless specified not to). + if ( $show_on_add ) { + add_action( "{$taxonomy}_add_form_fields", array( $this, 'term_metabox' ), $priority, 2 ); + } + + if ( $this->cmb->has_columns ) { + add_filter( "manage_edit-{$taxonomy}_columns", array( $this, 'register_column_headers' ) ); + add_filter( "manage_{$taxonomy}_custom_column", array( $this, 'return_column_display' ), 10, 3 ); + } + } + + add_action( 'created_term', array( $this, 'save_term' ), 10, 3 ); + add_action( 'edited_terms', array( $this, 'save_term' ), 10, 2 ); + add_action( 'delete_term', array( $this, 'delete_term' ), 10, 3 ); + + return $this; + } + + public function options_page_hooks() { + $option_keys = $this->cmb->options_page_keys(); + + if ( ! empty( $option_keys ) ) { + foreach ( $option_keys as $option_key ) { + $this->options_hookup[ $option_key ] = new CMB2_Options_Hookup( $this->cmb, $option_key ); + $this->options_hookup[ $option_key ]->hooks(); + } + } + + return $this; + } + + /** + * Registers styles for CMB2 + * + * @since 2.0.7 + */ + protected static function register_styles() { + if ( self::$css_registration_done ) { + return; + } + + // Only use minified files if SCRIPT_DEBUG is off. + $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + $front = is_admin() ? '' : '-front'; + $rtl = is_rtl() ? '-rtl' : ''; + + /** + * Filters the registered style dependencies for the cmb2 stylesheet. + * + * @param array $dependencies The registered style dependencies for the cmb2 stylesheet. + */ + $dependencies = apply_filters( 'cmb2_style_dependencies', array() ); + wp_register_style( 'cmb2-styles', CMB2_Utils::url( "css/cmb2{$front}{$rtl}{$min}.css" ), $dependencies ); + wp_register_style( 'cmb2-display-styles', CMB2_Utils::url( "css/cmb2-display{$rtl}{$min}.css" ), $dependencies ); + + self::$css_registration_done = true; + } + + /** + * Registers scripts for CMB2 + * + * @since 2.0.7 + */ + protected static function register_js() { + if ( self::$js_registration_done ) { + return; + } + + $hook = is_admin() ? 'admin_footer' : 'wp_footer'; + add_action( $hook, array( 'CMB2_JS', 'enqueue' ), 8 ); + + self::$js_registration_done = true; + } + + /** + * Registers scripts and styles for CMB2 + * + * @since 1.0.0 + */ + public static function register_scripts() { + self::register_styles(); + self::register_js(); + } + + /** + * Enqueues scripts and styles for CMB2 in admin_head. + * + * @since 1.0.0 + * + * @param string $hook Current hook for the admin page. + */ + public function do_scripts( $hook ) { + $hooks = array( + 'post.php', + 'post-new.php', + 'page-new.php', + 'page.php', + 'comment.php', + 'edit-tags.php', + 'term.php', + 'user-new.php', + 'profile.php', + 'user-edit.php', + ); + // only pre-enqueue our scripts/styles on the proper pages + // show_form_for_type will have us covered if we miss something here. + if ( in_array( $hook, $hooks, true ) ) { + if ( $this->cmb->prop( 'cmb_styles' ) ) { + self::enqueue_cmb_css(); + } + if ( $this->cmb->prop( 'enqueue_js' ) ) { + self::enqueue_cmb_js(); + } + } + } + + /** + * Register the CMB2 field column headers. + * + * @since 2.2.2 + * + * @param array $columns Array of columns available for the admin page. + */ + public function register_column_headers( $columns ) { + $fields = $this->cmb->prop( 'fields' ); + + foreach ( $fields as $key => $field ) { + if ( ! isset( $field['column'] ) ) { + continue; + } + + $column = $field['column']; + + if ( false === $column['position'] ) { + + $columns[ $field['id'] ] = $column['name']; + + } else { + + $before = array_slice( $columns, 0, absint( $column['position'] ) ); + $before[ $field['id'] ] = $column['name']; + $columns = $before + $columns; + } + + $column['field'] = $field; + $this->columns[ $field['id'] ] = $column; + } + + return $columns; + } + + /** + * The CMB2 field column display output. + * + * @since 2.2.2 + * + * @param string $column_name Current column name. + * @param mixed $object_id Current object ID. + */ + public function column_display( $column_name, $object_id ) { + if ( isset( $this->columns[ $column_name ] ) ) { + $field = new CMB2_Field( array( + 'field_args' => $this->columns[ $column_name ]['field'], + 'object_type' => $this->object_type, + 'object_id' => $this->cmb->object_id( $object_id ), + 'cmb_id' => $this->cmb->cmb_id, + ) ); + + $this->cmb->get_field( $field )->render_column(); + } + } + + /** + * Returns the column display. + * + * @since 2.2.2 + */ + public function return_column_display( $empty, $custom_column, $object_id ) { + ob_start(); + $this->column_display( $custom_column, $object_id ); + $column = ob_get_clean(); + + return $column ? $column : $empty; + } + + /** + * Output the CMB2 box/fields in an alternate context (not in a standard metabox area). + * + * @since 2.2.4 + */ + public function add_context_metaboxes() { + + if ( ! $this->show_on() ) { + return; + } + + $page = get_current_screen()->id; + + foreach ( $this->cmb->box_types() as $object_type ) { + $screen = convert_to_screen( $object_type ); + + // If we're on the right post-type/object... + if ( isset( $screen->id ) && $screen->id === $page ) { + + // Show the box. + $this->output_context_metabox(); + } + } + } + + /** + * Output the CMB2 box/fields in an alternate context (not in a standard metabox area). + * + * @since 2.2.4 + */ + public function output_context_metabox() { + $title = $this->cmb->prop( 'title' ); + + /* + * To keep from outputting the open/close markup, do not include + * a 'title' property in your metabox registration array. + * + * To output the fields 'naked' (without a postbox wrapper/style), then + * add a `'remove_box_wrap' => true` to your metabox registration array. + */ + $add_wrap = ! empty( $title ) || ! $this->cmb->prop( 'remove_box_wrap' ); + $add_handle = $add_wrap && ! empty( $title ); + + // Open the context-box wrap. + $this->context_box_title_markup_open( $add_handle ); + + // Show the form fields. + $this->cmb->show_form(); + + // Close the context-box wrap. + $this->context_box_title_markup_close( $add_handle ); + } + + /** + * Output the opening markup for a context box. + * + * @since 2.2.4 + * @param bool $add_handle Whether to add the metabox handle and opening div for .inside. + */ + public function context_box_title_markup_open( $add_handle = true ) { + $title = $this->cmb->prop( 'title' ); + + $page = get_current_screen()->id; + add_filter( "postbox_classes_{$page}_{$this->cmb->cmb_id}", array( $this, 'postbox_classes' ) ); + + echo '
            ' . "\n"; + + if ( $add_handle ) { + + echo ''; + + echo '

            ' . esc_attr( $title ) . '

            ' . "\n"; + echo '
            ' . "\n"; + } + } + + /** + * Output the closing markup for a context box. + * + * @since 2.2.4 + * @param bool $add_inside_close Whether to add closing div for .inside. + */ + public function context_box_title_markup_close( $add_inside_close = true ) { + + // Load the closing divs for a title box. + if ( $add_inside_close ) { + echo '
            ' . "\n"; // .inside + } + + echo '
            ' . "\n"; // .context-box + } + + /** + * Add metaboxes (to 'post' or 'comment' object types) + * + * @since 1.0.0 + */ + public function add_metaboxes() { + + if ( ! $this->show_on() ) { + return; + } + + /* + * To keep from registering an actual post-screen metabox, + * omit the 'title' property from the metabox registration array. + * + * (WordPress will not display metaboxes without titles anyway) + * + * This is a good solution if you want to handle outputting your + * metaboxes/fields elsewhere in the post-screen. + */ + if ( ! $this->cmb->prop( 'title' ) ) { + return; + } + + $page = get_current_screen()->id; + add_filter( "postbox_classes_{$page}_{$this->cmb->cmb_id}", array( $this, 'postbox_classes' ) ); + + foreach ( $this->cmb->box_types() as $object_type ) { + add_meta_box( + $this->cmb->cmb_id, + $this->cmb->prop( 'title' ), + array( $this, 'metabox_callback' ), + $object_type, + $this->cmb->prop( 'context' ), + $this->cmb->prop( 'priority' ), + $this->cmb->prop( 'mb_callback_args' ) + ); + } + } + + /** + * Remove the specified default taxonomy metaboxes for a post-type. + * + * @since 2.2.3 + * + */ + public function remove_default_tax_metaboxes() { + $to_remove = array_filter( (array) $this->cmb->tax_metaboxes_to_remove, 'taxonomy_exists' ); + if ( empty( $to_remove ) ) { + return; + } + + foreach ( $this->cmb->box_types() as $post_type ) { + foreach ( $to_remove as $taxonomy ) { + $mb_id = is_taxonomy_hierarchical( $taxonomy ) ? "{$taxonomy}div" : "tagsdiv-{$taxonomy}"; + remove_meta_box( $mb_id, $post_type, 'side' ); + } + } + } + + /** + * Modify metabox postbox classes. + * + * @since 2.2.4 + * @param array $classes Array of classes. + * @return array Modified array of classes + */ + public function postbox_classes( $classes ) { + if ( $this->cmb->prop( 'closed' ) && ! in_array( 'closed', $classes ) ) { + $classes[] = 'closed'; + } + + if ( $this->cmb->is_alternate_context_box() ) { + $classes = $this->alternate_context_postbox_classes( $classes ); + } else { + $classes[] = 'cmb2-postbox'; + } + + return $classes; + } + + /** + * Modify metabox altnernate context postbox classes. + * + * @since 2.2.4 + * @param array $classes Array of classes. + * @return array Modified array of classes + */ + protected function alternate_context_postbox_classes( $classes ) { + $classes[] = 'context-box'; + $classes[] = 'context-' . $this->cmb->prop( 'context' ) . '-box'; + + if ( in_array( $this->cmb->cmb_id, get_hidden_meta_boxes( get_current_screen() ) ) ) { + $classes[] = 'hide-if-js'; + } + + $add_wrap = $this->cmb->prop( 'title' ) || ! $this->cmb->prop( 'remove_box_wrap' ); + + if ( $add_wrap ) { + $classes[] = 'cmb2-postbox postbox'; + } else { + $classes[] = 'cmb2-no-box-wrap'; + } + + return $classes; + } + + /** + * Display metaboxes for a post or comment object. + * + * @since 1.0.0 + */ + public function metabox_callback() { + $object_id = 'comment' == $this->object_type ? get_comment_ID() : get_the_ID(); + $this->cmb->show_form( $object_id, $this->object_type ); + } + + /** + * Display metaboxes for new user page. + * + * @since 1.0.0 + * + * @param mixed $section User section metabox. + */ + public function user_new_metabox( $section ) { + if ( $section == $this->cmb->prop( 'new_user_section' ) ) { + $object_id = $this->cmb->object_id(); + $this->cmb->object_id( isset( $_REQUEST['user_id'] ) ? intval( $_REQUEST['user_id'] ) : $object_id ); + $this->user_metabox(); + } + } + + /** + * Display metaboxes for a user object. + * + * @since 1.0.0 + */ + public function user_metabox() { + $this->show_form_for_type( 'user' ); + } + + /** + * Display metaboxes for a taxonomy term object. + * + * @since 2.2.0 + */ + public function term_metabox() { + $this->show_form_for_type( 'term' ); + } + + /** + * Display metaboxes for an object type. + * + * @since 2.2.0 + * @param string $type Object type. + * @return void + */ + public function show_form_for_type( $type ) { + if ( $type != $this->object_type ) { + return; + } + + if ( ! $this->show_on() ) { + return; + } + + if ( $this->cmb->prop( 'cmb_styles' ) ) { + self::enqueue_cmb_css(); + } + if ( $this->cmb->prop( 'enqueue_js' ) ) { + self::enqueue_cmb_js(); + } + + $this->cmb->show_form( 0, $type ); + } + + /** + * Determines if metabox should be shown in current context. + * + * @since 2.0.0 + * @return bool Whether metabox should be added/shown. + */ + public function show_on() { + // If metabox is requesting to be conditionally shown. + $show = $this->cmb->should_show(); + + /** + * Filter to determine if metabox should show. Default is true. + * + * @param array $show Default is true, show the metabox. + * @param mixed $meta_box_args Array of the metabox arguments. + * @param mixed $cmb The CMB2 instance. + */ + $show = (bool) apply_filters( 'cmb2_show_on', $show, $this->cmb->meta_box, $this->cmb ); + + return $show; + } + + /** + * Get the CMB priority property set to numeric hook priority. + * + * @since 2.2.0 + * + * @param integer $default Default display hook priority. + * @return integer Hook priority. + */ + public function get_priority( $default = 10 ) { + $priority = $this->cmb->prop( 'priority' ); + + if ( ! is_numeric( $priority ) ) { + switch ( $priority ) { + + case 'high': + $priority = 5; + break; + + case 'low': + $priority = 20; + break; + + default: + $priority = $default; + break; + } + } + + return $priority; + } + + /** + * Save data from post metabox + * + * @since 1.0.0 + * @param int $post_id Post ID. + * @param mixed $post Post object. + * @return void + */ + public function save_post( $post_id, $post = false ) { + + $post_type = $post ? $post->post_type : get_post_type( $post_id ); + + $do_not_pass_go = ( + ! $this->can_save( $post_type ) + // Check user editing permissions. + || ( 'page' == $post_type && ! current_user_can( 'edit_page', $post_id ) ) + || ! current_user_can( 'edit_post', $post_id ) + ); + + if ( $do_not_pass_go ) { + return; + } + + $this->cmb->save_fields( $post_id, 'post', $_POST ); + } + + /** + * Save data from comment metabox. + * + * @since 2.0.9 + * @param int $comment_id Comment ID. + * @return void + */ + public function save_comment( $comment_id ) { + + $can_edit = current_user_can( 'moderate_comments', $comment_id ); + + if ( $this->can_save( get_comment_type( $comment_id ) ) && $can_edit ) { + $this->cmb->save_fields( $comment_id, 'comment', $_POST ); + } + } + + /** + * Save data from user fields. + * + * @since 1.0.x + * @param int $user_id User ID. + * @return void + */ + public function save_user( $user_id ) { + // check permissions. + if ( $this->can_save( 'user' ) ) { + $this->cmb->save_fields( $user_id, 'user', $_POST ); + } + } + + /** + * Save data from term fields + * + * @since 2.2.0 + * @param int $term_id Term ID. + * @param int $tt_id Term Taxonomy ID. + * @param string $taxonomy Taxonomy. + * @return void + */ + public function save_term( $term_id, $tt_id, $taxonomy = '' ) { + $taxonomy = $taxonomy ? $taxonomy : $tt_id; + + // check permissions. + if ( $this->taxonomy_can_save( $taxonomy ) && $this->can_save( 'term' ) ) { + $this->cmb->save_fields( $term_id, 'term', $_POST ); + } + } + + /** + * Delete term meta when a term is deleted. + * + * @since 2.2.0 + * @param int $term_id Term ID. + * @param int $tt_id Term Taxonomy ID. + * @param string $taxonomy Taxonomy. + * @return void + */ + public function delete_term( $term_id, $tt_id, $taxonomy = '' ) { + if ( $this->taxonomy_can_save( $taxonomy ) ) { + + $data_to_delete = array(); + foreach ( $this->cmb->prop( 'fields' ) as $field ) { + $data_to_delete[ $field['id'] ] = ''; + } + + $this->cmb->save_fields( $term_id, 'term', $data_to_delete ); + } + } + + /** + * Determines if the current object is able to be saved. + * + * @since 2.0.9 + * @param string $type Current object type. + * @return bool Whether object can be saved. + */ + public function can_save( $type = '' ) { + + $can_save = ( + $this->cmb->prop( 'save_fields' ) + // check nonce. + && isset( $_POST[ $this->cmb->nonce() ] ) + && wp_verify_nonce( $_POST[ $this->cmb->nonce() ], $this->cmb->nonce() ) + // check if autosave. + && ! ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) + // get the metabox types & compare it to this type. + && ( $type && in_array( $type, $this->cmb->box_types() ) ) + // Don't do updates during a switch-to-blog instance. + && ! ( is_multisite() && ms_is_switched() ) + ); + + /** + * Filter to determine if metabox is allowed to save. + * + * @param bool $can_save Whether the current metabox can save. + * @param object $cmb The CMB2 instance. + */ + return apply_filters( 'cmb2_can_save', $can_save, $this->cmb ); + } + + /** + * Determine if taxonomy of term being modified is cmb2-editable. + * + * @since 2.2.0 + * + * @param string $taxonomy Taxonomy of term being modified. + * @return bool Whether taxonomy is editable. + */ + public function taxonomy_can_save( $taxonomy ) { + if ( empty( $this->taxonomies ) || ! in_array( $taxonomy, $this->taxonomies ) ) { + return false; + } + + $taxonomy_object = get_taxonomy( $taxonomy ); + // Can the user edit this term? + if ( ! isset( $taxonomy_object->cap ) || ! current_user_can( $taxonomy_object->cap->edit_terms ) ) { + return false; + } + + return true; + } + + /** + * Enqueues the 'cmb2-display-styles' if the conditions match (has columns, on the right page, etc). + * + * @since 2.2.2.1 + */ + protected function maybe_enqueue_column_display_styles() { + global $pagenow; + if ( + $pagenow + && $this->cmb->has_columns + && $this->cmb->prop( 'cmb_styles' ) + && in_array( $pagenow, array( 'edit.php', 'users.php', 'edit-comments.php', 'edit-tags.php' ), 1 ) + ) { + self::enqueue_cmb_css( 'cmb2-display-styles' ); + } + } + + /** + * Includes CMB2 styles. + * + * @since 2.0.0 + * + * @param string $handle CSS handle. + * @return mixed + */ + public static function enqueue_cmb_css( $handle = 'cmb2-styles' ) { + + /** + * Filter to determine if CMB2'S css should be enqueued. + * + * @param bool $enqueue_css Default is true. + */ + if ( ! apply_filters( 'cmb2_enqueue_css', true ) ) { + return false; + } + + self::register_styles(); + + /* + * White list the options as this method can be used as a hook callback + * and have a different argument passed. + */ + return wp_enqueue_style( 'cmb2-display-styles' === $handle ? $handle : 'cmb2-styles' ); + } + + /** + * Includes CMB2 JS. + * + * @since 2.0.0 + */ + public static function enqueue_cmb_js() { + + /** + * Filter to determine if CMB2'S JS should be enqueued. + * + * @param bool $enqueue_js Default is true. + */ + if ( ! apply_filters( 'cmb2_enqueue_js', true ) ) { + return false; + } + + self::register_js(); + return true; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/helper-functions.php b/inc/vendors/cmb2-plugins/cmb2/includes/helper-functions.php new file mode 100755 index 00000000..d0a87760 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/helper-functions.php @@ -0,0 +1,426 @@ +get_oembed_no_edit( $args ); + + // Send back our embed. + if ( $oembed['embed'] && $oembed['embed'] != $oembed['fallback'] ) { + return '
            ' . $oembed['embed'] . '
            '; + } + + $error = sprintf( + /* translators: 1: results for. 2: link to codex.wordpress.org/Embeds */ + esc_html__( 'No oEmbed Results Found for %1$s. View more info at %2$s.', 'cmb2' ), + $oembed['fallback'], + 'codex.wordpress.org/Embeds' + ); + + if ( isset( $args['wp_error'] ) && $args['wp_error'] ) { + return new WP_Error( 'cmb2_get_oembed_result', $error, compact( 'oembed', 'args' ) ); + } + + // Otherwise, send back error info that no oEmbeds were found. + return '

            ' . $error . '

            '; +} + +/** + * Outputs the return of cmb2_get_oembed. + * + * @since 2.2.2 + * @see cmb2_get_oembed + * + * @param array $args oEmbed args. + */ +function cmb2_do_oembed( $args = array() ) { + echo cmb2_get_oembed( $args ); +} +add_action( 'cmb2_do_oembed', 'cmb2_do_oembed' ); + +/** + * A helper function to get an option from a CMB2 options array + * + * @since 1.0.1 + * @param string $option_key Option key. + * @param string $field_id Option array field key. + * @param mixed $default Optional default fallback value. + * @return array Options array or specific field + */ +function cmb2_get_option( $option_key, $field_id = '', $default = false ) { + return cmb2_options( $option_key )->get( $field_id, $default ); +} + +/** + * A helper function to update an option in a CMB2 options array + * + * @since 2.0.0 + * @param string $option_key Option key. + * @param string $field_id Option array field key. + * @param mixed $value Value to update data with. + * @param boolean $single Whether data should not be an array. + * @return boolean Success/Failure + */ +function cmb2_update_option( $option_key, $field_id, $value, $single = true ) { + if ( cmb2_options( $option_key )->update( $field_id, $value, false, $single ) ) { + return cmb2_options( $option_key )->set(); + } + + return false; +} + +/** + * Get a CMB2 field object. + * + * @since 1.1.0 + * @param array $meta_box Metabox ID or Metabox config array. + * @param array $field_id Field ID or all field arguments. + * @param int $object_id Object ID. + * @param string $object_type Type of object being saved. (e.g., post, user, comment, or options-page). + * Defaults to metabox object type. + * @return CMB2_Field|null CMB2_Field object unless metabox config cannot be found + */ +function cmb2_get_field( $meta_box, $field_id, $object_id = 0, $object_type = '' ) { + + $object_id = $object_id ? $object_id : get_the_ID(); + $cmb = $meta_box instanceof CMB2 ? $meta_box : cmb2_get_metabox( $meta_box, $object_id ); + + if ( ! $cmb ) { + return; + } + + $cmb->object_type( $object_type ? $object_type : $cmb->mb_object_type() ); + + return $cmb->get_field( $field_id ); +} + +/** + * Get a field's value. + * + * @since 1.1.0 + * @param array $meta_box Metabox ID or Metabox config array. + * @param array $field_id Field ID or all field arguments. + * @param int $object_id Object ID. + * @param string $object_type Type of object being saved. (e.g., post, user, comment, or options-page). + * Defaults to metabox object type. + * @return mixed Maybe escaped value + */ +function cmb2_get_field_value( $meta_box, $field_id, $object_id = 0, $object_type = '' ) { + $field = cmb2_get_field( $meta_box, $field_id, $object_id, $object_type ); + return $field->escaped_value(); +} + +/** + * Because OOP can be scary + * + * @since 2.0.2 + * @param array $meta_box_config Metabox Config array. + * @return CMB2 object Instantiated CMB2 object + */ +function new_cmb2_box( array $meta_box_config ) { + return cmb2_get_metabox( $meta_box_config ); +} + +/** + * Retrieve a CMB2 instance by the metabox ID + * + * @since 2.0.0 + * @param mixed $meta_box Metabox ID or Metabox config array. + * @param int $object_id Object ID. + * @param string $object_type Type of object being saved. (e.g., post, user, comment, or options-page). + * Defaults to metabox object type. + * @return CMB2 object + */ +function cmb2_get_metabox( $meta_box, $object_id = 0, $object_type = '' ) { + + if ( $meta_box instanceof CMB2 ) { + return $meta_box; + } + + if ( is_string( $meta_box ) ) { + $cmb = CMB2_Boxes::get( $meta_box ); + } else { + // See if we already have an instance of this metabox. + $cmb = CMB2_Boxes::get( $meta_box['id'] ); + // If not, we'll initate a new metabox. + $cmb = $cmb ? $cmb : new CMB2( $meta_box, $object_id ); + } + + if ( $cmb && $object_id ) { + $cmb->object_id( $object_id ); + } + + if ( $cmb && $object_type ) { + $cmb->object_type( $object_type ); + } + + return $cmb; +} + +/** + * Returns array of sanitized field values from a metabox (without saving them) + * + * @since 2.0.3 + * @param mixed $meta_box Metabox ID or Metabox config array. + * @param array $data_to_sanitize Array of field_id => value data for sanitizing (likely $_POST data). + * @return mixed Array of sanitized values or false if no CMB2 object found + */ +function cmb2_get_metabox_sanitized_values( $meta_box, array $data_to_sanitize ) { + $cmb = cmb2_get_metabox( $meta_box ); + return $cmb ? $cmb->get_sanitized_values( $data_to_sanitize ) : false; +} + +/** + * Retrieve a metabox form + * + * @since 2.0.0 + * @param mixed $meta_box Metabox config array or Metabox ID. + * @param int $object_id Object ID. + * @param array $args Optional arguments array. + * @return string CMB2 html form markup + */ +function cmb2_get_metabox_form( $meta_box, $object_id = 0, $args = array() ) { + + $object_id = $object_id ? $object_id : get_the_ID(); + $cmb = cmb2_get_metabox( $meta_box, $object_id ); + + ob_start(); + // Get cmb form. + cmb2_print_metabox_form( $cmb, $object_id, $args ); + $form = ob_get_clean(); + + return apply_filters( 'cmb2_get_metabox_form', $form, $object_id, $cmb ); +} + +/** + * Display a metabox form & save it on submission + * + * @since 1.0.0 + * @param mixed $meta_box Metabox config array or Metabox ID. + * @param int $object_id Object ID. + * @param array $args Optional arguments array. + */ +function cmb2_print_metabox_form( $meta_box, $object_id = 0, $args = array() ) { + + $object_id = $object_id ? $object_id : get_the_ID(); + $cmb = cmb2_get_metabox( $meta_box, $object_id ); + + // if passing a metabox ID, and that ID was not found. + if ( ! $cmb ) { + return; + } + + $args = wp_parse_args( $args, array( + 'form_format' => '
            %3$s
            ', + 'save_button' => esc_html__( 'Save', 'cmb2' ), + 'object_type' => $cmb->mb_object_type(), + 'cmb_styles' => $cmb->prop( 'cmb_styles' ), + 'enqueue_js' => $cmb->prop( 'enqueue_js' ), + ) ); + + // Set object type explicitly (rather than trying to guess from context). + $cmb->object_type( $args['object_type'] ); + + // Save the metabox if it's been submitted + // check permissions + // @todo more hardening? + if ( + $cmb->prop( 'save_fields' ) + // check nonce. + && isset( $_POST['submit-cmb'], $_POST['object_id'], $_POST[ $cmb->nonce() ] ) + && wp_verify_nonce( $_POST[ $cmb->nonce() ], $cmb->nonce() ) + && $object_id && $_POST['object_id'] == $object_id + ) { + $cmb->save_fields( $object_id, $cmb->object_type(), $_POST ); + } + + // Enqueue JS/CSS. + if ( $args['cmb_styles'] ) { + CMB2_hookup::enqueue_cmb_css(); + } + + if ( $args['enqueue_js'] ) { + CMB2_hookup::enqueue_cmb_js(); + } + + $form_format = apply_filters( 'cmb2_get_metabox_form_format', $args['form_format'], $object_id, $cmb ); + + $format_parts = explode( '%3$s', $form_format ); + + // Show cmb form. + printf( $format_parts[0], $cmb->cmb_id, $object_id ); + $cmb->show_form(); + + if ( isset( $format_parts[1] ) && $format_parts[1] ) { + printf( str_ireplace( '%4$s', '%1$s', $format_parts[1] ), $args['save_button'] ); + } + +} + +/** + * Display a metabox form (or optionally return it) & save it on submission. + * + * @since 1.0.0 + * @param mixed $meta_box Metabox config array or Metabox ID. + * @param int $object_id Object ID. + * @param array $args Optional arguments array. + * @return string + */ +function cmb2_metabox_form( $meta_box, $object_id = 0, $args = array() ) { + if ( ! isset( $args['echo'] ) || $args['echo'] ) { + cmb2_print_metabox_form( $meta_box, $object_id, $args ); + } else { + return cmb2_get_metabox_form( $meta_box, $object_id, $args ); + } +} + +if ( ! function_exists( 'date_create_from_format' ) ) { + + /** + * Reimplementation of DateTime::createFromFormat for PHP < 5.3. :( + * Borrowed from http://stackoverflow.com/questions/5399075/php-datetimecreatefromformat-in-5-2 + * + * @param string $date_format Date format. + * @param string $date_value Date value. + * + * @return DateTime + */ + function date_create_from_format( $date_format, $date_value ) { + + $schedule_format = str_replace( + array( 'M', 'Y', 'm', 'd', 'H', 'i', 'a' ), + array( '%b', '%Y', '%m', '%d', '%H', '%M', '%p' ), + $date_format + ); + + /* + * %Y, %m and %d correspond to date()'s Y m and d. + * %I corresponds to H, %M to i and %p to a + */ + $parsed_time = strptime( $date_value, $schedule_format ); + + $ymd = sprintf( + /** + * This is a format string that takes six total decimal + * arguments, then left-pads them with zeros to either + * 4 or 2 characters, as needed + */ + '%04d-%02d-%02d %02d:%02d:%02d', + $parsed_time['tm_year'] + 1900, // This will be "111", so we need to add 1900. + $parsed_time['tm_mon'] + 1, // This will be the month minus one, so we add one. + $parsed_time['tm_mday'], + $parsed_time['tm_hour'], + $parsed_time['tm_min'], + $parsed_time['tm_sec'] + ); + + return new DateTime( $ymd ); + } +}// End if. + +if ( ! function_exists( 'date_timestamp_get' ) ) { + + /** + * Returns the Unix timestamp representing the date. + * Reimplementation of DateTime::getTimestamp for PHP < 5.3. :( + * + * @param DateTime $date DateTime instance. + * + * @return int + */ + function date_timestamp_get( DateTime $date ) { + return $date->format( 'U' ); + } +}// End if. diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/index.php b/inc/vendors/cmb2-plugins/cmb2/includes/index.php new file mode 100755 index 00000000..eea59b98 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/index.php @@ -0,0 +1,2 @@ + array(), + 'user' => array(), + 'comment' => array(), + 'term' => array(), + ); + + /** + * Array of readable field objects. + * + * @var CMB2_Field[] + * @since 2.2.3 + */ + protected $read_fields = array(); + + /** + * Array of editable field objects. + * + * @var CMB2_Field[] + * @since 2.2.3 + */ + protected $edit_fields = array(); + + /** + * Whether CMB2 object is readable via the rest api. + * + * @var boolean + */ + protected $rest_read = false; + + /** + * Whether CMB2 object is editable via the rest api. + * + * @var boolean + */ + protected $rest_edit = false; + + /** + * A functionalized constructor, used for the hookup action callbacks. + * + * @since 2.2.6 + * + * @param CMB2 $cmb The CMB2 object to hookup + * + * @return CMB2_Hookup_Base $hookup The hookup object. + */ + public static function maybe_init_and_hookup( CMB2 $cmb ) { + if ( $cmb->prop( 'show_in_rest' ) && function_exists( 'rest_get_server' ) ) { + + $hookup = new self( $cmb ); + + return $hookup->universal_hooks(); + } + + return false; + } + + /** + * Constructor + * + * @since 2.2.3 + * + * @param CMB2 $cmb The CMB2 object to be registered for the API. + */ + public function __construct( CMB2 $cmb ) { + $this->cmb = $cmb; + self::$boxes[ $cmb->cmb_id ] = $this; + + $show_value = $this->cmb->prop( 'show_in_rest' ); + + $this->rest_read = self::is_readable( $show_value ); + $this->rest_edit = self::is_editable( $show_value ); + } + + /** + * Hooks to register on frontend and backend. + * + * @since 2.2.3 + * + * @return void + */ + public function universal_hooks() { + // hook up the CMB rest endpoint classes + $this->once( 'rest_api_init', array( __CLASS__, 'init_routes' ), 0 ); + + if ( function_exists( 'register_rest_field' ) ) { + $this->once( 'rest_api_init', array( __CLASS__, 'register_cmb2_fields' ), 50 ); + } + + $this->declare_read_edit_fields(); + + add_filter( 'is_protected_meta', array( $this, 'is_protected_meta' ), 10, 3 ); + + return $this; + } + + /** + * Initiate the CMB2 Boxes and Fields routes + * + * @since 2.2.3 + * + * @return void + */ + public static function init_routes() { + $wp_rest_server = rest_get_server(); + + $boxes_controller = new CMB2_REST_Controller_Boxes( $wp_rest_server ); + $boxes_controller->register_routes(); + + $fields_controller = new CMB2_REST_Controller_Fields( $wp_rest_server ); + $fields_controller->register_routes(); + } + + /** + * Loop through REST boxes and call register_rest_field for each object type. + * + * @since 2.2.3 + * + * @return void + */ + public static function register_cmb2_fields() { + $alltypes = $taxonomies = array(); + + foreach ( self::$boxes as $cmb_id => $rest_box ) { + $types = array_flip( $rest_box->cmb->box_types( array( 'post' ) ) ); + + if ( isset( $types['user'] ) ) { + unset( $types['user'] ); + self::$type_boxes['user'][ $cmb_id ] = $cmb_id; + } + + if ( isset( $types['comment'] ) ) { + unset( $types['comment'] ); + self::$type_boxes['comment'][ $cmb_id ] = $cmb_id; + } + + if ( isset( $types['term'] ) ) { + unset( $types['term'] ); + + $taxonomies = array_merge( + $taxonomies, + CMB2_Utils::ensure_array( $rest_box->cmb->prop( 'taxonomies' ) ) + ); + + self::$type_boxes['term'][ $cmb_id ] = $cmb_id; + } + + if ( ! empty( $types ) ) { + $alltypes = array_merge( $alltypes, array_flip( $types ) ); + self::$type_boxes['post'][ $cmb_id ] = $cmb_id; + } + } + + $alltypes = array_unique( $alltypes ); + + if ( ! empty( $alltypes ) ) { + self::register_rest_field( $alltypes, 'post' ); + } + + if ( ! empty( self::$type_boxes['user'] ) ) { + self::register_rest_field( 'user', 'user' ); + } + + if ( ! empty( self::$type_boxes['comment'] ) ) { + self::register_rest_field( 'comment', 'comment' ); + } + + if ( ! empty( self::$type_boxes['term'] ) ) { + self::register_rest_field( $taxonomies, 'term' ); + } + } + + /** + * Wrapper for register_rest_field. + * + * @since 2.2.3 + * + * @param string|array $object_types Object(s) the field is being registered + * to, "post"|"term"|"comment" etc. + * @param string $object_types Canonical object type for callbacks. + * + * @return void + */ + protected static function register_rest_field( $object_types, $object_type ) { + register_rest_field( $object_types, 'cmb2', array( + 'get_callback' => array( __CLASS__, "get_{$object_type}_rest_values" ), + 'update_callback' => array( __CLASS__, "update_{$object_type}_rest_values" ), + 'schema' => null, // @todo add schema + ) ); + } + + /** + * Setup readable and editable fields. + * + * @since 2.2.3 + * + * @return void + */ + protected function declare_read_edit_fields() { + foreach ( $this->cmb->prop( 'fields' ) as $field ) { + $show_in_rest = isset( $field['show_in_rest'] ) ? $field['show_in_rest'] : null; + + if ( false === $show_in_rest ) { + continue; + } + + if ( $this->can_read( $show_in_rest ) ) { + $this->read_fields[] = $field['id']; + } + + if ( $this->can_edit( $show_in_rest ) ) { + $this->edit_fields[] = $field['id']; + } + } + } + + /** + * Determines if a field is readable based on it's show_in_rest value + * and the box's show_in_rest value. + * + * @since 2.2.3 + * + * @param bool $show_in_rest Field's show_in_rest value. Default null. + * + * @return bool Whether field is readable. + */ + protected function can_read( $show_in_rest ) { + // if 'null', then use default box value. + if ( null === $show_in_rest ) { + return $this->rest_read; + } + + // Else check if the value represents readable. + return self::is_readable( $show_in_rest ); + } + + /** + * Determines if a field is editable based on it's show_in_rest value + * and the box's show_in_rest value. + * + * @since 2.2.3 + * + * @param bool $show_in_rest Field's show_in_rest value. Default null. + * + * @return bool Whether field is editable. + */ + protected function can_edit( $show_in_rest ) { + // if 'null', then use default box value. + if ( null === $show_in_rest ) { + return $this->rest_edit; + } + + // Else check if the value represents editable. + return self::is_editable( $show_in_rest ); + } + + /** + * Handler for getting post custom field data. + * + * @since 2.2.3 + * + * @param array $object The object data from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return mixed + */ + public static function get_post_rest_values( $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::get_rest_values( $object, $request, $object_type, 'post' ); + } + } + + /** + * Handler for getting user custom field data. + * + * @since 2.2.3 + * + * @param array $object The object data from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return mixed + */ + public static function get_user_rest_values( $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::get_rest_values( $object, $request, $object_type, 'user' ); + } + } + + /** + * Handler for getting comment custom field data. + * + * @since 2.2.3 + * + * @param array $object The object data from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return mixed + */ + public static function get_comment_rest_values( $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::get_rest_values( $object, $request, $object_type, 'comment' ); + } + } + + /** + * Handler for getting term custom field data. + * + * @since 2.2.3 + * + * @param array $object The object data from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return mixed + */ + public static function get_term_rest_values( $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::get_rest_values( $object, $request, $object_type, 'term' ); + } + } + + /** + * Handler for getting custom field data. + * + * @since 2.2.3 + * + * @param array $object The object data from the response + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * @param string $main_object_type The cmb main object type + * + * @return mixed + */ + protected static function get_rest_values( $object, $request, $object_type, $main_object_type = 'post' ) { + if ( ! isset( $object['id'] ) ) { + return; + } + + $values = array(); + + if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) { + foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) { + $rest_box = self::$boxes[ $cmb_id ]; + + foreach ( $rest_box->read_fields as $field_id ) { + $rest_box->cmb->object_id( $object['id'] ); + $rest_box->cmb->object_type( $main_object_type ); + + $field = $rest_box->cmb->get_field( $field_id ); + + $field->object_id( $object['id'] ); + $field->object_type( $main_object_type ); + + $values[ $cmb_id ][ $field->id( true ) ] = $field->get_data(); + } + } + } + + return $values; + } + + /** + * Handler for updating post custom field data. + * + * @since 2.2.3 + * + * @param mixed $values The value of the field + * @param object $object The object from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return bool|int + */ + public static function update_post_rest_values( $values, $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::update_rest_values( $values, $object, $request, $object_type, 'post' ); + } + } + + /** + * Handler for updating user custom field data. + * + * @since 2.2.3 + * + * @param mixed $values The value of the field + * @param object $object The object from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return bool|int + */ + public static function update_user_rest_values( $values, $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::update_rest_values( $values, $object, $request, $object_type, 'user' ); + } + } + + /** + * Handler for updating comment custom field data. + * + * @since 2.2.3 + * + * @param mixed $values The value of the field + * @param object $object The object from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return bool|int + */ + public static function update_comment_rest_values( $values, $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::update_rest_values( $values, $object, $request, $object_type, 'comment' ); + } + } + + /** + * Handler for updating term custom field data. + * + * @since 2.2.3 + * + * @param mixed $values The value of the field + * @param object $object The object from the response + * @param string $field_name Name of field + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * + * @return bool|int + */ + public static function update_term_rest_values( $values, $object, $field_name, $request, $object_type ) { + if ( 'cmb2' === $field_name ) { + return self::update_rest_values( $values, $object, $request, $object_type, 'term' ); + } + } + + /** + * Handler for updating custom field data. + * + * @since 2.2.3 + * + * @param mixed $values The value of the field + * @param object $object The object from the response + * @param WP_REST_Request $request Current request + * @param string $object_type The request object type + * @param string $main_object_type The cmb main object type + * + * @return bool|int + */ + protected static function update_rest_values( $values, $object, $request, $object_type, $main_object_type = 'post' ) { + if ( empty( $values ) || ! is_array( $values ) ) { + return; + } + + $object_id = self::get_object_id( $object, $main_object_type ); + + if ( ! $object_id ) { + return; + } + + $updated = array(); + + if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) { + foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) { + $rest_box = self::$boxes[ $cmb_id ]; + + if ( ! array_key_exists( $cmb_id, $values ) ) { + continue; + } + + $rest_box->cmb->object_id( $object_id ); + $rest_box->cmb->object_type( $main_object_type ); + + $updated[ $cmb_id ] = $rest_box->sanitize_box_values( $values ); + } + } + + return $updated; + } + + /** + * Loop through box fields and sanitize the values. + * + * @since 2.2.o + * + * @param array $values Array of values being provided. + * @return array Array of updated/sanitized values. + */ + public function sanitize_box_values( array $values ) { + $updated = array(); + + $this->cmb->pre_process(); + + foreach ( $this->edit_fields as $field_id ) { + $updated[ $field_id ] = $this->sanitize_field_value( $values, $field_id ); + } + + $this->cmb->after_save(); + + return $updated; + } + + /** + * Handles returning a sanitized field value. + * + * @since 2.2.3 + * + * @param array $values Array of values being provided. + * @param string $field_id The id of the field to update. + * + * @return mixed The results of saving/sanitizing a field value. + */ + protected function sanitize_field_value( array $values, $field_id ) { + if ( ! array_key_exists( $field_id, $values[ $this->cmb->cmb_id ] ) ) { + return; + } + + $field = $this->cmb->get_field( $field_id ); + + if ( 'title' == $field->type() ) { + return; + } + + $field->object_id( $this->cmb->object_id() ); + $field->object_type( $this->cmb->object_type() ); + + if ( 'group' == $field->type() ) { + return $this->sanitize_group_value( $values, $field ); + } + + return $field->save_field( $values[ $this->cmb->cmb_id ][ $field_id ] ); + } + + /** + * Handles returning a sanitized group field value. + * + * @since 2.2.3 + * + * @param array $values Array of values being provided. + * @param CMB2_Field $field CMB2_Field object. + * + * @return mixed The results of saving/sanitizing the group field value. + */ + protected function sanitize_group_value( array $values, CMB2_Field $field ) { + $fields = $field->fields(); + if ( empty( $fields ) ) { + return; + } + + $this->cmb->data_to_save[ $field->_id() ] = $values[ $this->cmb->cmb_id ][ $field->_id() ]; + + return $this->cmb->save_group_field( $field ); + } + + /** + * Filter whether a meta key is protected. + * + * @since 2.2.3 + * + * @param bool $protected Whether the key is protected. Default false. + * @param string $meta_key Meta key. + * @param string $meta_type Meta type. + */ + public function is_protected_meta( $protected, $meta_key, $meta_type ) { + if ( $this->field_can_edit( $meta_key ) ) { + return false; + } + + return $protected; + } + + protected static function get_object_id( $object, $object_type = 'post' ) { + switch ( $object_type ) { + case 'user': + case 'post': + if ( isset( $object->ID ) ) { + return intval( $object->ID ); + } + case 'comment': + if ( isset( $object->comment_ID ) ) { + return intval( $object->comment_ID ); + } + case 'term': + if ( is_array( $object ) && isset( $object['term_id'] ) ) { + return intval( $object['term_id'] ); + } elseif ( isset( $object->term_id ) ) { + return intval( $object->term_id ); + } + } + + return 0; + } + + /** + * Checks if a given field can be read. + * + * @since 2.2.3 + * + * @param string|CMB2_Field $field_id Field ID or CMB2_Field object. + * @param boolean $return_object Whether to return the Field object. + * + * @return mixed False if field can't be read or true|CMB2_Field object. + */ + public function field_can_read( $field_id, $return_object = false ) { + return $this->field_can( 'read_fields', $field_id, $return_object ); + } + + /** + * Checks if a given field can be edited. + * + * @since 2.2.3 + * + * @param string|CMB2_Field $field_id Field ID or CMB2_Field object. + * @param boolean $return_object Whether to return the Field object. + * + * @return mixed False if field can't be edited or true|CMB2_Field object. + */ + public function field_can_edit( $field_id, $return_object = false ) { + return $this->field_can( 'edit_fields', $field_id, $return_object ); + } + + /** + * Checks if a given field can be read or edited. + * + * @since 2.2.3 + * + * @param string $type Whether we are checking for read or edit fields. + * @param string|CMB2_Field $field_id Field ID or CMB2_Field object. + * @param boolean $return_object Whether to return the Field object. + * + * @return mixed False if field can't be read or edited or true|CMB2_Field object. + */ + protected function field_can( $type = 'read_fields', $field_id, $return_object = false ) { + if ( ! in_array( $field_id instanceof CMB2_Field ? $field_id->id() : $field_id, $this->{$type}, true ) ) { + return false; + } + + return $return_object ? $this->cmb->get_field( $field_id ) : true; + } + + /** + * Get a CMB2_REST instance object from the registry by a CMB2 id. + * + * @since 2.2.3 + * + * @param string $cmb_id CMB2 config id + * + * @return CMB2_REST|false The CMB2_REST object or false. + */ + public static function get_rest_box( $cmb_id ) { + return isset( self::$boxes[ $cmb_id ] ) ? self::$boxes[ $cmb_id ] : false; + } + + /** + * Remove a CMB2_REST instance object from the registry. + * + * @since 2.2.3 + * + * @param string $cmb_id A CMB2 instance id. + */ + public static function remove( $cmb_id ) { + if ( array_key_exists( $cmb_id, self::$boxes ) ) { + unset( self::$boxes[ $cmb_id ] ); + } + } + + /** + * Retrieve all CMB2_REST instances from the registry. + * + * @since 2.2.3 + * @return CMB2[] Array of all registered CMB2_REST instances. + */ + public static function get_all() { + return self::$boxes; + } + + /** + * Checks if given value is readable. + * + * Value is considered readable if it is not empty and if it does not match the editable blacklist. + * + * @since 2.2.3 + * + * @param mixed $value Value to check. + * + * @return boolean Whether value is considered readable. + */ + public static function is_readable( $value ) { + return ! empty( $value ) && ! in_array( $value, array( + WP_REST_Server::CREATABLE, + WP_REST_Server::EDITABLE, + WP_REST_Server::DELETABLE, + ), true ); + } + + /** + * Checks if given value is editable. + * + * Value is considered editable if matches the editable whitelist. + * + * @since 2.2.3 + * + * @param mixed $value Value to check. + * + * @return boolean Whether value is considered editable. + */ + public static function is_editable( $value ) { + return in_array( $value, array( + WP_REST_Server::EDITABLE, + WP_REST_Server::ALLMETHODS, + ), true ); + } + + /** + * Magic getter for our object. + * + * @param string $field + * @throws Exception Throws an exception if the field is invalid. + * + * @return mixed + */ + public function __get( $field ) { + switch ( $field ) { + case 'read_fields': + case 'edit_fields': + case 'rest_read': + case 'rest_edit': + return $this->{$field}; + default: + throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . $field ); + } + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller.php b/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller.php new file mode 100755 index 00000000..6f201702 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller.php @@ -0,0 +1,448 @@ +server = $wp_rest_server; + } + + /** + * A wrapper for `apply_filters` which checks for box/field properties to hook to the filter. + * + * Checks if a CMB object callback property exists, and if it does, + * hook it to the permissions filter. + * + * @since 2.2.3 + * + * @param string $filter The name of the filter to apply. + * @param bool $default_access The default access for this request. + * + * @return void + */ + public function maybe_hook_callback_and_apply_filters( $filter, $default_access ) { + if ( ! $this->rest_box && $this->request->get_param( 'cmb_id' ) ) { + $this->rest_box = CMB2_REST::get_rest_box( $this->request->get_param( 'cmb_id' ) ); + } + + $default_access = $this->maybe_hook_registered_callback( $filter, $default_access ); + + /** + * Apply the permissions check filter. + * + * @since 2.2.3 + * + * @param bool $default_access Whether this CMB2 endpoint can be accessed. + * @param object $controller This CMB2_REST_Controller object. + */ + $default_access = apply_filters( $filter, $default_access, $this ); + + $this->maybe_unhook_registered_callback( $filter ); + + return $default_access; + } + + /** + * Checks if the CMB2 box has any registered callback parameters for the given filter. + * + * The registered handlers will have a property name which matches the filter, except: + * - The 'cmb2_api' prefix will be removed + * - A '_cb' suffix will be added (to stay inline with other '*_cb' parameters). + * + * @since 2.2.3 + * + * @param string $filter The filter name. + * @param bool $default_val The default filter value. + * + * @return bool The possibly-modified filter value (if the '*_cb' param is non-callable). + */ + public function maybe_hook_registered_callback( $filter, $default_val ) { + if ( ! $this->rest_box || is_wp_error( $this->rest_box ) ) { + return $default_val; + } + + // Hook box specific filter callbacks. + $val = $this->rest_box->cmb->maybe_hook_parameter( $filter, $default_val ); + if ( null !== $val ) { + $default_val = $val; + } + + return $default_val; + } + + /** + * Unhooks any CMB2 box registered callback parameters for the given filter. + * + * @since 2.2.3 + * + * @param string $filter The filter name. + * + * @return void + */ + public function maybe_unhook_registered_callback( $filter ) { + if ( ! $this->rest_box || is_wp_error( $this->rest_box ) ) { + return; + } + + // Unhook box specific filter callbacks. + $this->rest_box->cmb->maybe_hook_parameter( $filter, null, 'remove_filter' ); + } + + /** + * Prepare a CMB2 object for serialization + * + * @since 2.2.3 + * + * @param mixed $data + * @return array $data + */ + public function prepare_item( $data ) { + return $this->prepare_item_for_response( $data, $this->request ); + } + + /** + * Output buffers a callback and returns the results. + * + * @since 2.2.3 + * + * @param mixed $cb Callable function/method. + * @return mixed Results of output buffer after calling function/method. + */ + public function get_cb_results( $cb ) { + $args = func_get_args(); + array_shift( $args ); // ignore $cb + ob_start(); + call_user_func_array( $cb, $args ); + + return ob_get_clean(); + } + + /** + * Prepare the CMB2 item for the REST response. + * + * @since 2.2.3 + * + * @param mixed $item WordPress representation of the item. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $data, $request = null ) { + $data = $this->filter_response_by_context( $data, $this->request['context'] ); + + /** + * Filter the prepared CMB2 item response. + * + * @since 2.2.3 + * + * @param mixed $data Prepared data + * @param object $request The WP_REST_Request object + * @param object $cmb2_endpoints This endpoints object + */ + return apply_filters( 'cmb2_rest_prepare', rest_ensure_response( $data ), $this->request, $this ); + } + + /** + * Initiates the request property and the rest_box property if box is readable. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Request object. + * @param string $request_type A description of the type of request being made. + * + * @return void + */ + protected function initiate_rest_read_box( $request, $request_type ) { + $this->initiate_rest_box( $request, $request_type ); + + if ( ! is_wp_error( $this->rest_box ) && ! $this->rest_box->rest_read ) { + $this->rest_box = new WP_Error( 'cmb2_rest_no_read_error', esc_html__( 'This box does not have read permissions.', 'cmb2' ), array( + 'status' => 403, + ) ); + } + } + + /** + * Initiates the request property and the rest_box property if box is writeable. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Request object. + * @param string $request_type A description of the type of request being made. + * + * @return void + */ + protected function initiate_rest_edit_box( $request, $request_type ) { + $this->initiate_rest_box( $request, $request_type ); + + if ( ! is_wp_error( $this->rest_box ) && ! $this->rest_box->rest_edit ) { + $this->rest_box = new WP_Error( 'cmb2_rest_no_write_error', esc_html__( 'This box does not have write permissions.', 'cmb2' ), array( + 'status' => 403, + ) ); + } + } + + /** + * Initiates the request property and the rest_box property. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Request object. + * @param string $request_type A description of the type of request being made. + * + * @return void + */ + protected function initiate_rest_box( $request, $request_type ) { + $this->initiate_request( $request, $request_type ); + + $this->rest_box = CMB2_REST::get_rest_box( $this->request->get_param( 'cmb_id' ) ); + + if ( ! $this->rest_box ) { + + $this->rest_box = new WP_Error( 'cmb2_rest_box_not_found_error', esc_html__( 'No box found by that id. A box needs to be registered with the "show_in_rest" parameter configured.', 'cmb2' ), array( + 'status' => 403, + ) ); + + } else { + + if ( isset( $this->request['object_id'] ) ) { + $this->rest_box->cmb->object_id( sanitize_text_field( $this->request['object_id'] ) ); + } + + if ( isset( $this->request['object_type'] ) ) { + $this->rest_box->cmb->object_type( sanitize_text_field( $this->request['object_type'] ) ); + } + } + } + + /** + * Initiates the request property and sets up the initial static properties. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Request object. + * @param string $request_type A description of the type of request being made. + * + * @return void + */ + public function initiate_request( $request, $request_type ) { + $this->request = $request; + + if ( ! isset( $this->request['context'] ) || empty( $this->request['context'] ) ) { + $this->request['context'] = 'view'; + } + + if ( ! self::$request_type ) { + self::$request_type = $request_type; + } + + if ( ! self::$route ) { + self::$route = $this->request->get_route(); + } + } + + /** + * Useful when getting `_embed`-ed items + * + * @since 2.2.3 + * + * @return string Initial requested type. + */ + public static function get_intial_request_type() { + return self::$request_type; + } + + /** + * Useful when getting `_embed`-ed items + * + * @since 2.2.3 + * + * @return string Initial requested route. + */ + public static function get_intial_route() { + return self::$route; + } + + /** + * Get CMB2 fields schema, conforming to JSON Schema + * + * @since 2.2.3 + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'CMB2', + 'type' => 'object', + 'properties' => array( + 'description' => array( + 'description' => esc_html__( 'A human-readable description of the object.', 'cmb2' ), + 'type' => 'string', + 'context' => array( + 'view', + ), + ), + 'name' => array( + 'description' => esc_html__( 'The id for the object.', 'cmb2' ), + 'type' => 'integer', + 'context' => array( + 'view', + ), + ), + 'name' => array( + 'description' => esc_html__( 'The title for the object.', 'cmb2' ), + 'type' => 'string', + 'context' => array( + 'view', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Return an array of contextual links for endpoint/object + * + * @link http://v2.wp-api.org/extending/linking/ + * @link http://www.iana.org/assignments/link-relations/link-relations.xhtml + * + * @since 2.2.3 + * + * @param mixed $object Object to build links from. + * + * @return array Array of links + */ + abstract protected function prepare_links( $object ); + + /** + * Get whitelisted query strings from URL for appending to link URLS. + * + * @since 2.2.3 + * + * @return string URL query stringl + */ + public function get_query_string() { + $defaults = array( + 'object_id' => 0, + 'object_type' => '', + '_rendered' => '', + // '_embed' => '', + ); + + $query_string = ''; + + foreach ( $defaults as $key => $value ) { + if ( isset( $this->request[ $key ] ) ) { + $query_string .= $query_string ? '&' : '?'; + $query_string .= $key; + if ( $value = sanitize_text_field( $this->request[ $key ] ) ) { + $query_string .= '=' . $value; + } + } + } + + return $query_string; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller_Boxes.php b/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller_Boxes.php new file mode 100755 index 00000000..d568fc27 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller_Boxes.php @@ -0,0 +1,270 @@ +namespace_base = $this->namespace . '/' . $this->rest_base; + parent::__construct( $wp_rest_server ); + } + + /** + * Register the routes for the objects of the controller. + * + * @since 2.2.3 + */ + public function register_routes() { + $args = array( + '_embed' => array( + 'description' => esc_html__( 'Includes the registered fields for the box in the response.', 'cmb2' ), + ), + ); + + // @todo determine what belongs in the context param. + // $args['context'] = $this->get_context_param(); + // $args['context']['required'] = false; + // $args['context']['default'] = 'view'; + // $args['context']['enum'] = array( 'view', 'embed' ); + // Returns all boxes data. + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'callback' => array( $this, 'get_items' ), + 'args' => $args, + ), + 'schema' => array( $this, 'get_item_schema' ), + ) ); + + $args['_rendered'] = array( + 'description' => esc_html__( 'Includes the fully rendered attributes, \'form_open\', \'form_close\', as well as the enqueued \'js_dependencies\' script handles, and \'css_dependencies\' stylesheet handles.', 'cmb2' ), + ); + + // Returns specific box's data. + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'callback' => array( $this, 'get_item' ), + 'args' => $args, + ), + 'schema' => array( $this, 'get_item_schema' ), + ) ); + } + + /** + * Check if a given request has access to get boxes. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $this->initiate_request( $request, __FUNCTION__ ); + + /** + * By default, no special permissions needed. + * + * @since 2.2.3 + * + * @param bool $can_access Whether this CMB2 endpoint can be accessed. + * @param object $controller This CMB2_REST_Controller object. + */ + return apply_filters( 'cmb2_api_get_boxes_permissions_check', true, $this ); + } + + /** + * Get all public CMB2 boxes. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $this->initiate_request( $request, 'boxes_read' ); + + $boxes = CMB2_REST::get_all(); + if ( empty( $boxes ) ) { + return new WP_Error( 'cmb2_rest_no_boxes', esc_html__( 'No boxes found.', 'cmb2' ), array( + 'status' => 403, + ) ); + } + + $boxes_data = array(); + + // Loop and prepare boxes data. + foreach ( $boxes as $this->rest_box ) { + if ( + // Make sure this box can be read + $this->rest_box->rest_read + // And make sure current user can view this box. + && $this->get_item_permissions_check_filter( $this->request ) + ) { + $boxes_data[] = $this->server->response_to_data( + $this->get_rest_box(), + isset( $this->request['_embed'] ) + ); + } + } + + return $this->prepare_item( $boxes_data ); + } + + /** + * Check if a given request has access to a box. + * By default, no special permissions needed, but filtering return value. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $this->initiate_rest_read_box( $request, 'box_read' ); + + return $this->get_item_permissions_check_filter(); + } + + /** + * Check by filter if a given request has access to a box. + * By default, no special permissions needed, but filtering return value. + * + * @since 2.2.3 + * + * @param bool $can_access Whether the current request has access to view the box by default. + * @return WP_Error|boolean + */ + public function get_item_permissions_check_filter( $can_access = true ) { + /** + * By default, no special permissions needed. + * + * @since 2.2.3 + * + * @param bool $can_access Whether this CMB2 endpoint can be accessed. + * @param object $controller This CMB2_REST_Controller object. + */ + return $this->maybe_hook_callback_and_apply_filters( 'cmb2_api_get_box_permissions_check', $can_access ); + } + + /** + * Get one CMB2 box from the collection. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $this->initiate_rest_read_box( $request, 'box_read' ); + + if ( is_wp_error( $this->rest_box ) ) { + return $this->rest_box; + } + + return $this->prepare_item( $this->get_rest_box() ); + } + + /** + * Get a CMB2 box prepared for REST + * + * @since 2.2.3 + * + * @return array + */ + public function get_rest_box() { + $cmb = $this->rest_box->cmb; + + $boxes_data = $cmb->meta_box; + + if ( isset( $this->request['_rendered'] ) && $this->namespace_base !== ltrim( CMB2_REST_Controller::get_intial_route(), '/' ) ) { + $boxes_data['form_open'] = $this->get_cb_results( array( $cmb, 'render_form_open' ) ); + $boxes_data['form_close'] = $this->get_cb_results( array( $cmb, 'render_form_close' ) ); + + global $wp_scripts, $wp_styles; + $before_css = $wp_styles->queue; + $before_js = $wp_scripts->queue; + + CMB2_JS::enqueue(); + + $boxes_data['js_dependencies'] = array_values( array_diff( $wp_scripts->queue, $before_js ) ); + $boxes_data['css_dependencies'] = array_values( array_diff( $wp_styles->queue, $before_css ) ); + } + + // TODO: look into 'embed' parameter. + // http://demo.wp-api.org/wp-json/wp/v2/posts?_embed + unset( $boxes_data['fields'] ); + // Handle callable properties. + unset( $boxes_data['show_on_cb'] ); + + $response = rest_ensure_response( $boxes_data ); + + $response->add_links( $this->prepare_links( $cmb ) ); + + return $response; + } + + /** + * Return an array of contextual links for box/boxes. + * + * @since 2.2.3 + * + * @param CMB2_REST $cmb CMB2_REST object to build links from. + * + * @return array Array of links + */ + protected function prepare_links( $cmb ) { + $boxbase = $this->namespace_base . '/' . $cmb->cmb_id; + $query_string = $this->get_query_string(); + + return array( + // Standard Link Relations -- http://v2.wp-api.org/extending/linking/ + 'self' => array( + 'href' => rest_url( $boxbase . $query_string ), + ), + 'collection' => array( + 'href' => rest_url( $this->namespace_base . $query_string ), + ), + // Custom Link Relations -- http://v2.wp-api.org/extending/linking/ + // TODO URL should document relationship. + 'https://cmb2.io/fields' => array( + 'href' => rest_url( trailingslashit( $boxbase ) . 'fields' . $query_string ), + 'embeddable' => true, + ), + ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller_Fields.php b/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller_Fields.php new file mode 100755 index 00000000..6e52b542 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/rest-api/CMB2_REST_Controller_Fields.php @@ -0,0 +1,502 @@ + array( + 'description' => esc_html__( 'Includes the box object which the fields are registered to in the response.', 'cmb2' ), + ), + '_rendered' => array( + 'description' => esc_html__( 'When the \'_rendered\' argument is passed, the renderable field attributes will be returned fully rendered. By default, the names of the callback handers for the renderable attributes will be returned.', 'cmb2' ), + ), + 'object_id' => array( + 'description' => esc_html__( 'To view or modify the field\'s value, the \'object_id\' and \'object_type\' arguments are required.', 'cmb2' ), + ), + 'object_type' => array( + 'description' => esc_html__( 'To view or modify the field\'s value, the \'object_id\' and \'object_type\' arguments are required.', 'cmb2' ), + ), + ); + + // Returns specific box's fields. + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/fields/', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'callback' => array( $this, 'get_items' ), + 'args' => $args, + ), + 'schema' => array( $this, 'get_item_schema' ), + ) ); + + $delete_args = $args; + $delete_args['object_id']['required'] = true; + $delete_args['object_type']['required'] = true; + + // Returns specific field data. + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/fields/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'permission_callback' => array( $this, 'get_item_permissions_check' ), + 'callback' => array( $this, 'get_item' ), + 'args' => $args, + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'callback' => array( $this, 'update_item' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + 'args' => $args, + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'callback' => array( $this, 'delete_item' ), + 'args' => $delete_args, + ), + 'schema' => array( $this, 'get_item_schema' ), + ) ); + } + + /** + * Check if a given request has access to get fields. + * By default, no special permissions needed, but filtering return value. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $this->initiate_rest_read_box( $request, 'fields_read' ); + $can_access = true; + + /** + * By default, no special permissions needed. + * + * @since 2.2.3 + * + * @param bool $can_access Whether this CMB2 endpoint can be accessed. + * @param object $controller This CMB2_REST_Controller object. + */ + return $this->maybe_hook_callback_and_apply_filters( 'cmb2_api_get_fields_permissions_check', $can_access ); + } + + /** + * Get all public CMB2 box fields. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + if ( ! $this->rest_box ) { + $this->initiate_rest_read_box( $request, 'fields_read' ); + } + + if ( is_wp_error( $this->rest_box ) ) { + return $this->rest_box; + } + + $fields = array(); + foreach ( $this->rest_box->cmb->prop( 'fields', array() ) as $field ) { + + // Make sure this field can be read. + $this->field = $this->rest_box->field_can_read( $field['id'], true ); + + // And make sure current user can view this box. + if ( $this->field && $this->get_item_permissions_check_filter() ) { + $fields[ $field['id'] ] = $this->server->response_to_data( + $this->prepare_field_response(), + isset( $this->request['_embed'] ) + ); + } + } + + return $this->prepare_item( $fields ); + } + + /** + * Check if a given request has access to a field. + * By default, no special permissions needed, but filtering return value. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $this->initiate_rest_read_box( $request, 'field_read' ); + if ( ! is_wp_error( $this->rest_box ) ) { + $this->field = $this->rest_box->field_can_read( $this->request->get_param( 'field_id' ), true ); + } + + return $this->get_item_permissions_check_filter(); + } + + /** + * Check by filter if a given request has access to a field. + * By default, no special permissions needed, but filtering return value. + * + * @since 2.2.3 + * + * @param bool $can_access Whether the current request has access to view the field by default. + * @return WP_Error|boolean + */ + public function get_item_permissions_check_filter( $can_access = true ) { + /** + * By default, no special permissions needed. + * + * @since 2.2.3 + * + * @param bool $can_access Whether this CMB2 endpoint can be accessed. + * @param object $controller This CMB2_REST_Controller object. + */ + return $this->maybe_hook_callback_and_apply_filters( 'cmb2_api_get_field_permissions_check', $can_access ); + } + + /** + * Get one CMB2 field from the collection. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + $this->initiate_rest_read_box( $request, 'field_read' ); + + if ( is_wp_error( $this->rest_box ) ) { + return $this->rest_box; + } + + return $this->prepare_read_field( $this->request->get_param( 'field_id' ) ); + } + + /** + * Check if a given request has access to update a field value. + * By default, requires 'edit_others_posts' capability, but filtering return value. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $this->initiate_rest_read_box( $request, 'field_value_update' ); + if ( ! is_wp_error( $this->rest_box ) ) { + $this->field = $this->rest_box->field_can_edit( $this->request->get_param( 'field_id' ), true ); + } + + $can_update = current_user_can( 'edit_others_posts' ); + + /** + * By default, 'edit_others_posts' is required capability. + * + * @since 2.2.3 + * + * @param bool $can_update Whether this CMB2 endpoint can be accessed. + * @param object $controller This CMB2_REST_Controller object. + */ + return $this->maybe_hook_callback_and_apply_filters( 'cmb2_api_update_field_value_permissions_check', $can_update ); + } + + /** + * Update CMB2 field value. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $this->initiate_rest_read_box( $request, 'field_value_update' ); + + if ( ! $this->request['value'] ) { + return new WP_Error( 'cmb2_rest_update_field_error', esc_html__( 'CMB2 Field value cannot be updated without the value parameter specified.', 'cmb2' ), array( + 'status' => 400, + ) ); + } + + return $this->modify_field_value( 'updated' ); + } + + /** + * Check if a given request has access to delete a field value. + * By default, requires 'delete_others_posts' capability, but filtering return value. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $this->initiate_rest_read_box( $request, 'field_value_delete' ); + if ( ! is_wp_error( $this->rest_box ) ) { + $this->field = $this->rest_box->field_can_edit( $this->request->get_param( 'field_id' ), true ); + } + + $can_delete = current_user_can( 'delete_others_posts' ); + + /** + * By default, 'delete_others_posts' is required capability. + * + * @since 2.2.3 + * + * @param bool $can_delete Whether this CMB2 endpoint can be accessed. + * @param object $controller This CMB2_REST_Controller object. + */ + return $this->maybe_hook_callback_and_apply_filters( 'cmb2_api_delete_field_value_permissions_check', $can_delete ); + } + + /** + * Delete CMB2 field value. + * + * @since 2.2.3 + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + $this->initiate_rest_read_box( $request, 'field_value_delete' ); + + return $this->modify_field_value( 'deleted' ); + } + + /** + * Modify CMB2 field value. + * + * @since 2.2.3 + * + * @param string $activity The modification activity (updated or deleted). + * @return WP_Error|WP_REST_Response + */ + public function modify_field_value( $activity ) { + + if ( ! $this->request['object_id'] || ! $this->request['object_type'] ) { + return new WP_Error( 'cmb2_rest_modify_field_value_error', esc_html__( 'CMB2 Field value cannot be modified without the object_id and object_type parameters specified.', 'cmb2' ), array( + 'status' => 400, + ) ); + } + + if ( is_wp_error( $this->rest_box ) ) { + return $this->rest_box; + } + + $this->field = $this->rest_box->field_can_edit( + $this->field ? $this->field : $this->request->get_param( 'field_id' ), + true + ); + + if ( ! $this->field ) { + return new WP_Error( 'cmb2_rest_no_field_by_id_error', esc_html__( 'No field found by that id.', 'cmb2' ), array( + 'status' => 403, + ) ); + } + + $this->field->args[ "value_{$activity}" ] = (bool) 'deleted' === $activity + ? $this->field->remove_data() + : $this->field->save_field( $this->request['value'] ); + + // If options page, save the $activity options + if ( 'options-page' == $this->request['object_type'] ) { + $this->field->args[ "value_{$activity}" ] = cmb2_options( $this->request['object_id'] )->set(); + } + + return $this->prepare_read_field( $this->field ); + } + + /** + * Get a response object for a specific field ID. + * + * @since 2.2.3 + * + * @param string\CMB2_Field Field id or Field object. + * @return WP_Error|WP_REST_Response + */ + public function prepare_read_field( $field ) { + $this->field = $this->rest_box->field_can_read( $field, true ); + + if ( ! $this->field ) { + return new WP_Error( 'cmb2_rest_no_field_by_id_error', esc_html__( 'No field found by that id.', 'cmb2' ), array( + 'status' => 403, + ) ); + } + + return $this->prepare_item( $this->prepare_field_response() ); + } + + /** + * Get a specific field response. + * + * @since 2.2.3 + * + * @param CMB2_Field Field object. + * @return array Response array. + */ + public function prepare_field_response() { + $field_data = $this->prepare_field_data( $this->field ); + $response = rest_ensure_response( $field_data ); + + $response->add_links( $this->prepare_links( $this->field ) ); + + return $response; + } + + /** + * Prepare the field data array for JSON. + * + * @since 2.2.3 + * + * @param CMB2_Field $field field object. + * + * @return array Array of field data. + */ + protected function prepare_field_data( CMB2_Field $field ) { + $field_data = array(); + $params_to_ignore = array( 'show_in_rest', 'options' ); + $params_to_rename = array( + 'label_cb' => 'label', + 'options_cb' => 'options', + ); + + // Run this first so the js_dependencies arg is populated. + $rendered = ( $cb = $field->maybe_callback( 'render_row_cb' ) ) + // Ok, callback is good, let's run it. + ? $this->get_cb_results( $cb, $field->args(), $field ) + : false; + + $field_args = $field->args(); + + foreach ( $field_args as $key => $value ) { + if ( in_array( $key, $params_to_ignore, true ) ) { + continue; + } + + if ( 'options_cb' === $key ) { + $value = $field->options(); + } elseif ( in_array( $key, CMB2_Field::$callable_fields, true ) ) { + + if ( isset( $this->request['_rendered'] ) ) { + $value = $key === 'render_row_cb' ? $rendered : $field->get_param_callback_result( $key ); + } elseif ( is_array( $value ) ) { + // We need to rewrite callbacks as string as they will cause + // JSON recursion errors. + $class = is_string( $value[0] ) ? $value[0] : get_class( $value[0] ); + $value = $class . '::' . $value[1]; + } + } + + $key = isset( $params_to_rename[ $key ] ) ? $params_to_rename[ $key ] : $key; + + if ( empty( $value ) || is_scalar( $value ) || is_array( $value ) ) { + $field_data[ $key ] = $value; + } else { + $field_data[ $key ] = sprintf( esc_html__( 'Value Error for %s', 'cmb2' ), $key ); + } + } + + if ( $this->request['object_id'] && $this->request['object_type'] ) { + $field_data['value'] = $field->get_rest_value(); + } + + return $field_data; + } + + /** + * Return an array of contextual links for field/fields. + * + * @since 2.2.3 + * + * @param CMB2_Field $field Field object to build links from. + * + * @return array Array of links + */ + protected function prepare_links( $field ) { + $boxbase = $this->namespace_base . '/' . $this->rest_box->cmb->cmb_id; + $query_string = $this->get_query_string(); + + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $boxbase ) . 'fields/' . $field->_id() . $query_string ), + ), + 'collection' => array( + 'href' => rest_url( trailingslashit( $boxbase ) . 'fields' . $query_string ), + ), + 'up' => array( + 'embeddable' => true, + 'href' => rest_url( $boxbase . $query_string ), + ), + ); + + return $links; + } + + /** + * Checks if the CMB2 box or field has any registered callback parameters for the given filter. + * + * The registered handlers will have a property name which matches the filter, except: + * - The 'cmb2_api' prefix will be removed + * - A '_cb' suffix will be added (to stay inline with other '*_cb' parameters). + * + * @since 2.2.3 + * + * @param string $filter The filter name. + * @param bool $default_val The default filter value. + * + * @return bool The possibly-modified filter value (if the _cb param is a non-callable). + */ + public function maybe_hook_registered_callback( $filter, $default_val ) { + $default_val = parent::maybe_hook_registered_callback( $filter, $default_val ); + + if ( $this->field ) { + + // Hook field specific filter callbacks. + $val = $this->field->maybe_hook_parameter( $filter, $default_val ); + if ( null !== $val ) { + $default_val = $val; + } + } + + return $default_val; + } + + /** + * Unhooks any CMB2 box or field registered callback parameters for the given filter. + * + * @since 2.2.3 + * + * @param string $filter The filter name. + * + * @return void + */ + public function maybe_unhook_registered_callback( $filter ) { + parent::maybe_unhook_registered_callback( $filter ); + + if ( $this->field ) { + // Unhook field specific filter callbacks. + $this->field->maybe_hook_parameter( $filter, null, 'remove_filter' ); + } + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/shim/WP_REST_Controller.php b/inc/vendors/cmb2-plugins/cmb2/includes/shim/WP_REST_Controller.php new file mode 100755 index 00000000..e278235a --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/shim/WP_REST_Controller.php @@ -0,0 +1,541 @@ + 405, + ) ); + } + + /** + * Get a collection of items. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Check if a given request has access to get a specific item. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Get one item from the collection. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_item( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Check if a given request has access to create items. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Create one item from the collection. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Check if a given request has access to update a specific item. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Update one item from the collection. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Check if a given request has access to delete a specific item. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Delete one item from the collection. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|WP_REST_Response + */ + public function delete_item( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Prepare the item for create or update operation. + * + * @param WP_REST_Request $request Request object. + * @return WP_Error|object $prepared_item + */ + protected function prepare_item_for_database( $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Prepare the item for the REST response. + * + * @param mixed $item WordPress representation of the item. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + return new WP_Error( 'invalid-method', sprintf( esc_html__( "Method '%s' not implemented. Must be overridden in subclass." ), __METHOD__ ), array( + 'status' => 405, + ) ); + } + + /** + * Prepare a response for inserting into a collection. + * + * @param WP_REST_Response $response Response object. + * @return array Response data, ready for insertion into collection data. + */ + public function prepare_response_for_collection( $response ) { + if ( ! ( $response instanceof WP_REST_Response ) ) { + return $response; + } + + $data = (array) $response->get_data(); + $server = rest_get_server(); + + if ( method_exists( $server, 'get_compact_response_links' ) ) { + $links = call_user_func( array( $server, 'get_compact_response_links' ), $response ); + } else { + $links = call_user_func( array( $server, 'get_response_links' ), $response ); + } + + if ( ! empty( $links ) ) { + $data['_links'] = $links; + } + + return $data; + } + + /** + * Filter a response based on the context defined in the schema. + * + * @param array $data + * @param string $context + * @return array + */ + public function filter_response_by_context( $data, $context ) { + + $schema = $this->get_item_schema(); + foreach ( $data as $key => $value ) { + if ( empty( $schema['properties'][ $key ] ) || empty( $schema['properties'][ $key ]['context'] ) ) { + continue; + } + + if ( ! in_array( $context, $schema['properties'][ $key ]['context'] ) ) { + unset( $data[ $key ] ); + continue; + } + + if ( 'object' === $schema['properties'][ $key ]['type'] && ! empty( $schema['properties'][ $key ]['properties'] ) ) { + foreach ( $schema['properties'][ $key ]['properties'] as $attribute => $details ) { + if ( empty( $details['context'] ) ) { + continue; + } + if ( ! in_array( $context, $details['context'] ) ) { + if ( isset( $data[ $key ][ $attribute ] ) ) { + unset( $data[ $key ][ $attribute ] ); + } + } + } + } + } + + return $data; + } + + /** + * Get the item's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + return $this->add_additional_fields_schema( array() ); + } + + /** + * Get the item's schema for display / public consumption purposes. + * + * @return array + */ + public function get_public_item_schema() { + + $schema = $this->get_item_schema(); + + foreach ( $schema['properties'] as &$property ) { + if ( isset( $property['arg_options'] ) ) { + unset( $property['arg_options'] ); + } + } + + return $schema; + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param(), + 'page' => array( + 'description' => esc_html__( 'Current page of the collection.' ), + 'type' => 'integer', + 'default' => 1, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + 'minimum' => 1, + ), + 'per_page' => array( + 'description' => esc_html__( 'Maximum number of items to be returned in result set.' ), + 'type' => 'integer', + 'default' => 10, + 'minimum' => 1, + 'maximum' => 100, + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ), + 'search' => array( + 'description' => esc_html__( 'Limit results to those matching a string.' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => 'rest_validate_request_arg', + ), + ); + } + + /** + * Get the magical context param. + * + * Ensures consistent description between endpoints, and populates enum from schema. + * + * @param array $args + * @return array + */ + public function get_context_param( $args = array() ) { + $param_details = array( + 'description' => esc_html__( 'Scope under which the request is made; determines fields present in response.' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'validate_callback' => 'rest_validate_request_arg', + ); + $schema = $this->get_item_schema(); + if ( empty( $schema['properties'] ) ) { + return array_merge( $param_details, $args ); + } + $contexts = array(); + foreach ( $schema['properties'] as $attributes ) { + if ( ! empty( $attributes['context'] ) ) { + $contexts = array_merge( $contexts, $attributes['context'] ); + } + } + if ( ! empty( $contexts ) ) { + $param_details['enum'] = array_unique( $contexts ); + rsort( $param_details['enum'] ); + } + return array_merge( $param_details, $args ); + } + + /** + * Add the values from additional fields to a data object. + * + * @param array $object + * @param WP_REST_Request $request + * @return array modified object with additional fields. + */ + protected function add_additional_fields_to_object( $object, $request ) { + + $additional_fields = $this->get_additional_fields(); + + foreach ( $additional_fields as $field_name => $field_options ) { + + if ( ! $field_options['get_callback'] ) { + continue; + } + + $object[ $field_name ] = call_user_func( $field_options['get_callback'], $object, $field_name, $request, $this->get_object_type() ); + } + + return $object; + } + + /** + * Update the values of additional fields added to a data object. + * + * @param array $object + * @param WP_REST_Request $request + */ + protected function update_additional_fields_for_object( $object, $request ) { + + $additional_fields = $this->get_additional_fields(); + + foreach ( $additional_fields as $field_name => $field_options ) { + + if ( ! $field_options['update_callback'] ) { + continue; + } + + // Don't run the update callbacks if the data wasn't passed in the request. + if ( ! isset( $request[ $field_name ] ) ) { + continue; + } + + call_user_func( $field_options['update_callback'], $request[ $field_name ], $object, $field_name, $request, $this->get_object_type() ); + } + } + + /** + * Add the schema from additional fields to an schema array. + * + * The type of object is inferred from the passed schema. + * + * @param array $schema Schema array. + */ + protected function add_additional_fields_schema( $schema ) { + if ( empty( $schema['title'] ) ) { + return $schema; + } + + /** + * Can't use $this->get_object_type otherwise we cause an inf loop. + */ + $object_type = $schema['title']; + + $additional_fields = $this->get_additional_fields( $object_type ); + + foreach ( $additional_fields as $field_name => $field_options ) { + if ( ! $field_options['schema'] ) { + continue; + } + + $schema['properties'][ $field_name ] = $field_options['schema']; + } + + return $schema; + } + + /** + * Get all the registered additional fields for a given object-type. + * + * @param string $object_type + * @return array + */ + protected function get_additional_fields( $object_type = null ) { + + if ( ! $object_type ) { + $object_type = $this->get_object_type(); + } + + if ( ! $object_type ) { + return array(); + } + + global $wp_rest_additional_fields; + + if ( ! $wp_rest_additional_fields || ! isset( $wp_rest_additional_fields[ $object_type ] ) ) { + return array(); + } + + return $wp_rest_additional_fields[ $object_type ]; + } + + /** + * Get the object type this controller is responsible for managing. + * + * @return string + */ + protected function get_object_type() { + $schema = $this->get_item_schema(); + + if ( ! $schema || ! isset( $schema['title'] ) ) { + return null; + } + + return $schema['title']; + } + + /** + * Get an array of endpoint arguments from the item schema for the controller. + * + * @param string $method HTTP method of the request. The arguments + * for `CREATABLE` requests are checked for required + * values and may fall-back to a given default, this + * is not done on `EDITABLE` requests. Default is + * WP_REST_Server::CREATABLE. + * @return array $endpoint_args + */ + public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) { + + $schema = $this->get_item_schema(); + $schema_properties = ! empty( $schema['properties'] ) ? $schema['properties'] : array(); + $endpoint_args = array(); + + foreach ( $schema_properties as $field_id => $params ) { + + // Arguments specified as `readonly` are not allowed to be set. + if ( ! empty( $params['readonly'] ) ) { + continue; + } + + $endpoint_args[ $field_id ] = array( + 'validate_callback' => 'rest_validate_request_arg', + 'sanitize_callback' => 'rest_sanitize_request_arg', + ); + + if ( isset( $params['description'] ) ) { + $endpoint_args[ $field_id ]['description'] = $params['description']; + } + + if ( WP_REST_Server::CREATABLE === $method && isset( $params['default'] ) ) { + $endpoint_args[ $field_id ]['default'] = $params['default']; + } + + if ( WP_REST_Server::CREATABLE === $method && ! empty( $params['required'] ) ) { + $endpoint_args[ $field_id ]['required'] = true; + } + + foreach ( array( 'type', 'format', 'enum' ) as $schema_prop ) { + if ( isset( $params[ $schema_prop ] ) ) { + $endpoint_args[ $field_id ][ $schema_prop ] = $params[ $schema_prop ]; + } + } + + // Merge in any options provided by the schema property. + if ( isset( $params['arg_options'] ) ) { + + // Only use required / default from arg_options on CREATABLE endpoints. + if ( WP_REST_Server::CREATABLE !== $method ) { + $params['arg_options'] = array_diff_key( $params['arg_options'], array( + 'required' => '', + 'default' => '', + ) ); + } + + $endpoint_args[ $field_id ] = array_merge( $endpoint_args[ $field_id ], $params['arg_options'] ); + } + }// End foreach(). + + return $endpoint_args; + } + + /** + * Retrieves post data given a post ID or post object. + * + * This is a subset of the functionality of the `get_post()` function, with + * the additional functionality of having `the_post` action done on the + * resultant post object. This is done so that plugins may manipulate the + * post that is used in the REST API. + * + * @see get_post() + * @global WP_Query $wp_query + * + * @param int|WP_Post $post Post ID or post object. Defaults to global $post. + * @return WP_Post|null A `WP_Post` object when successful. + */ + public function get_post( $post ) { + $post_obj = get_post( $post ); + + /** + * Filter the post. + * + * Allows plugins to filter the post object as returned by `\WP_REST_Controller::get_post()`. + * + * @param WP_Post|null $post_obj The post object as returned by `get_post()`. + * @param int|WP_Post $post The original value used to obtain the post object. + */ + $post = apply_filters( 'rest_the_post', $post_obj, $post ); + + return $post; + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Base.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Base.php new file mode 100755 index 00000000..c79d51a8 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Base.php @@ -0,0 +1,177 @@ +types = $types; + $args['rendered'] = isset( $args['rendered'] ) ? (bool) $args['rendered'] : true; + $this->args = $args; + } + + /** + * Handles rendering this field type. + * + * @since 2.2.2 + * @return string Rendered field type. + */ + abstract public function render(); + + /** + * Stores the rendered field output. + * + * @since 2.2.2 + * @param string|CMB2_Type_Base $rendered Rendered output. + * @return string|CMB2_Type_Base Rendered output or this object. + */ + public function rendered( $rendered ) { + $this->field->register_js_data(); + + if ( $this->args['rendered'] ) { + return is_a( $rendered, __CLASS__ ) ? $rendered->rendered : $rendered; + } + + $this->rendered = is_a( $rendered, __CLASS__ ) ? $rendered->rendered : $rendered; + + return $this; + } + + /** + * Returns the stored rendered field output. + * + * @since 2.2.2 + * @return string Stored rendered output (if 'rendered' argument is set to false). + */ + public function get_rendered() { + return $this->rendered; + } + + /** + * Handles parsing and filtering attributes while preserving any passed in via field config. + * + * @since 1.1.0 + * @param string $element Element for filter + * @param array $type_defaults Type default arguments + * @param array $type_overrides Type override arguments + * @return array Parsed and filtered arguments + */ + public function parse_args( $element, $type_defaults, $type_overrides = array() ) { + $args = $this->parse_args_from_overrides( $type_overrides ); + + /** + * Filter attributes for a field type. + * The dynamic portion of the hook name, $element, refers to the field type. + * + * @since 1.1.0 + * @param array $args The array of attribute arguments. + * @param array $type_defaults The array of default values. + * @param array $field The `CMB2_Field` object. + * @param object $field_type_object This `CMB2_Types` object. + */ + $args = apply_filters( "cmb2_{$element}_attributes", $args, $type_defaults, $this->field, $this->types ); + + $args = wp_parse_args( $args, $type_defaults ); + + if ( ! empty( $args['js_dependencies'] ) ) { + $this->field->add_js_dependencies( $args['js_dependencies'] ); + } + + return $args; + } + + /** + * Handles parsing and filtering attributes while preserving any passed in via field config. + * + * @since 2.2.4 + * @param array $type_overrides Type override arguments + * @return array Parsed arguments + */ + protected function parse_args_from_overrides( $type_overrides = array() ) { + $type_overrides = empty( $type_overrides ) ? $this->args : $type_overrides; + + if ( true !== $this->field->args( 'disable_hash_data_attribute' ) ) { + $type_overrides['data-hash'] = $this->field->hash_id(); + } + + $field_overrides = $this->field->args( 'attributes' ); + + return ! empty( $field_overrides ) + ? wp_parse_args( $field_overrides, $type_overrides ) + : $type_overrides; + } + + /** + * Fall back to CMB2_Types methods + * + * @param string $method + * @param array $arguments + * @throws Exception Throws an exception if the field is invalid. + * @return mixed + */ + public function __call( $method, $arguments ) { + switch ( $method ) { + case '_id': + case '_name': + case '_desc': + case '_text': + case 'concat_attrs': + return call_user_func_array( array( $this->types, $method ), $arguments ); + default: + throw new Exception( sprintf( esc_html__( 'Invalid %1$s method: %2$s', 'cmb2' ), __CLASS__, $method ) ); + } + } + + /** + * Magic getter for our object. + * + * @param string $field + * @throws Exception Throws an exception if the field is invalid. + * @return mixed + */ + public function __get( $field ) { + switch ( $field ) { + case 'field': + return $this->types->field; + default: + throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) ); + } + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Checkbox.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Checkbox.php new file mode 100755 index 00000000..ccd4adec --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Checkbox.php @@ -0,0 +1,65 @@ +is_checked = $is_checked; + } + + public function render( $args = array() ) { + $defaults = array( + 'type' => 'checkbox', + 'class' => 'cmb2-option cmb2-list', + 'value' => 'on', + 'desc' => '', + ); + + $meta_value = $this->field->escaped_value(); + + $is_checked = null === $this->is_checked + ? ! empty( $meta_value ) + : $this->is_checked; + + if ( $is_checked ) { + $defaults['checked'] = 'checked'; + } + + $args = $this->parse_args( 'checkbox', $defaults ); + + return $this->rendered( + sprintf( + '%s ', + parent::render( $args ), + $this->_id(), + $this->_desc() + ) + ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Colorpicker.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Colorpicker.php new file mode 100755 index 00000000..28d00599 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Colorpicker.php @@ -0,0 +1,79 @@ +value = $value ? $value : $this->value; + } + + public function render( $args = array() ) { + $meta_value = $this->value ? $this->value : $this->field->escaped_value(); + + $hex_color = '(([a-fA-F0-9]){3}){1,2}$'; + if ( preg_match( '/^' . $hex_color . '/i', $meta_value ) ) { + // Value is just 123abc, so prepend # + $meta_value = '#' . $meta_value; + } elseif ( + // If value doesn't match #123abc... + ! preg_match( '/^#' . $hex_color . '/i', $meta_value ) + // And value doesn't match rgba()... + && 0 !== strpos( trim( $meta_value ), 'rgba' ) + ) { + // Then sanitize to just #. + $meta_value = '#'; + } + + wp_enqueue_style( 'wp-color-picker' ); + + $args = wp_parse_args( $args, array( + 'class' => 'cmb2-text-small', + ) ); + + $args['class'] .= ' cmb2-colorpicker'; + $args['value'] = $meta_value; + $args['js_dependencies'] = array( 'wp-color-picker' ); + + if ( $this->field->options( 'alpha' ) ) { + $args['js_dependencies'][] = 'wp-color-picker-alpha'; + $args['data-alpha'] = 'true'; + } + + $args = wp_parse_args( $this->args, $args ); + + return parent::render( $args ); + } + + public static function dequeue_rgba_colorpicker_script() { + if ( wp_script_is( 'jw-cmb2-rgba-picker-js', 'enqueued' ) ) { + wp_dequeue_script( 'jw-cmb2-rgba-picker-js' ); + CMB2_JS::register_colorpicker_alpha( true ); + } + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File.php new file mode 100755 index 00000000..c17ff908 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File.php @@ -0,0 +1,169 @@ +args : $args; + $field = $this->field; + $options = (array) $field->options(); + + $a = $this->args = $this->parse_args( 'file', array( + 'class' => 'cmb2-upload-file regular-text', + 'id' => $this->_id(), + 'name' => $this->_name(), + 'value' => $field->escaped_value(), + 'id_value' => null, + 'desc' => $this->_desc( true ), + 'size' => 45, + 'js_dependencies' => 'media-editor', + 'preview_size' => $field->args( 'preview_size' ), + 'query_args' => $field->args( 'query_args' ), + + // if options array and 'url' => false, then hide the url field + 'type' => array_key_exists( 'url', $options ) && false === $options['url'] + ? 'hidden' + : 'text', + ), $args ); + + // get an array of image size meta data, fallback to 'large' + $this->args['img_size_data'] = $img_size_data = parent::get_image_size_data( + $a['preview_size'], + 'large' + ); + + $output = ''; + + $output .= parent::render( array( + 'type' => $a['type'], + 'class' => $a['class'], + 'value' => $a['value'], + 'id' => $a['id'], + 'name' => $a['name'], + 'size' => $a['size'], + 'desc' => '', + 'data-previewsize' => sprintf( '[%d,%d]', $img_size_data['width'], $img_size_data['height'] ), + 'data-sizename' => $img_size_data['name'], + 'data-queryargs' => ! empty( $a['query_args'] ) ? json_encode( $a['query_args'] ) : '', + 'js_dependencies' => $a['js_dependencies'], + ) ); + + // Now remove the data-iterator attribute if it exists. + // (Possible if being used within a custom field) + // This is not elegant, but compensates for CMB2_Types::_id + // automagically & inelegantly adding the data-iterator attribute. + // Single responsibility principle? pffft + $parts = explode( '"', $this->args['id'] ); + $this->args['id'] = $parts[0]; + + $output .= sprintf( + '', + esc_attr( $this->_text( 'add_upload_file_text', esc_html__( 'Add or Upload File', 'cmb2' ) ) ) + ); + + $output .= $a['desc']; + $output .= $this->get_id_field_output(); + + $output .= '
            '; + if ( ! empty( $a['value'] ) ) { + $output .= $this->get_file_preview_output(); + } + $output .= '
            '; + + return $this->rendered( $output ); + } + + public function get_file_preview_output() { + if ( ! $this->is_valid_img_ext( $this->args['value'] ) ) { + + return $this->file_status_output( array( + 'value' => $this->args['value'], + 'tag' => 'div', + 'cached_id' => $this->args['id'], + ) ); + } + + if ( $this->args['id_value'] ) { + $image = wp_get_attachment_image( $this->args['id_value'], $this->args['preview_size'], null, array( + 'class' => 'cmb-file-field-image', + ) ); + } else { + $image = ''; + } + + return $this->img_status_output( array( + 'image' => $image, + 'tag' => 'div', + 'cached_id' => $this->args['id'], + ) ); + } + + public function get_id_field_output() { + $field = $this->field; + + /* + * A little bit of magic (tsk tsk) replacing the $this->types->field object, + * So that the render function is using the proper field object. + */ + $this->types->field = $this->get_id_field(); + + $output = parent::render( array( + 'type' => 'hidden', + 'class' => 'cmb2-upload-file-id', + 'value' => $this->types->field->value, + 'desc' => '', + ) ); + + // We need to put the original field object back + // or other fields in a custom field will be broken. + $this->types->field = $field; + + return $output; + } + + public function get_id_field() { + + // reset field args for attachment id + $args = array( + // if we're looking at a file in a group, we need to get the non-prefixed id + 'id' => ( $this->field->group ? $this->field->args( '_id' ) : $this->args['id'] ) . '_id', + 'disable_hash_data_attribute' => true, + ); + + // and get new field object + // (need to set it to the types field property) + $id_field = $this->field->get_field_clone( $args ); + + $id_value = absint( null !== $this->args['id_value'] ? $this->args['id_value'] : $id_field->escaped_value() ); + + // we don't want to output "0" as a value. + if ( ! $id_value ) { + $id_value = ''; + } + + // if there is no id saved yet, try to get it from the url + if ( $this->args['value'] && ! $id_value ) { + $id_value = CMB2_Utils::image_id_from_url( esc_url_raw( $this->args['value'] ) ); + } + + $id_field->value = $id_value; + + return $id_field; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File_Base.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File_Base.php new file mode 100755 index 00000000..5edbb21a --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File_Base.php @@ -0,0 +1,210 @@ +field->id(); + + /** + * Filter for determining if a field value has a valid image file-type extension. + * + * The dynamic portion of the hook name, $field_id, refers to the field id attribute. + * + * @since 2.0.9 + * + * @param bool $is_valid Whether field value has a valid image file-type extension. + * @param string $file File url. + * @param string $file_ext File extension. + */ + return (bool) apply_filters( "cmb2_{$field_id}_is_valid_img_ext", $is_valid, $file, $file_ext ); + } + + /** + * file/file_list image wrap + * + * @since 2.0.2 + * @param array $args Array of arguments for output + * @return string Image wrap output + */ + public function img_status_output( $args ) { + return sprintf( '<%1$s class="img-status cmb2-media-item">%2$s

            %4$s

            %5$s', + $args['tag'], + $args['image'], + isset( $args['cached_id'] ) ? ' rel="' . $args['cached_id'] . '"' : '', + esc_html( $this->_text( 'remove_image_text', esc_html__( 'Remove Image', 'cmb2' ) ) ), + isset( $args['id_input'] ) ? $args['id_input'] : '' + ); + } + + /** + * file/file_list file wrap + * + * @since 2.0.2 + * @param array $args Array of arguments for output + * @return string File wrap output + */ + public function file_status_output( $args ) { + return sprintf( '<%1$s class="file-status cmb2-media-item">%2$s %3$s   (%5$s / %7$s)%8$s', + $args['tag'], + esc_html( $this->_text( 'file_text', esc_html__( 'File:', 'cmb2' ) ) ), + CMB2_Utils::get_file_name_from_path( $args['value'] ), + $args['value'], + esc_html( $this->_text( 'file_download_text', esc_html__( 'Download', 'cmb2' ) ) ), + isset( $args['cached_id'] ) ? ' rel="' . $args['cached_id'] . '"' : '', + esc_html( $this->_text( 'remove_text', esc_html__( 'Remove', 'cmb2' ) ) ), + isset( $args['id_input'] ) ? $args['id_input'] : '' + ); + } + + /** + * Outputs the file/file_list underscore Javascript templates in the footer. + * + * @since 2.2.4 + * @return void + */ + public static function output_js_underscore_templates() { + ?> + + + + + (int) image size width + * 'height' => (int) image size height + * 'name' => (string) e.g. 'thumbnail' + * ) + */ + static function get_image_size_data( $img_size = '', $fallback = 'thumbnail' ) { + $data = array(); + + if ( is_array( $img_size ) ) { + $data['width'] = intval( $img_size[0] ); + $data['height'] = intval( $img_size[1] ); + $data['name'] = ''; + + // Try and get the closest named size from our array of dimensions + if ( $named_size = CMB2_Utils::get_named_size( $img_size ) ) { + $data['name'] = $named_size; + } + } else { + + $image_sizes = CMB2_Utils::get_available_image_sizes(); + + // The 'thumb' alias, which works elsewhere, doesn't work in the wp.media uploader + if ( 'thumb' == $img_size ) { + $img_size = 'thumbnail'; + } + + // Named size doesn't exist, use $fallback + if ( ! array_key_exists( $img_size, $image_sizes ) ) { + $img_size = $fallback; + } + + // Get image dimensions from named sizes + $data['width'] = intval( $image_sizes[ $img_size ]['width'] ); + $data['height'] = intval( $image_sizes[ $img_size ]['height'] ); + $data['name'] = $img_size; + } + + return $data; + } + + /** + * Filters attachment data prepared for JavaScript. + * + * Adds the url, width, height, and orientation for custom sizes to the JavaScript + * object returned by the wp.media uploader. Hooked to 'wp_prepare_attachment_for_js'. + * + * @since 2.2.4 + * @param array $response Array of prepared attachment data + * @param int|object $attachment Attachment ID or object + * @param array $meta Array of attachment meta data ( from wp_get_attachment_metadata() ) + * @return array filtered $response array + */ + public static function prepare_image_sizes_for_js( $response, $attachment, $meta ) { + foreach ( CMB2_Utils::get_available_image_sizes() as $size => $info ) { + + // registered image size exists for this attachment + if ( isset( $meta['sizes'][ $size ] ) ) { + + $attachment_url = wp_get_attachment_url( $attachment->ID ); + $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url ); + $size_meta = $meta['sizes'][ $size ]; + + $response['sizes'][ $size ] = array( + 'url' => $base_url . $size_meta['file'], + 'height' => $size_meta['height'], + 'width' => $size_meta['width'], + 'orientation' => $size_meta['height'] > $size_meta['width'] ? 'portrait' : 'landscape', + ); + } + } + + return $response; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File_List.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File_List.php new file mode 100755 index 00000000..4a6b3ef5 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_File_List.php @@ -0,0 +1,86 @@ +field; + $meta_value = $field->escaped_value(); + $name = $this->_name(); + $img_size = $field->args( 'preview_size' ); + $query_args = $field->args( 'query_args' ); + $output = ''; + + // get an array of image size meta data, fallback to 'thumbnail' + $img_size_data = parent::get_image_size_data( $img_size, 'thumbnail' ); + + $output .= parent::render( array( + 'type' => 'hidden', + 'class' => 'cmb2-upload-file cmb2-upload-list', + 'size' => 45, + 'desc' => '', + 'value' => '', + 'data-previewsize' => sprintf( '[%d,%d]', $img_size_data['width'], $img_size_data['height'] ), + 'data-sizename' => $img_size_data['name'], + 'data-queryargs' => ! empty( $query_args ) ? json_encode( $query_args ) : '', + 'js_dependencies' => 'media-editor', + ) ); + + $output .= parent::render( array( + 'type' => 'button', + 'class' => 'cmb2-upload-button button-secondary cmb2-upload-list', + 'value' => esc_attr( $this->_text( 'add_upload_files_text', esc_html__( 'Add or Upload Files', 'cmb2' ) ) ), + 'name' => '', + 'id' => '', + ) ); + + $output .= '
              '; + + if ( $meta_value && is_array( $meta_value ) ) { + + foreach ( $meta_value as $id => $fullurl ) { + $id_input = parent::render( array( + 'type' => 'hidden', + 'value' => $fullurl, + 'name' => $name . '[' . $id . ']', + 'id' => 'filelist-' . $id, + 'data-id' => $id, + 'desc' => '', + 'class' => false, + ) ); + + if ( $this->is_valid_img_ext( $fullurl ) ) { + + $output .= $this->img_status_output( array( + 'image' => wp_get_attachment_image( $id, $img_size ), + 'tag' => 'li', + 'id_input' => $id_input, + ) ); + + } else { + + $output .= $this->file_status_output( array( + 'value' => $fullurl, + 'tag' => 'li', + 'id_input' => $id_input, + ) ); + + } + } + } + + $output .= '
            '; + + return $this->rendered( $output ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Multi_Base.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Multi_Base.php new file mode 100755 index 00000000..652c92c4 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Multi_Base.php @@ -0,0 +1,110 @@ +%s', $args['value'], selected( isset( $args['checked'] ) && $args['checked'], true, false ), $args['label'] ) . "\n"; + } + + /** + * Generates html for list item with input + * + * @since 1.1.0 + * @param array $args Override arguments + * @param int $i Iterator value + * @return string Gnerated list item html + */ + public function list_input( $args = array(), $i ) { + $a = $this->parse_args( 'list_input', array( + 'type' => 'radio', + 'class' => 'cmb2-option', + 'name' => $this->_name(), + 'id' => $this->_id( $i ), + 'value' => $this->field->escaped_value(), + 'label' => '', + ), $args ); + + return sprintf( "\t" . '
          • ' . "\n", $this->concat_attrs( $a, array( 'label' ) ), $a['id'], $a['label'] ); + } + + /** + * Generates html for list item with checkbox input + * + * @since 1.1.0 + * @param array $args Override arguments + * @param int $i Iterator value + * @return string Gnerated list item html + */ + public function list_input_checkbox( $args, $i ) { + $saved_value = $this->field->escaped_value(); + if ( is_array( $saved_value ) && in_array( $args['value'], $saved_value ) ) { + $args['checked'] = 'checked'; + } + $args['type'] = 'checkbox'; + return $this->list_input( $args, $i ); + } + + /** + * Generates html for concatenated items + * + * @since 1.1.0 + * @param array $args Optional arguments + * @return string Concatenated html items + */ + public function concat_items( $args = array() ) { + $field = $this->field; + + $method = isset( $args['method'] ) ? $args['method'] : 'select_option'; + unset( $args['method'] ); + + $value = null !== $field->escaped_value() + ? $field->escaped_value() + : $field->get_default(); + + $value = CMB2_Utils::normalize_if_numeric( $value ); + + $concatenated_items = ''; + $i = 1; + + $options = array(); + if ( $option_none = $field->args( 'show_option_none' ) ) { + $options[''] = $option_none; + } + $options = $options + (array) $field->options(); + foreach ( $options as $opt_value => $opt_label ) { + + // Clone args & modify for just this item + $a = $args; + + $a['value'] = $opt_value; + $a['label'] = $opt_label; + + // Check if this option is the value of the input + if ( $value === CMB2_Utils::normalize_if_numeric( $opt_value ) ) { + $a['checked'] = 'checked'; + } + + $concatenated_items .= $this->$method( $a, $i++ ); + } + + return $concatenated_items; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Multicheck.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Multicheck.php new file mode 100755 index 00000000..a9c078be --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Multicheck.php @@ -0,0 +1,39 @@ +field->args( 'select_all_button' ) + ? 'cmb2-checkbox-list no-select-all cmb2-list' + : 'cmb2-checkbox-list cmb2-list'; + + $args = $this->parse_args( $this->type, array( + 'class' => $classes, + 'options' => $this->concat_items( array( + 'name' => $this->_name() . '[]', + 'method' => 'list_input_checkbox', + ) ), + 'desc' => $this->_desc( true ), + ) ); + + return $this->rendered( $this->ul( $args ) ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Oembed.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Oembed.php new file mode 100755 index 00000000..9d10fa13 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Oembed.php @@ -0,0 +1,41 @@ +field; + + $meta_value = trim( $field->escaped_value() ); + + $oembed = ! empty( $meta_value ) + ? cmb2_ajax()->get_oembed( array( + 'url' => $field->escaped_value(), + 'object_id' => $field->object_id, + 'object_type' => $field->object_type, + 'oembed_args' => array( + 'width' => '640', + ), + 'field_id' => $this->_id(), + ) ) + : ''; + + return parent::render( array( + 'class' => 'cmb2-oembed regular-text', + 'data-objectid' => $field->object_id, + 'data-objecttype' => $field->object_type, + ) ) + . '

            ' + . '
            ' . $oembed . '
            '; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Picker_Base.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Picker_Base.php new file mode 100755 index 00000000..581ecb85 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Picker_Base.php @@ -0,0 +1,56 @@ +field->args['attributes']) + * @return array Array of field attributes + */ + public function parse_picker_options( $arg = 'date', $args = array() ) { + $att = 'data-' . $arg . 'picker'; + $update = empty( $args ); + $atts = array(); + $format = $this->field->args( $arg . '_format' ); + + if ( $js_format = CMB2_Utils::php_to_js_dateformat( $format ) ) { + + if ( $update ) { + $atts = $this->field->args( 'attributes' ); + } else { + $atts = isset( $args['attributes'] ) + ? $args['attributes'] + : $atts; + } + + // Don't override user-provided datepicker values + $data = isset( $atts[ $att ] ) + ? json_decode( $atts[ $att ], true ) + : array(); + + $data[ $arg . 'Format' ] = $js_format; + $atts[ $att ] = function_exists( 'wp_json_encode' ) + ? wp_json_encode( $data ) + : json_encode( $data ); + } + + if ( $update ) { + $this->field->args['attributes'] = $atts; + } + + return array_merge( $args, $atts ); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Radio.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Radio.php new file mode 100755 index 00000000..d91bcc39 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Radio.php @@ -0,0 +1,52 @@ +type = $type ? $type : $this->type; + } + + public function render() { + $args = $this->parse_args( $this->type, array( + 'class' => 'cmb2-radio-list cmb2-list', + 'options' => $this->concat_items( array( + 'label' => 'test', + 'method' => 'list_input', + ) ), + 'desc' => $this->_desc( true ), + ) ); + + return $this->rendered( $this->ul( $args ) ); + } + + protected function ul( $a ) { + return sprintf( '
              %s
            %s', $a['class'], $a['options'], $a['desc'] ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Select.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Select.php new file mode 100755 index 00000000..655cf11b --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Select.php @@ -0,0 +1,30 @@ +parse_args( 'select', array( + 'class' => 'cmb2_select', + 'name' => $this->_name(), + 'id' => $this->_id(), + 'desc' => $this->_desc( true ), + 'options' => $this->concat_items(), + ) ); + + $attrs = $this->concat_attrs( $a, array( 'desc', 'options' ) ); + + return $this->rendered( + sprintf( '%s%s', $attrs, $a['options'], $a['desc'] ) + ); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Select_Timezone.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Select_Timezone.php new file mode 100755 index 00000000..5a333a38 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Select_Timezone.php @@ -0,0 +1,29 @@ +field->args['default'] = $this->field->get_default() + ? $this->field->get_default() + : CMB2_Utils::timezone_string(); + + $this->args = wp_parse_args( $this->args, array( + 'class' => 'cmb2_select cmb2-select-timezone', + 'options' => wp_timezone_choice( $this->field->escaped_value() ), + 'desc' => $this->_desc(), + ) ); + + return parent::render(); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Base.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Base.php new file mode 100755 index 00000000..fa09bd40 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Base.php @@ -0,0 +1,173 @@ +field->object_type ) { + case 'options-page': + case 'term': + return $this->options_terms(); + case 'post': + // WP caches internally so it's better to use + return get_the_terms( $this->field->object_id, $this->field->args( 'taxonomy' ) ); + + default: + return $this->non_post_object_terms(); + } + } + + /** + * Gets the term objects for the terms stored via options boxes. + * + * @since 2.2.4 + * @return mixed Array of terms on success + */ + public function options_terms() { + if ( empty( $this->field->value ) ) { + return array(); + } + + $terms = (array) $this->field->value; + + foreach ( $terms as $index => $term ) { + $terms[ $index ] = get_term_by( 'slug', $term, $this->field->args( 'taxonomy' ) ); + } + + return $terms; + } + + /** + * For non-post objects, wraps the call to wp_get_object_terms with transient caching. + * + * @since 2.2.4 + * @return mixed Array of terms on success + */ + public function non_post_object_terms() { + $object_id = $this->field->object_id; + $taxonomy = $this->field->args( 'taxonomy' ); + + $cache_key = "cmb-cache-{$taxonomy}-{$object_id}"; + + // Check cache + $cached = get_transient( $cache_key ); + + if ( ! $cached ) { + $cached = wp_get_object_terms( $object_id, $taxonomy ); + // Do our own (minimal) caching. Long enough for a page-load. + set_transient( $cache_key, $cached, 60 ); + } + + return $cached; + } + + /** + * Wrapper for `get_terms` to account for changes in WP 4.6 where taxonomy is expected + * as part of the arguments. + * + * @since 2.2.2 + * @return mixed Array of terms on success + */ + public function get_terms() { + $args = array( + 'taxonomy' => $this->field->args( 'taxonomy' ), + 'hide_empty' => false, + ); + + if ( null !== $this->parent ) { + $args['parent'] = $this->parent; + } + + $args = wp_parse_args( $this->field->prop( 'query_args', array() ), $args ); + + return CMB2_Utils::wp_at_least( '4.5.0' ) + ? get_terms( $args ) + : get_terms( $this->field->args( 'taxonomy' ), http_build_query( $args ) ); + } + + protected function no_terms_result( $error, $tag = 'li' ) { + if ( is_wp_error( $error ) ) { + $message = $error->get_error_message(); + $data = 'data-error="' . esc_attr( $error->get_error_code() ) . '"'; + } else { + $message = $this->_text( 'no_terms_text', esc_html__( 'No terms', 'cmb2' ) ); + $data = ''; + } + + $this->field->args['select_all_button'] = false; + + return sprintf( '<%3$s>', $data, esc_html( $message ), $tag ); + } + + public function get_object_term_or_default() { + $saved_terms = $this->get_object_terms(); + + return is_wp_error( $saved_terms ) || empty( $saved_terms ) + ? $this->field->get_default() + : array_shift( $saved_terms )->slug; + } + + /** + * Takes a list of all tax terms and outputs. + * + * @since 2.2.5 + * + * @param array $all_terms Array of all terms. + * @param array|string $saved Array of terms set to the object, or single term slug. + * + * @return string List of terms. + */ + protected function loop_terms( $all_terms, $saved_terms ) { + return ''; + } + + /** + * Build children hierarchy. + * + * @param object $parent_term The parent term object. + * @param array|string $saved Array of terms set to the object, or single term slug. + * + * @return string List of terms. + */ + protected function build_children( $parent_term, $saved ) { + if ( empty( $parent_term->term_id ) ) { + return ''; + } + + $this->parent = $parent_term->term_id; + + $terms = $this->get_terms(); + $options = ''; + + if ( ! empty( $terms ) && is_array( $terms ) ) { + $options = '
            • '; + $options .= $this->loop_terms( $terms, $saved ); + $options .= '
          • '; + } + + return $options; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Multicheck.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Multicheck.php new file mode 100755 index 00000000..ce5a3ef5 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Multicheck.php @@ -0,0 +1,76 @@ +rendered( + $this->types->radio( array( + 'class' => $this->get_wrapper_classes(), + 'options' => $this->get_term_options(), + ), 'taxonomy_multicheck' ) + ); + } + + protected function get_term_options() { + $all_terms = $this->get_terms(); + + if ( ! $all_terms || is_wp_error( $all_terms ) ) { + return $this->no_terms_result( $all_terms ); + } + + return $this->loop_terms( $all_terms, $this->get_object_term_or_default() ); + } + + protected function loop_terms( $all_terms, $saved_terms ) { + $options = ''; + foreach ( $all_terms as $term ) { + $options .= $this->list_term_input( $term, $saved_terms ); + } + + return $options; + } + + protected function list_term_input( $term, $saved_terms ) { + $args = array( + 'value' => $term->slug, + 'label' => $term->name, + 'type' => 'checkbox', + 'name' => $this->_name() . '[]', + ); + + if ( is_array( $saved_terms ) && in_array( $term->slug, $saved_terms ) ) { + $args['checked'] = 'checked'; + } + + return $this->list_input( $args, ++$this->counter ); + } + + public function get_object_term_or_default() { + $saved_terms = $this->get_object_terms(); + + return is_wp_error( $saved_terms ) || empty( $saved_terms ) + ? $this->field->get_default() + : wp_list_pluck( $saved_terms, 'slug' ); + } + + protected function get_wrapper_classes() { + $classes = 'cmb2-checkbox-list cmb2-list'; + if ( false === $this->field->args( 'select_all_button' ) ) { + $classes .= ' no-select-all'; + } + + return $classes; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Multicheck_Hierarchical.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Multicheck_Hierarchical.php new file mode 100755 index 00000000..9fdadeaa --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Multicheck_Hierarchical.php @@ -0,0 +1,42 @@ +rendered( + $this->types->radio( array( + 'class' => $this->get_wrapper_classes(), + 'options' => $this->get_term_options(), + ), 'taxonomy_multicheck_hierarchical' ) + ); + } + + protected function list_term_input( $term, $saved_terms ) { + $options = parent::list_term_input( $term, $saved_terms ); + $children = $this->build_children( $term, $saved_terms ); + + if ( ! empty( $children ) ) { + $options .= $children; + } + + return $options; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Radio.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Radio.php new file mode 100755 index 00000000..410519ab --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Radio.php @@ -0,0 +1,92 @@ +rendered( + $this->types->radio( array( + 'options' => $this->get_term_options(), + ), 'taxonomy_radio' ) + ); + } + + protected function get_term_options() { + $all_terms = $this->get_terms(); + + if ( ! $all_terms || is_wp_error( $all_terms ) ) { + return $this->no_terms_result( $all_terms ); + } + + $saved_term = $this->get_object_term_or_default(); + $option_none = $this->field->args( 'show_option_none' ); + $options = ''; + + if ( ! empty( $option_none ) ) { + + $field_id = $this->_id(); + + /** + * Default (option-none) taxonomy-radio value. + * + * @since 1.3.0 + * + * @param string $option_none_value Default (option-none) taxonomy-radio value. + */ + $option_none_value = apply_filters( 'cmb2_taxonomy_radio_default_value', '' ); + + /** + * Default (option-none) taxonomy-radio value. + * + * The dynamic portion of the hook name, $field_id, refers to the field id attribute. + * + * @since 1.3.0 + * + * @param string $option_none_value Default (option-none) taxonomy-radio value. + */ + $option_none_value = apply_filters( "cmb2_taxonomy_radio_{$field_id}_default_value", $option_none_value ); + + $options .= $this->list_term_input( (object) array( + 'slug' => $option_none_value, + 'name' => $option_none, + ), $saved_term ); + } + + $options .= $this->loop_terms( $all_terms, $saved_term ); + + return $options; + } + + protected function loop_terms( $all_terms, $saved_term ) { + $options = ''; + foreach ( $all_terms as $term ) { + $options .= $this->list_term_input( $term, $saved_term ); + } + + return $options; + } + + protected function list_term_input( $term, $saved_term ) { + $args = array( + 'value' => $term->slug, + 'label' => $term->name, + ); + + if ( $saved_term == $term->slug ) { + $args['checked'] = 'checked'; + } + + return $this->list_input( $args, ++$this->counter ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Radio_Hierarchical.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Radio_Hierarchical.php new file mode 100755 index 00000000..90a1d82c --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Radio_Hierarchical.php @@ -0,0 +1,41 @@ +rendered( + $this->types->radio( array( + 'options' => $this->get_term_options(), + ), 'taxonomy_radio_hierarchical' ) + ); + } + + protected function list_term_input( $term, $saved_term ) { + $options = parent::list_term_input( $term, $saved_term ); + $children = $this->build_children( $term, $saved_term ); + + if ( ! empty( $children ) ) { + $options .= $children; + } + + return $options; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Select.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Select.php new file mode 100755 index 00000000..76921470 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Taxonomy_Select.php @@ -0,0 +1,79 @@ +get_terms(); + + if ( ! $all_terms || is_wp_error( $all_terms ) ) { + return $this->no_terms_result( $all_terms, 'strong' ); + } + + $saved_term = $this->get_object_term_or_default(); + $option_none = $this->field->args( 'show_option_none' ); + $options = ''; + + if ( ! empty( $option_none ) ) { + + $field_id = $this->_id(); + + /** + * Default (option-none) taxonomy-select value. + * + * @since 1.3.0 + * + * @param string $option_none_value Default (option-none) taxonomy-select value. + */ + $option_none_value = apply_filters( 'cmb2_taxonomy_select_default_value', '' ); + + /** + * Default (option-none) taxonomy-select value. + * + * The dynamic portion of the hook name, $field_id, refers to the field id attribute. + * + * @since 1.3.0 + * + * @param string $option_none_value Default (option-none) taxonomy-select value. + */ + $option_none_value = apply_filters( "cmb2_taxonomy_select_{$field_id}_default_value", $option_none_value ); + + $options .= $this->select_option( array( + 'label' => $option_none, + 'value' => $option_none_value, + 'checked' => $saved_term == $option_none_value, + ) ); + } + + $options .= $this->loop_terms( $all_terms, $saved_term ); + + return $this->rendered( + $this->types->select( array( + 'options' => $options, + ) ) + ); + } + + protected function loop_terms( $all_terms, $saved_term ) { + $options = ''; + + foreach ( $all_terms as $term ) { + $options .= $this->select_option( array( + 'label' => $term->name, + 'value' => $term->slug, + 'checked' => $saved_term === $term->slug, + ) ); + } + + return $options; + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text.php new file mode 100755 index 00000000..5416b9e7 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text.php @@ -0,0 +1,58 @@ +type = $type ? $type : $this->type; + } + + /** + * Handles outputting an 'input' element + * + * @since 1.1.0 + * @param array $args Override arguments + * @return string Form input element + */ + public function render( $args = array() ) { + $args = empty( $args ) ? $this->args : $args; + $a = $this->parse_args( $this->type, array( + 'type' => 'text', + 'class' => 'regular-text', + 'name' => $this->_name(), + 'id' => $this->_id(), + 'value' => $this->field->escaped_value(), + 'desc' => $this->_desc( true ), + 'js_dependencies' => array(), + ), $args ); + + return $this->rendered( + sprintf( '%s', $this->concat_attrs( $a, array( 'desc' ) ), $a['desc'] ) + ); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Date.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Date.php new file mode 100755 index 00000000..225c643f --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Date.php @@ -0,0 +1,30 @@ +parse_args( 'text_date', array( + 'class' => 'cmb2-text-small cmb2-datepicker', + 'value' => $this->field->get_timestamp_format(), + 'desc' => $this->_desc(), + 'js_dependencies' => array( 'jquery-ui-core', 'jquery-ui-datepicker' ), + ) ); + + if ( false === strpos( $args['class'], 'timepicker' ) ) { + $this->parse_picker_options( 'date' ); + } + + return parent::render( $args ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Datetime_Timestamp.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Datetime_Timestamp.php new file mode 100755 index 00000000..3608e090 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Datetime_Timestamp.php @@ -0,0 +1,73 @@ +field; + + $args = wp_parse_args( $this->args, array( + 'value' => $field->escaped_value(), + 'desc' => $this->_desc(), + 'datepicker' => array(), + 'timepicker' => array(), + ) ); + + if ( empty( $args['value'] ) ) { + $args['value'] = $field->escaped_value(); + // This will be used if there is a select_timezone set for this field + $tz_offset = $field->field_timezone_offset(); + if ( ! empty( $tz_offset ) ) { + $args['value'] -= $tz_offset; + } + } + + $has_good_value = ! empty( $args['value'] ) && ! is_array( $args['value'] ); + + $date_input = parent::render( $this->date_args( $args, $has_good_value ) ); + $time_input = parent::render( $this->time_args( $args, $has_good_value ) ); + + return $this->rendered( $date_input . "\n" . $time_input ); + } + + public function date_args( $args, $has_good_value ) { + $date_args = wp_parse_args( $args['datepicker'], array( + 'class' => 'cmb2-text-small cmb2-datepicker', + 'name' => $this->_name( '[date]' ), + 'id' => $this->_id( '_date' ), + 'value' => $has_good_value ? $this->field->get_timestamp_format( 'date_format', $args['value'] ) : '', + 'desc' => '', + ) ); + + $date_args['rendered'] = true; + + // Let's get the date-format, and set it up as a data attr for the field. + return $this->parse_picker_options( 'date', $date_args ); + } + + public function time_args( $args, $has_good_value ) { + $time_args = wp_parse_args( $args['timepicker'], array( + 'class' => 'cmb2-timepicker text-time', + 'name' => $this->_name( '[time]' ), + 'id' => $this->_id( '_time' ), + 'value' => $has_good_value ? $this->field->get_timestamp_format( 'time_format', $args['value'] ) : '', + 'desc' => $args['desc'], + 'js_dependencies' => array( 'jquery-ui-core', 'jquery-ui-datepicker', 'jquery-ui-datetimepicker' ), + ) ); + + $time_args['rendered'] = true; + + // Let's get the time-format, and set it up as a data attr for the field. + return $this->parse_picker_options( 'time', $time_args ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Datetime_Timestamp_Timezone.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Datetime_Timestamp_Timezone.php new file mode 100755 index 00000000..d0942932 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Datetime_Timestamp_Timezone.php @@ -0,0 +1,61 @@ +field; + + $args = wp_parse_args( $this->args, array( + 'value' => $field->escaped_value(), + 'desc' => $this->_desc( true ), + 'text_datetime_timestamp' => array(), + 'select_timezone' => array(), + ) ); + + $args['value'] = $field->escaped_value(); + if ( is_array( $args['value'] ) ) { + $args['value'] = ''; + } + + $datetime = maybe_unserialize( $args['value'] ); + $value = $tzstring = ''; + + if ( $datetime && $datetime instanceof DateTime ) { + $tz = $datetime->getTimezone(); + $tzstring = $tz->getName(); + $value = $datetime->getTimestamp(); + } + + $timestamp_args = wp_parse_args( $args['text_datetime_timestamp'], array( + 'desc' => '', + 'value' => $value, + 'rendered' => true, + ) ); + $datetime_timestamp = $this->types->text_datetime_timestamp( $timestamp_args ); + + $timezone_select_args = wp_parse_args( $args['select_timezone'], array( + 'class' => 'cmb2_select cmb2-select-timezone', + 'name' => $this->_name( '[timezone]' ), + 'id' => $this->_id( '_timezone' ), + 'options' => wp_timezone_choice( $tzstring ), + 'desc' => $args['desc'], + 'rendered' => true, + ) ); + $select = $this->types->select( $timezone_select_args ); + + return $this->rendered( + $datetime_timestamp . "\n" . $select + ); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Time.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Time.php new file mode 100755 index 00000000..8ce6b1fa --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Text_Time.php @@ -0,0 +1,25 @@ +args = $this->parse_picker_options( 'time', wp_parse_args( $this->args, array( + 'class' => 'cmb2-timepicker text-time', + 'value' => $this->field->get_timestamp_format( 'time_format' ), + 'js_dependencies' => array( 'jquery-ui-core', 'jquery-ui-datepicker', 'jquery-ui-datetimepicker' ), + ) ) ); + + return parent::render(); + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Textarea.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Textarea.php new file mode 100755 index 00000000..227a5322 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Textarea.php @@ -0,0 +1,38 @@ +args : $args; + $a = $this->parse_args( 'textarea', array( + 'class' => 'cmb2_textarea', + 'name' => $this->_name(), + 'id' => $this->_id(), + 'cols' => 60, + 'rows' => 10, + 'value' => $this->field->escaped_value( 'esc_textarea' ), + 'desc' => $this->_desc( true ), + ), $args ); + + return $this->rendered( + sprintf( '%s%s', $this->concat_attrs( $a, array( 'desc', 'value' ) ), $a['value'], $a['desc'] ) + ); + } +} diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Textarea_Code.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Textarea_Code.php new file mode 100755 index 00000000..ee36c01c --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Textarea_Code.php @@ -0,0 +1,39 @@ + 'cmb2-textarea-code', + 'desc' => '
            ' . $this->_desc( true ), + ) ); + + if ( true !== $this->field->options( 'disable_codemirror' ) + && function_exists( 'wp_enqueue_code_editor' ) ) { + $args['js_dependencies'] = array( 'code-editor' ); + } else { + $args['class'] = rtrim( $args['class'] ) . ' disable-codemirror'; + } + + return $this->rendered( + sprintf( '
            %s', parent::render( $args ) )
            +		);
            +	}
            +}
            diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Title.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Title.php
            new file mode 100755
            index 00000000..a90fdb52
            --- /dev/null
            +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Title.php
            @@ -0,0 +1,47 @@
            +field->args( 'name' );
            +		$tag  = 'span';
            +
            +		if ( ! empty( $name ) ) {
            +			$tag = $this->field->object_type == 'post' ? 'h5' : 'h3';
            +		}
            +
            +		$a = $this->parse_args( 'title', array(
            +			'tag'   => $tag,
            +			'class' => empty( $name ) ? 'cmb2-metabox-title-anchor' : 'cmb2-metabox-title',
            +			'name'  => $name,
            +			'desc'  => $this->_desc( true ),
            +			'id'    => str_replace( '_', '-', sanitize_html_class( $this->field->id() ) ),
            +		) );
            +
            +		return $this->rendered(
            +			sprintf(
            +				'<%1$s %2$s>%3$s%4$s',
            +				$a['tag'],
            +				$this->concat_attrs( $a, array( 'tag', 'name', 'desc' ) ),
            +				$a['name'],
            +				$a['desc']
            +			)
            +		);
            +	}
            +
            +}
            diff --git a/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Wysiwyg.php b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Wysiwyg.php
            new file mode 100755
            index 00000000..f9f49e08
            --- /dev/null
            +++ b/inc/vendors/cmb2-plugins/cmb2/includes/types/CMB2_Type_Wysiwyg.php
            @@ -0,0 +1,93 @@
            +field;
            +		$a = $this->parse_args( 'wysiwyg', array(
            +			'id'      => $this->_id(),
            +			'value'   => $field->escaped_value( 'stripslashes' ),
            +			'desc'    => $this->_desc( true ),
            +			'options' => $field->options(),
            +		) );
            +
            +		if ( ! $field->group ) {
            +			return $this->rendered( $this->get_wp_editor( $a ) . $a['desc'] );
            +		}
            +
            +		// wysiwyg fields in a group need some special handling.
            +
            +		$field->add_js_dependencies( 'wp-util' );
            +		$field->add_js_dependencies( 'cmb2-wysiwyg' );
            +
            +		// Hook in our template-output to the footer.
            +		add_action( is_admin() ? 'admin_footer' : 'wp_footer', array( $this, 'add_wysiwyg_template_for_group' ) );
            +
            +		return $this->rendered(
            +			sprintf( '
            %s', parent::render( array( + 'class' => 'cmb2_textarea cmb2-wysiwyg-placeholder', + 'data-groupid' => $field->group->id(), + 'data-iterator' => $field->group->index, + 'data-fieldid' => $field->id( true ), + 'desc' => '
            ' . $this->_desc( true ), + ) ) ) + ); + } + + protected function get_wp_editor( $args ) { + ob_start(); + wp_editor( $args['value'], $args['id'], $args['options'] ); + return ob_get_clean(); + } + + public function add_wysiwyg_template_for_group() { + $group_id = $this->field->group->id(); + $field_id = $this->field->id( true ); + $hash = $this->field->hash_id(); + $options = $this->field->options(); + $options['textarea_name'] = 'cmb2_n_' . $group_id . $field_id; + + // Initate the editor with special id/value/name so we can retrieve the options in JS. + $editor = $this->get_wp_editor( array( + 'value' => 'cmb2_v_' . $group_id . $field_id, + 'id' => 'cmb2_i_' . $group_id . $field_id, + 'options' => $options, + ) ); + + // Then replace the special id/value/name with underscore placeholders. + $editor = str_replace( array( + 'cmb2_n_' . $group_id . $field_id, + 'cmb2_v_' . $group_id . $field_id, + 'cmb2_i_' . $group_id . $field_id, + ), array( + '{{ data.name }}', + '{{{ data.value }}}', + '{{ data.id }}', + ), $editor ); + + // And put the editor instance in a JS template wrapper. + echo ''; + } + +} diff --git a/inc/vendors/cmb2-plugins/cmb2/index.php b/inc/vendors/cmb2-plugins/cmb2/index.php new file mode 100755 index 00000000..49d255dd --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/index.php @@ -0,0 +1 @@ +l10ni18n(); + + // Include helper functions. + require_once CMB2_DIR . 'includes/CMB2_Base.php'; + require_once CMB2_DIR . 'includes/CMB2.php'; + require_once CMB2_DIR . 'includes/helper-functions.php'; + + // Now kick off the class autoloader. + spl_autoload_register( 'cmb2_autoload_classes' ); + + // Kick the whole thing off. + require_once( cmb2_dir( 'bootstrap.php' ) ); + cmb2_bootstrap(); + } + + /** + * Registers CMB2 text domain path + * + * @since 2.0.0 + */ + public function l10ni18n() { + + $loaded = load_plugin_textdomain( 'cmb2', false, '/languages/' ); + + if ( ! $loaded ) { + $loaded = load_muplugin_textdomain( 'cmb2', '/languages/' ); + } + + if ( ! $loaded ) { + $loaded = load_theme_textdomain( 'cmb2', get_stylesheet_directory() . '/languages/' ); + } + + if ( ! $loaded ) { + $locale = apply_filters( 'plugin_locale', get_locale(), 'cmb2' ); + $mofile = dirname( __FILE__ ) . '/languages/cmb2-' . $locale . '.mo'; + load_textdomain( 'cmb2', $mofile ); + } + + } + + } + + // Make it so... + CMB2_Bootstrap_260::initiate(); + +}// End if(). diff --git a/inc/vendors/cmb2-plugins/cmb2/js/cmb2-wysiwyg.js b/inc/vendors/cmb2-plugins/cmb2/js/cmb2-wysiwyg.js new file mode 100755 index 00000000..111e7ea0 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/js/cmb2-wysiwyg.js @@ -0,0 +1,345 @@ +/** + * Used for WYSIWYG logic + */ +window.CMB2 = window.CMB2 || {}; +window.CMB2.wysiwyg = window.CMB2.wysiwyg || {}; + +( function(window, document, $, cmb, wysiwyg, undefined ) { + 'use strict'; + + // Private variables + var toBeDestroyed = []; + var toBeInitialized = []; + var all = wysiwyg.all = {}; + + // Private functions + + /** + * Initializes any editors that weren't initialized because they didn't exist yet. + * + * @since 2.2.3 + * + * @return {void} + */ + function delayedInit() { + + // Don't initialize until they've all been destroyed. + if ( 0 === toBeDestroyed.length ) { + toBeInitialized.forEach( function ( toInit ) { + toBeInitialized.splice( toBeInitialized.indexOf( toInit ), 1 ); + wysiwyg.init.apply( wysiwyg, toInit ); + } ); + } else { + window.setTimeout( delayedInit, 100 ); + } + } + + /** + * Destroys any editors that weren't destroyed because they didn't exist yet. + * + * @since 2.2.3 + * + * @return {void} + */ + function delayedDestroy() { + toBeDestroyed.forEach( function( id ) { + toBeDestroyed.splice( toBeDestroyed.indexOf( id ), 1 ); + wysiwyg.destroy( id ); + } ); + } + + /** + * Gets the option data for a group (and initializes that data if it doesn't exist). + * + * @since 2.2.3 + * + * @param {object} data The group/field data. + * + * @return {object} Options data object for a group. + */ + function getGroupData( data ) { + var groupid = data.groupid; + var fieldid = data.fieldid; + + if ( ! all[ groupid ] || ! all[ groupid ][ fieldid ] ) { + all[ groupid ] = all[ groupid ] || {}; + all[ groupid ][ fieldid ] = { + template : wp.template( 'cmb2-wysiwyg-' + groupid + '-' + fieldid ), + defaults : { + + // Get the data from the template-wysiwyg initiation. + mce : $.extend( {}, tinyMCEPreInit.mceInit[ 'cmb2_i_' + groupid + fieldid ] ), + qt : $.extend( {}, tinyMCEPreInit.qtInit[ 'cmb2_i_' + groupid + fieldid ] ) + } + }; + // This is the template-wysiwyg data, and we do not want that to be initiated. + delete tinyMCEPreInit.mceInit[ 'cmb2_i_' + groupid + fieldid ]; + delete tinyMCEPreInit.qtInit[ 'cmb2_i_' + groupid + fieldid ]; + } + + return all[ groupid ][ fieldid ]; + } + + /** + * Initiates the tinyMCEPreInit options for a wysiwyg editor instance. + * + * @since 2.2.3 + * + * @param {object} options Options data object for the wysiwyg editor instance. + * + * @return {void} + */ + function initOptions( options ) { + var nameRegex = new RegExp( 'cmb2_n_' + options.groupid + options.fieldid, 'g' ); + var idRegex = new RegExp( 'cmb2_i_' + options.groupid + options.fieldid, 'g' ); + var prop, newSettings, newQTS; + + // If no settings for this field. Clone from placeholder. + if ( 'undefined' === typeof( tinyMCEPreInit.mceInit[ options.id ] ) ) { + newSettings = $.extend( {}, options.defaults.mce ); + for ( prop in newSettings ) { + if ( 'string' === typeof( newSettings[ prop ] ) ) { + newSettings[ prop ] = newSettings[ prop ] + .replace( idRegex, options.id ) + .replace( nameRegex, options.name ); + } + } + tinyMCEPreInit.mceInit[ options.id ] = newSettings; + } + + // If no Quicktag settings for this field. Clone from placeholder. + if ( 'undefined' === typeof( tinyMCEPreInit.qtInit[ options.id ] ) ) { + newQTS = $.extend( {}, options.defaults.qt ); + for ( prop in newQTS ) { + if ( 'string' === typeof( newQTS[ prop ] ) ) { + newQTS[ prop ] = newQTS[ prop ] + .replace( idRegex, options.id ) + .replace( nameRegex, options.name ); + } + } + tinyMCEPreInit.qtInit[ options.id ] = newQTS; + } + } + + /** + * Initializes all group wysiwyg editors. Hooked to cmb_init. + * + * @since 2.2.3 + * + * @return {void} + */ + wysiwyg.initAll = function() { + var $this,data,initiated; + + $( '.cmb2-wysiwyg-placeholder' ).each( function() { + $this = $( this ); + data = $this.data(); + + if ( data.groupid ) { + + data.id = $this.attr( 'id' ); + data.name = $this.attr( 'name' ); + data.value = $this.val(); + + wysiwyg.init( $this, data, false ); + initiated = true; + } + } ); + + if ( true === initiated ) { + if ( 'undefined' !== typeof window.QTags ) { + window.QTags._buttonsInit(); + } + + // Hook in our event callbacks. + $( document ) + .on( 'cmb2_add_row', wysiwyg.addRow ) + .on( 'cmb2_remove_group_row_start', wysiwyg.destroyRowEditors ) + .on( 'cmb2_shift_rows_start', wysiwyg.shiftStart ) + .on( 'cmb2_shift_rows_complete', wysiwyg.shiftComplete ); + } + }; + + /** + * Initiates wysiwyg editors in a new group row. Hooked to cmb2_add_row. + * + * @since 2.2.3 + * + * @param {object} evt A jQuery-normalized event object. + * @param {object} $row A jQuery dom element object for the group row. + * + * @return {void} + */ + wysiwyg.addRow = function( evt, $row ) { + wysiwyg.initRow( $row, evt ); + }; + + /** + * Destroys wysiwyg editors in a group row when that row is removed. Hooked to cmb2_remove_group_row_start. + * + * @since 2.2.3 + * + * @param {object} evt A jQuery-normalized event object. + * @param {object} $btn A jQuery dom element object for the remove-row button. + * + * @return {void} + */ + wysiwyg.destroyRowEditors = function( evt, $btn ) { + wysiwyg.destroy( $btn.parents( '.cmb-repeatable-grouping' ).find( '.wp-editor-area' ).attr( 'id' ) ); + }; + + /** + * When a row-shift starts, we need to destroy the wysiwyg editors for the group-rows being shuffled. + * + * @since 2.2.3 + * + * @param {object} evt A jQuery-normalized event object. + * @param {object} $btn A jQuery dom element object for the remove-row button. + * @param {object} $from A jQuery dom element object for the row being shifted from. + * @param {object} $to A jQuery dom element object for the row being shifted to. + * + * @return {void} + */ + wysiwyg.shiftStart = function( evt, $btn, $from, $to ) { + $from.add( $to ).find( '.wp-editor-wrap textarea' ).each( function() { + wysiwyg.destroy( $( this ).attr( 'id' ) ); + } ); + }; + + /** + * When a row-shift completes, we need to re-init the wysiwyg editors for the group-rows being shuffled. + * + * @since 2.2.3 + * + * @param {object} evt A jQuery-normalized event object. + * @param {object} $btn A jQuery dom element object for the remove-row button. + * @param {object} $from A jQuery dom element object for the row being shifted from. + * @param {object} $to A jQuery dom element object for the row being shifted to. + * + * @return {void} + */ + wysiwyg.shiftComplete = function( evt, $btn, $from, $to ) { + $from.add( $to ).each( function() { + wysiwyg.initRow( $( this ), evt ); + } ); + }; + + /** + * Initializes editors for a new CMB row. + * + * @since 2.2.3 + * + * @param {object} $row A jQuery dom element object for the group row. + * @param {object} evt A jQuery-normalized event object. + * + * @return {void} + */ + wysiwyg.initRow = function( $row, evt ) { + var $toReplace, data, defVal; + + $row.find( '.cmb2-wysiwyg-inner-wrap' ).each( function() { + $toReplace = $( this ); + data = $toReplace.data(); + defVal = cmb.getFieldArg( data.hash, 'default', '' ); + defVal = 'undefined' !== typeof defVal && false !== defVal ? defVal : ''; + + data.iterator = $row.data( 'iterator' ); + data.fieldid = data.id; + data.id = data.groupid + '_' + data.iterator + '_' + data.fieldid; + data.name = data.groupid + '[' + data.iterator + '][' + data.fieldid + ']'; + data.value = 'cmb2_add_row' !== evt.type && $toReplace.find( '.wp-editor-area' ).length ? $toReplace.find( '.wp-editor-area' ).val() : defVal; + + // The destroys might not have happened yet. Don't init until they have. + if ( 0 === toBeDestroyed.length ) { + + wysiwyg.init( $toReplace, data ); + + } else { + toBeInitialized.push( [$toReplace, data] ); + window.setTimeout( delayedInit, 100 ); + } + } ); + + }; + + /** + * Initiates a wysiwyg editor instance and replaces the passed dom element w/ the editor html. + * + * @since 2.2.3 + * + * @param {object} $toReplace A jQuery dom element which will be replaced with the wysiwyg editor. + * @param {object} data Data used to initate the editor. + * @param {bool} buttonsInit Whether to run QTags._buttonsInit() + * + * @return {void} + */ + wysiwyg.init = function( $toReplace, data, buttonsInit ) { + if ( ! data.groupid ) { + return false; + } + + var mceActive = cmb.canTinyMCE(); + var qtActive = 'function' === typeof window.quicktags; + $.extend( data, getGroupData( data ) ); + + initOptions( data ); + + $toReplace.replaceWith( data.template( data ) ); + + if ( mceActive ) { + window.tinyMCE.init( tinyMCEPreInit.mceInit[ data.id ] ); + } + + if ( qtActive ) { + window.quicktags( tinyMCEPreInit.qtInit[ data.id ] ); + } + + if ( mceActive ) { + $( document.getElementById( data.id ) ).parents( '.wp-editor-wrap' ).removeClass( 'html-active' ).addClass( 'tmce-active' ); + } + + if ( false !== buttonsInit && 'undefined' !== typeof window.QTags ) { + window.QTags._buttonsInit(); + } + + }; + + /** + * Destroys a wysiwyg editor instance. + * + * @since 2.2.3 + * + * @param {string} id Editor id. + * + * @return {void} + */ + wysiwyg.destroy = function( id ) { + if ( ! cmb.canTinyMCE() ) { + // Nothing to see here. + return; + } + + // The editor might not be initialized yet. But we need to destroy it once it is. + var editor = tinyMCE.get( id ); + + if ( editor !== null && typeof( editor ) !== 'undefined' ) { + editor.destroy(); + + if ( 'undefined' === typeof( tinyMCEPreInit.mceInit[ id ] ) ) { + delete tinyMCEPreInit.mceInit[ id ]; + } + + if ( 'undefined' === typeof( tinyMCEPreInit.qtInit[ id ] ) ) { + delete tinyMCEPreInit.qtInit[ id ]; + } + + } else if ( -1 === toBeDestroyed.indexOf( id ) ) { + toBeDestroyed.push( id ); + window.setTimeout( delayedDestroy, 100 ); + } + }; + + // Hook in our event callbacks. + $( document ).on( 'cmb_init', wysiwyg.initAll ); + +} )( window, document, jQuery, window.CMB2, window.CMB2.wysiwyg ); diff --git a/inc/vendors/cmb2-plugins/cmb2/js/cmb2.js b/inc/vendors/cmb2-plugins/cmb2/js/cmb2.js new file mode 100755 index 00000000..96c78e23 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/js/cmb2.js @@ -0,0 +1,1344 @@ +/** + * Controls the behaviours of custom metabox fields. + * + * @author CMB2 team + * @see https://github.com/CMB2/CMB2 + */ + +/** + * Custom jQuery for Custom Metaboxes and Fields + */ +window.CMB2 = window.CMB2 || {}; +(function(window, document, $, cmb, undefined){ + 'use strict'; + + // localization strings + var l10n = window.cmb2_l10; + var setTimeout = window.setTimeout; + var $document; + var $id = function( selector ) { + return $( document.getElementById( selector ) ); + }; + var defaults = { + idNumber : false, + repeatEls : 'input:not([type="button"],[id^=filelist]),select,textarea,.cmb2-media-status', + noEmpty : 'input:not([type="button"]):not([type="radio"]):not([type="checkbox"]),textarea', + repeatUpdate : 'input:not([type="button"]),select,textarea,label', + styleBreakPoint : 450, + mediaHandlers : {}, + defaults : { + time_picker : l10n.defaults.time_picker, + date_picker : l10n.defaults.date_picker, + color_picker : l10n.defaults.color_picker || {}, + code_editor : l10n.defaults.code_editor, + }, + media : { + frames : {}, + }, + }; + + cmb.init = function() { + $document = $( document ); + + // Setup the CMB2 object defaults. + $.extend( cmb, defaults ); + + cmb.trigger( 'cmb_pre_init' ); + + var $metabox = cmb.metabox(); + var $repeatGroup = $metabox.find('.cmb-repeatable-group'); + + // Init time/date/color pickers + cmb.initPickers( $metabox.find('input[type="text"].cmb2-timepicker'), $metabox.find('input[type="text"].cmb2-datepicker'), $metabox.find('input[type="text"].cmb2-colorpicker') ); + + // Init code editors. + cmb.initCodeEditors( $metabox.find( '.cmb2-textarea-code:not(.disable-codemirror)' ) ); + + // Insert toggle button into DOM wherever there is multicheck. credit: Genesis Framework + $( '

            ' + l10n.strings.check_toggle + '

            ' ).insertBefore( '.cmb2-checkbox-list:not(.no-select-all)' ); + + // Make File List drag/drop sortable: + cmb.makeListSortable(); + // Make Repeatable fields drag/drop sortable: + cmb.makeRepeatableSortable(); + + $metabox + .on( 'change', '.cmb2_upload_file', function() { + cmb.media.field = $( this ).attr( 'id' ); + $id( cmb.media.field + '_id' ).val(''); + }) + // Media/file management + .on( 'click', '.cmb-multicheck-toggle', cmb.toggleCheckBoxes ) + .on( 'click', '.cmb2-upload-button', cmb.handleMedia ) + .on( 'click', '.cmb-attach-list li, .cmb2-media-status .img-status img, .cmb2-media-status .file-status > span', cmb.handleFileClick ) + .on( 'click', '.cmb2-remove-file-button', cmb.handleRemoveMedia ) + // Repeatable content + .on( 'click', '.cmb-add-group-row', cmb.addGroupRow ) + .on( 'click', '.cmb-add-row-button', cmb.addAjaxRow ) + .on( 'click', '.cmb-remove-group-row', cmb.removeGroupRow ) + .on( 'click', '.cmb-remove-row-button', cmb.removeAjaxRow ) + // Ajax oEmbed display + .on( 'keyup paste focusout', '.cmb2-oembed', cmb.maybeOembed ) + // Reset titles when removing a row + .on( 'cmb2_remove_row', '.cmb-repeatable-group', cmb.resetTitlesAndIterator ) + .on( 'click', '.cmbhandle, .cmbhandle + .cmbhandle-title', cmb.toggleHandle ); + + if ( $repeatGroup.length ) { + $repeatGroup + .on( 'cmb2_add_row', cmb.emptyValue ) + .on( 'cmb2_add_row', cmb.setDefaults ) + .filter('.sortable').each( function() { + // Add sorting arrows + $( this ).find( '.cmb-remove-group-row-button' ).before( ' ' ); + }) + .on( 'click', '.cmb-shift-rows', cmb.shiftRows ); + } + + // on pageload + setTimeout( cmb.resizeoEmbeds, 500); + // and on window resize + $( window ).on( 'resize', cmb.resizeoEmbeds ); + + if ( $id( 'addtag' ).length ) { + cmb.listenTagAdd(); + } + + $( document ).on( 'cmb_init', cmb.mceEnsureSave ); + + cmb.trigger( 'cmb_init' ); + }; + + // Handles updating tiny mce instances when saving a gutenberg post. + // https://github.com/CMB2/CMB2/issues/1156 + cmb.mceEnsureSave = function() { + // If no wp.data, do not proceed (no gutenberg) + if ( ! wp.data || ! wp.data.hasOwnProperty('subscribe') ) { + return; + } + + // If the current user cannot richedit, or MCE is not available, bail. + if ( ! cmb.canTinyMCE() ) { + return; + } + + wp.data.subscribe( function() { + var editor = wp.data.hasOwnProperty('select') ? wp.data.select( 'core/editor' ) : null; + + // the post is currently being saved && we have tinymce editors + if ( editor && editor.isSavingPost && editor.isSavingPost() && window.tinyMCE.editors.length ) { + for ( var i = 0; i < window.tinyMCE.editors.length; i++ ) { + if ( window.tinyMCE.activeEditor !== window.tinyMCE.editors[i] ) { + window.tinyMCE.editors[i].save(); + } + } + } + }); + }; + + cmb.canTinyMCE = function() { + return l10n.user_can_richedit && window.tinyMCE; + }; + + cmb.listenTagAdd = function() { + $document.ajaxSuccess( function( evt, xhr, settings ) { + if ( settings.data && settings.data.length && -1 !== settings.data.indexOf( 'action=add-tag' ) ) { + cmb.resetBoxes( $id( 'addtag' ).find( '.cmb2-wrap > .cmb2-metabox' ) ); + } + }); + }; + + cmb.resetBoxes = function( $boxes ) { + $.each( $boxes, function() { + cmb.resetBox( $( this ) ); + }); + }; + + cmb.resetBox = function( $box ) { + $box.find( '.wp-picker-clear' ).trigger( 'click' ); + $box.find( '.cmb2-remove-file-button' ).trigger( 'click' ); + $box.find( '.cmb-row.cmb-repeatable-grouping:not(:first-of-type) .cmb-remove-group-row' ).click(); + $box.find( '.cmb-repeat-row:not(:first-child)' ).remove(); + + $box.find( 'input:not([type="button"]),select,textarea' ).each( function() { + var $element = $( this ); + var tagName = $element.prop('tagName'); + + if ( 'INPUT' === tagName ) { + var elType = $element.attr( 'type' ); + if ( 'checkbox' === elType || 'radio' === elType ) { + $element.prop( 'checked', false ); + } else { + $element.val( '' ); + } + } + if ( 'SELECT' === tagName ) { + $( 'option:selected', this ).prop( 'selected', false ); + } + if ( 'TEXTAREA' === tagName ) { + $element.html( '' ); + } + }); + }; + + cmb.resetTitlesAndIterator = function( evt ) { + if ( ! evt.group ) { + return; + } + + // Loop repeatable group tables + $( '.cmb-repeatable-group.repeatable' ).each( function() { + var $table = $( this ); + var groupTitle = $table.find( '.cmb-add-group-row' ).data( 'grouptitle' ); + + // Loop repeatable group table rows + $table.find( '.cmb-repeatable-grouping' ).each( function( rowindex ) { + var $row = $( this ); + var $rowTitle = $row.find( 'h3.cmb-group-title' ); + // Reset rows iterator + $row.data( 'iterator', rowindex ); + // Reset rows title + if ( $rowTitle.length ) { + $rowTitle.text( groupTitle.replace( '{#}', ( rowindex + 1 ) ) ); + } + }); + }); + }; + + cmb.toggleHandle = function( evt ) { + evt.preventDefault(); + cmb.trigger( 'postbox-toggled', $( this ).parent('.postbox').toggleClass('closed') ); + }; + + cmb.toggleCheckBoxes = function( evt ) { + evt.preventDefault(); + var $this = $( this ); + var $multicheck = $this.closest( '.cmb-td' ).find( 'input[type=checkbox]:not([disabled])' ); + + // If the button has already been clicked once... + if ( $this.data( 'checked' ) ) { + // clear the checkboxes and remove the flag + $multicheck.prop( 'checked', false ); + $this.data( 'checked', false ); + } + // Otherwise mark the checkboxes and add a flag + else { + $multicheck.prop( 'checked', true ); + $this.data( 'checked', true ); + } + }; + + cmb.handleMedia = function( evt ) { + evt.preventDefault(); + + var $el = $( this ); + cmb.attach_id = ! $el.hasClass( 'cmb2-upload-list' ) ? $el.closest( '.cmb-td' ).find( '.cmb2-upload-file-id' ).val() : false; + // Clean up default 0 value + cmb.attach_id = '0' !== cmb.attach_id ? cmb.attach_id : false; + + cmb._handleMedia( $el.prev('input.cmb2-upload-file').attr('id'), $el.hasClass( 'cmb2-upload-list' ) ); + }; + + cmb.handleFileClick = function( evt ) { + if ( $( evt.target ).is( 'a' ) ) { + return; + } + + evt.preventDefault(); + + var $el = $( this ); + var $td = $el.closest( '.cmb-td' ); + var isList = $td.find( '.cmb2-upload-button' ).hasClass( 'cmb2-upload-list' ); + cmb.attach_id = isList ? $el.find( 'input[type="hidden"]' ).data( 'id' ) : $td.find( '.cmb2-upload-file-id' ).val(); + + if ( cmb.attach_id ) { + cmb._handleMedia( $td.find( 'input.cmb2-upload-file' ).attr( 'id' ), isList, cmb.attach_id ); + } + }; + + cmb._handleMedia = function( id, isList ) { + if ( ! wp ) { + return; + } + + var media, handlers; + + handlers = cmb.mediaHandlers; + media = cmb.media; + media.field = id; + media.$field = $id( media.field ); + media.fieldData = media.$field.data(); + media.previewSize = media.fieldData.previewsize; + media.sizeName = media.fieldData.sizename; + media.fieldName = media.$field.attr('name'); + media.isList = isList; + + // If this field's media frame already exists, reopen it. + if ( id in media.frames ) { + return media.frames[ id ].open(); + } + + // Create the media frame. + media.frames[ id ] = wp.media( { + title: cmb.metabox().find('label[for="' + id + '"]').text(), + library : media.fieldData.queryargs || {}, + button: { + text: l10n.strings[ isList ? 'upload_files' : 'upload_file' ] + }, + multiple: isList ? 'add' : false + } ); + + // Enable the additional media filters: https://github.com/CMB2/CMB2/issues/873 + media.frames[ id ].states.first().set( 'filterable', 'all' ); + + cmb.trigger( 'cmb_media_modal_init', media ); + + handlers.list = function( selection, returnIt ) { + + // Setup our fileGroup array + var fileGroup = []; + var attachmentHtml; + + if ( ! handlers.list.templates ) { + handlers.list.templates = { + image : wp.template( 'cmb2-list-image' ), + file : wp.template( 'cmb2-list-file' ), + }; + } + + // Loop through each attachment + selection.each( function( attachment ) { + + // Image preview or standard generic output if it's not an image. + attachmentHtml = handlers.getAttachmentHtml( attachment, 'list' ); + + // Add our file to our fileGroup array + fileGroup.push( attachmentHtml ); + }); + + if ( ! returnIt ) { + // Append each item from our fileGroup array to .cmb2-media-status + media.$field.siblings( '.cmb2-media-status' ).append( fileGroup ); + } else { + return fileGroup; + } + + }; + + handlers.single = function( selection ) { + if ( ! handlers.single.templates ) { + handlers.single.templates = { + image : wp.template( 'cmb2-single-image' ), + file : wp.template( 'cmb2-single-file' ), + }; + } + + // Only get one file from the uploader + var attachment = selection.first(); + + media.$field.val( attachment.get( 'url' ) ); + $id( media.field +'_id' ).val( attachment.get( 'id' ) ); + + // Image preview or standard generic output if it's not an image. + var attachmentHtml = handlers.getAttachmentHtml( attachment, 'single' ); + + // add/display our output + media.$field.siblings( '.cmb2-media-status' ).slideDown().html( attachmentHtml ); + }; + + handlers.getAttachmentHtml = function( attachment, templatesId ) { + var isImage = 'image' === attachment.get( 'type' ); + var data = handlers.prepareData( attachment, isImage ); + + // Image preview or standard generic output if it's not an image. + return handlers[ templatesId ].templates[ isImage ? 'image' : 'file' ]( data ); + }; + + handlers.prepareData = function( data, image ) { + if ( image ) { + // Set the correct image size data + handlers.getImageData.call( data, 50 ); + } + + data = data.toJSON(); + data.mediaField = media.field; + data.mediaFieldName = media.fieldName; + data.stringRemoveImage = l10n.strings.remove_image; + data.stringFile = l10n.strings.file; + data.stringDownload = l10n.strings.download; + data.stringRemoveFile = l10n.strings.remove_file; + + return data; + }; + + handlers.getImageData = function( fallbackSize ) { + + // Preview size dimensions + var previewW = media.previewSize[0] || fallbackSize; + var previewH = media.previewSize[1] || fallbackSize; + + // Image dimensions and url + var url = this.get( 'url' ); + var width = this.get( 'width' ); + var height = this.get( 'height' ); + var sizes = this.get( 'sizes' ); + + // Get the correct dimensions and url if a named size is set and exists + // fallback to the 'large' size + if ( sizes ) { + if ( sizes[ media.sizeName ] ) { + url = sizes[ media.sizeName ].url; + width = sizes[ media.sizeName ].width; + height = sizes[ media.sizeName ].height; + } else if ( sizes.large ) { + url = sizes.large.url; + width = sizes.large.width; + height = sizes.large.height; + } + } + + // Fit the image in to the preview size, keeping the correct aspect ratio + if ( width > previewW ) { + height = Math.floor( previewW * height / width ); + width = previewW; + } + + if ( height > previewH ) { + width = Math.floor( previewH * width / height ); + height = previewH; + } + + if ( ! width ) { + width = previewW; + } + + if ( ! height ) { + height = 'svg' === this.get( 'filename' ).split( '.' ).pop() ? '100%' : previewH; + } + + this.set( 'sizeUrl', url ); + this.set( 'sizeWidth', width ); + this.set( 'sizeHeight', height ); + + return this; + }; + + handlers.selectFile = function() { + var selection = media.frames[ id ].state().get( 'selection' ); + var type = isList ? 'list' : 'single'; + + if ( cmb.attach_id && isList ) { + $( '[data-id="'+ cmb.attach_id +'"]' ).parents( 'li' ).replaceWith( handlers.list( selection, true ) ); + } else { + handlers[type]( selection ); + } + + cmb.trigger( 'cmb_media_modal_select', selection, media ); + }; + + handlers.openModal = function() { + var selection = media.frames[ id ].state().get( 'selection' ); + var attach; + + if ( ! cmb.attach_id ) { + selection.reset(); + } else { + attach = wp.media.attachment( cmb.attach_id ); + attach.fetch(); + selection.set( attach ? [ attach ] : [] ); + } + + cmb.trigger( 'cmb_media_modal_open', selection, media ); + }; + + // When a file is selected, run a callback. + media.frames[ id ] + .on( 'select', handlers.selectFile ) + .on( 'open', handlers.openModal ); + + // Finally, open the modal + media.frames[ id ].open(); + }; + + cmb.handleRemoveMedia = function( evt ) { + evt.preventDefault(); + var $this = $( this ); + if ( $this.is( '.cmb-attach-list .cmb2-remove-file-button' ) ) { + $this.parents( '.cmb2-media-item' ).remove(); + return false; + } + + cmb.media.field = $this.attr('rel'); + + cmb.metabox().find( document.getElementById( cmb.media.field ) ).val(''); + cmb.metabox().find( document.getElementById( cmb.media.field + '_id' ) ).val(''); + $this.parents('.cmb2-media-status').html(''); + + return false; + }; + + cmb.cleanRow = function( $row, prevNum, group ) { + var $elements = $row.find( cmb.repeatUpdate ); + if ( group ) { + + var $other = $row.find( '[id]' ).not( cmb.repeatUpdate ); + + // Remove extra ajaxed rows + $row.find('.cmb-repeat-table .cmb-repeat-row:not(:first-child)').remove(); + + // Update all elements w/ an ID + if ( $other.length ) { + $other.each( function() { + var $_this = $( this ); + var oldID = $_this.attr( 'id' ); + var newID = oldID.replace( '_'+ prevNum, '_'+ cmb.idNumber ); + var $buttons = $row.find('[data-selector="'+ oldID +'"]'); + $_this.attr( 'id', newID ); + + // Replace data-selector vars + if ( $buttons.length ) { + $buttons.attr( 'data-selector', newID ).data( 'selector', newID ); + } + }); + } + } + + $elements.filter( ':checked' ).removeAttr( 'checked' ); + $elements.find( ':checked' ).removeAttr( 'checked' ); + $elements.filter( ':selected' ).removeAttr( 'selected' ); + $elements.find( ':selected' ).removeAttr( 'selected', false ); + + if ( $row.find('h3.cmb-group-title').length ) { + $row.find( 'h3.cmb-group-title' ).text( $row.data( 'title' ).replace( '{#}', ( cmb.idNumber + 1 ) ) ); + } + + $elements.each( function() { + cmb.elReplacements( $( this ), prevNum, group ); + } ); + + return cmb; + }; + + cmb.elReplacements = function( $newInput, prevNum, group ) { + var oldFor = $newInput.attr( 'for' ); + var oldVal = $newInput.val(); + var type = $newInput.prop( 'type' ); + var defVal = cmb.getFieldArg( $newInput, 'default' ); + var newVal = 'undefined' !== typeof defVal && false !== defVal ? defVal : ''; + var tagName = $newInput.prop('tagName'); + var checkable = 'radio' === type || 'checkbox' === type ? oldVal : false; + var attrs = {}; + var newID, oldID; + if ( oldFor ) { + attrs = { 'for' : oldFor.replace( '_'+ prevNum, '_'+ cmb.idNumber ) }; + } else { + var oldName = $newInput.attr( 'name' ); + var newName; + oldID = $newInput.attr( 'id' ); + + // Handle adding groups vs rows. + if ( group ) { + // Expect another bracket after group's index closing bracket. + newName = oldName ? oldName.replace( '['+ prevNum +'][', '['+ cmb.idNumber +'][' ) : ''; + // Expect another underscore after group's index trailing underscore. + newID = oldID ? oldID.replace( '_' + prevNum + '_', '_' + cmb.idNumber + '_' ) : ''; + } + else { + // Row indexes are at the very end of the string. + newName = oldName ? cmb.replaceLast( oldName, '[' + prevNum + ']', '[' + cmb.idNumber + ']' ) : ''; + newID = oldID ? cmb.replaceLast( oldID, '_' + prevNum, '_' + cmb.idNumber ) : ''; + } + + attrs = { + id: newID, + name: newName + }; + + } + + // Clear out textarea values + if ( 'TEXTAREA' === tagName ) { + $newInput.html( newVal ); + } + + if ( 'SELECT' === tagName && 'undefined' !== typeof defVal ) { + var $toSelect = $newInput.find( '[value="'+ defVal + '"]' ); + if ( $toSelect.length ) { + $toSelect.attr( 'selected', 'selected' ).prop( 'selected', 'selected' ); + } + } + + if ( checkable ) { + $newInput.removeAttr( 'checked' ); + if ( 'undefined' !== typeof defVal && oldVal === defVal ) { + $newInput.attr( 'checked', 'checked' ).prop( 'checked', 'checked' ); + } + } + + if ( ! group && $newInput[0].hasAttribute( 'data-iterator' ) ) { + attrs['data-iterator'] = cmb.idNumber; + } + + $newInput + .removeClass( 'hasDatepicker' ) + .val( checkable ? checkable : newVal ).attr( attrs ); + + return $newInput; + }; + + cmb.newRowHousekeeping = function( $row ) { + var $colorPicker = $row.find( '.wp-picker-container' ); + var $list = $row.find( '.cmb2-media-status' ); + + if ( $colorPicker.length ) { + // Need to clean-up colorpicker before appending + $colorPicker.each( function() { + var $td = $( this ).parent(); + $td.html( $td.find( 'input[type="text"].cmb2-colorpicker' ).attr('style', '') ); + }); + } + + // Need to clean-up colorpicker before appending + if ( $list.length ) { + $list.empty(); + } + + return cmb; + }; + + cmb.afterRowInsert = function( $row ) { + // Init pickers from new row + cmb.initPickers( $row.find('input[type="text"].cmb2-timepicker'), $row.find('input[type="text"].cmb2-datepicker'), $row.find('input[type="text"].cmb2-colorpicker') ); + }; + + cmb.updateNameAttr = function () { + var $this = $( this ); + var name = $this.attr( 'name' ); // get current name + + // If name is defined + if ( 'undefined' !== typeof name ) { + var prevNum = parseInt( $this.parents( '.cmb-repeatable-grouping' ).data( 'iterator' ), 10 ); + var newNum = prevNum - 1; // Subtract 1 to get new iterator number + + // Update field name attributes so data is not orphaned when a row is removed and post is saved + var $newName = name.replace( '[' + prevNum + ']', '[' + newNum + ']' ); + + // New name with replaced iterator + $this.attr( 'name', $newName ); + } + }; + + cmb.emptyValue = function( evt, row ) { + $( cmb.noEmpty, row ).val( '' ); + }; + + cmb.setDefaults = function( evt, row ) { + $( cmb.noEmpty, row ).each( function() { + var $el = $(this); + var defVal = cmb.getFieldArg( $el, 'default' ); + if ( 'undefined' !== typeof defVal && false !== defVal ) { + $el.val( defVal ); + } + }); + }; + + cmb.addGroupRow = function( evt ) { + evt.preventDefault(); + + var $this = $( this ); + + // before anything significant happens + cmb.triggerElement( $this, 'cmb2_add_group_row_start', $this ); + + var $table = $id( $this.data('selector') ); + var $oldRow = $table.find('.cmb-repeatable-grouping').last(); + var prevNum = parseInt( $oldRow.data('iterator'), 10 ); + cmb.idNumber = parseInt( prevNum, 10 ) + 1; + var $row = $oldRow.clone(); + var nodeName = $row.prop('nodeName') || 'div'; + var getRowId = function( id ) { + id = id.split('-'); + id.splice(id.length - 1, 1); + id.push( cmb.idNumber ); + return id.join('-'); + }; + + // Make sure the next number doesn't exist. + while ( $table.find( '.cmb-repeatable-grouping[data-iterator="'+ cmb.idNumber +'"]' ).length > 0 ) { + cmb.idNumber++; + } + + cmb.newRowHousekeeping( $row.data( 'title', $this.data( 'grouptitle' ) ) ).cleanRow( $row, prevNum, true ); + $row.find( '.cmb-add-row-button' ).prop( 'disabled', false ); + + var $newRow = $( '<' + nodeName + ' id="'+ getRowId( $oldRow.attr('id') ) +'" class="postbox cmb-row cmb-repeatable-grouping" data-iterator="'+ cmb.idNumber +'">'+ $row.html() +'' ); + $oldRow.after( $newRow ); + + cmb.afterRowInsert( $newRow ); + + cmb.triggerElement( $table, { type: 'cmb2_add_row', group: true }, $newRow ); + + }; + + cmb.addAjaxRow = function( evt ) { + evt.preventDefault(); + + var $this = $( this ); + var $table = $id( $this.data('selector') ); + var $emptyrow = $table.find('.empty-row'); + var prevNum = parseInt( $emptyrow.find('[data-iterator]').data('iterator'), 10 ); + cmb.idNumber = parseInt( prevNum, 10 ) + 1; + var $row = $emptyrow.clone(); + + cmb.newRowHousekeeping( $row ).cleanRow( $row, prevNum ); + + $emptyrow.removeClass('empty-row hidden').addClass('cmb-repeat-row'); + $emptyrow.after( $row ); + + cmb.afterRowInsert( $row ); + + cmb.triggerElement( $table, { type: 'cmb2_add_row', group: false }, $row ); + + }; + + cmb.removeGroupRow = function( evt ) { + evt.preventDefault(); + + var $this = $( this ); + var confirmation = $this.data('confirm'); + + // Process further only if deletion confirmation enabled and user agreed. + if ( confirmation && ! window.confirm( confirmation ) ) { + return; + } + + var $table = $id( $this.data('selector') ); + var $parent = $this.parents('.cmb-repeatable-grouping'); + var number = $table.find('.cmb-repeatable-grouping').length; + + if ( number < 2 ) { + return cmb.resetRow( $parent.parents('.cmb-repeatable-group').find( '.cmb-add-group-row' ), $this ); + } + + cmb.triggerElement( $table, 'cmb2_remove_group_row_start', $this ); + + // When a group is removed, loop through all next groups and update fields names. + $parent.nextAll( '.cmb-repeatable-grouping' ).find( cmb.repeatEls ).each( cmb.updateNameAttr ); + + $parent.remove(); + + cmb.triggerElement( $table, { type: 'cmb2_remove_row', group: true } ); + }; + + cmb.removeAjaxRow = function( evt ) { + evt.preventDefault(); + + var $this = $( this ); + + // Check if disabled + if ( $this.hasClass( 'button-disabled' ) ) { + return; + } + + var $parent = $this.parents('.cmb-row'); + var $table = $this.parents('.cmb-repeat-table'); + var number = $table.find('.cmb-row').length; + + if ( number <= 2 ) { + return cmb.resetRow( $parent.find( '.cmb-add-row-button' ), $this ); + } + + if ( $parent.hasClass('empty-row') ) { + $parent.prev().addClass( 'empty-row' ).removeClass('cmb-repeat-row'); + } + + $this.parents('.cmb-repeat-table .cmb-row').remove(); + + + cmb.triggerElement( $table, { type: 'cmb2_remove_row', group: false } ); + }; + + cmb.resetRow = function( $addNewBtn, $removeBtn ) { + // Click the "add new" button followed by the "remove this" button + // in order to reset the repeat row to empty values. + $addNewBtn.trigger( 'click' ); + $removeBtn.trigger( 'click' ); + }; + + cmb.shiftRows = function( evt ) { + + evt.preventDefault(); + + var $this = $( this ); + var $from = $this.parents( '.cmb-repeatable-grouping' ); + var $goto = $this.hasClass( 'move-up' ) ? $from.prev( '.cmb-repeatable-grouping' ) : $from.next( '.cmb-repeatable-grouping' ); + + // Before shift occurs. + cmb.triggerElement( $this, 'cmb2_shift_rows_enter', $this, $from, $goto ); + + if ( ! $goto.length ) { + return; + } + + // About to shift + cmb.triggerElement( $this, 'cmb2_shift_rows_start', $this, $from, $goto ); + + var inputVals = []; + // Loop this item's fields + $from.find( cmb.repeatEls ).each( function() { + var $element = $( this ); + var elType = $element.attr( 'type' ); + var val; + + if ( $element.hasClass('cmb2-media-status') ) { + // special case for image previews + val = $element.html(); + } else if ( 'checkbox' === elType || 'radio' === elType ) { + val = $element.is(':checked'); + } else if ( 'select' === $element.prop('tagName') ) { + val = $element.is(':selected'); + } else { + val = $element.val(); + } + + // Get all the current values per element + inputVals.push( { val: val, $: $element } ); + }); + // And swap them all + $goto.find( cmb.repeatEls ).each( function( index ) { + var $element = $( this ); + var elType = $element.attr( 'type' ); + var val; + + if ( $element.hasClass('cmb2-media-status') ) { + var toRowId = $element.closest('.cmb-repeatable-grouping').attr('data-iterator'); + var fromRowId = inputVals[ index ].$.closest('.cmb-repeatable-grouping').attr('data-iterator'); + + // special case for image previews + val = $element.html(); + $element.html( inputVals[ index ].val ); + inputVals[ index ].$.html( val ); + + inputVals[ index ].$.find( 'input' ).each(function() { + var name = $( this ).attr( 'name' ); + name = name.replace( '['+toRowId+']', '['+fromRowId+']' ); + $( this ).attr( 'name', name ); + }); + $element.find('input').each(function() { + var name = $( this ).attr('name'); + name = name.replace('['+fromRowId+']', '['+toRowId+']'); + $( this ).attr('name', name); + }); + + } + // handle checkbox swapping + else if ( 'checkbox' === elType ) { + inputVals[ index ].$.prop( 'checked', $element.is(':checked') ); + $element.prop( 'checked', inputVals[ index ].val ); + } + // handle radio swapping + else if ( 'radio' === elType ) { + if ( $element.is( ':checked' ) ) { + inputVals[ index ].$.attr( 'data-checked', 'true' ); + } + if ( inputVals[ index ].$.is( ':checked' ) ) { + $element.attr( 'data-checked', 'true' ); + } + } + // handle select swapping + else if ( 'select' === $element.prop('tagName') ) { + inputVals[ index ].$.prop( 'selected', $element.is(':selected') ); + $element.prop( 'selected', inputVals[ index ].val ); + } + // handle normal input swapping + else { + inputVals[ index ].$.val( $element.val() ); + $element.val( inputVals[ index ].val ); + } + }); + + $from.find( 'input[data-checked=true]' ).prop( 'checked', true ).removeAttr( 'data-checked' ); + $goto.find( 'input[data-checked=true]' ).prop( 'checked', true ).removeAttr( 'data-checked' ); + + // trigger color picker change event + $from.find( 'input[type="text"].cmb2-colorpicker' ).trigger( 'change' ); + $goto.find( 'input[type="text"].cmb2-colorpicker' ).trigger( 'change' ); + + // shift done + cmb.triggerElement( $this, 'cmb2_shift_rows_complete', $this, $from, $goto ); + }; + + cmb.initPickers = function( $timePickers, $datePickers, $colorPickers ) { + cmb.trigger( 'cmb_init_pickers', { + time: $timePickers, + date: $datePickers, + color: $colorPickers + } ); + + // Initialize jQuery UI timepickers + cmb.initDateTimePickers( $timePickers, 'timepicker', 'time_picker' ); + // Initialize jQuery UI datepickers + cmb.initDateTimePickers( $datePickers, 'datepicker', 'date_picker' ); + // Initialize color picker + cmb.initColorPickers( $colorPickers ); + }; + + cmb.initDateTimePickers = function( $selector, method, defaultKey ) { + if ( $selector.length ) { + $selector[ method ]( 'destroy' ).each( function() { + var $this = $( this ); + var fieldOpts = $this.data( method ) || {}; + var options = $.extend( {}, cmb.defaults[ defaultKey ], fieldOpts ); + $this[ method ]( cmb.datePickerSetupOpts( fieldOpts, options, method ) ); + } ); + } + }; + + cmb.datePickerSetupOpts = function( fieldOpts, options, method ) { + var existing = $.extend( {}, options ); + + options.beforeShow = function( input, inst ) { + if ( 'timepicker' === method ) { + cmb.addTimePickerClasses( inst.dpDiv ); + } + + // Wrap datepicker w/ class to narrow the scope of jQuery UI CSS and prevent conflicts + $id( 'ui-datepicker-div' ).addClass( 'cmb2-element' ); + + // Let's be sure to call beforeShow if it was added + if ( 'function' === typeof existing.beforeShow ) { + existing.beforeShow( input, inst ); + } + }; + + if ( 'timepicker' === method ) { + options.onChangeMonthYear = function( year, month, inst, picker ) { + cmb.addTimePickerClasses( inst.dpDiv ); + + // Let's be sure to call onChangeMonthYear if it was added + if ( 'function' === typeof existing.onChangeMonthYear ) { + existing.onChangeMonthYear( year, month, inst, picker ); + } + }; + } + + options.onClose = function( dateText, inst ) { + // Remove the class when we're done with it (and hide to remove FOUC). + var $picker = $id( 'ui-datepicker-div' ).removeClass( 'cmb2-element' ).hide(); + if ( 'timepicker' === method && ! $( inst.input ).val() ) { + // Set the timepicker field value if it's empty. + inst.input.val( $picker.find( '.ui_tpicker_time' ).text() ); + } + + // Let's be sure to call onClose if it was added + if ( 'function' === typeof existing.onClose ) { + existing.onClose( dateText, inst ); + } + }; + + return options; + }; + + // Adds classes to timepicker buttons. + cmb.addTimePickerClasses = function( $picker ) { + var func = cmb.addTimePickerClasses; + func.count = func.count || 0; + + // Wait a bit to let the timepicker render, since these are pre-render events. + setTimeout( function() { + if ( $picker.find( '.ui-priority-secondary' ).length ) { + $picker.find( '.ui-priority-secondary' ).addClass( 'button-secondary' ); + $picker.find( '.ui-priority-primary' ).addClass( 'button-primary' ); + func.count = 0; + } else if ( func.count < 5 ) { + func.count++; + func( $picker ); + } + }, 10 ); + }; + + cmb.initColorPickers = function( $selector ) { + if ( ! $selector.length ) { + return; + } + if ( 'object' === typeof jQuery.wp && 'function' === typeof jQuery.wp.wpColorPicker ) { + + $selector.each( function() { + var $this = $( this ); + var fieldOpts = $this.data( 'colorpicker' ) || {}; + $this.wpColorPicker( $.extend( {}, cmb.defaults.color_picker, fieldOpts ) ); + } ); + + } else { + $selector.each( function( i ) { + $( this ).after( '
            ' ); + $id( 'picker-' + i ).hide().farbtastic( $( this ) ); + } ) + .focus( function() { + $( this ).next().show(); + } ) + .blur( function() { + $( this ).next().hide(); + } ); + } + }; + + cmb.initCodeEditors = function( $selector ) { + cmb.trigger( 'cmb_init_code_editors', $selector ); + + if ( ! cmb.defaults.code_editor || ! wp || ! wp.codeEditor || ! $selector.length ) { + return; + } + + $selector.each( function() { + wp.codeEditor.initialize( + this.id, + cmb.codeEditorArgs( $( this ).data( 'codeeditor' ) ) + ); + } ); + }; + + cmb.codeEditorArgs = function( overrides ) { + var props = [ 'codemirror', 'csslint', 'jshint', 'htmlhint' ]; + var args = $.extend( {}, cmb.defaults.code_editor ); + overrides = overrides || {}; + + for ( var i = props.length - 1; i >= 0; i-- ) { + if ( overrides.hasOwnProperty( props[i] ) ) { + args[ props[i] ] = $.extend( {}, args[ props[i] ] || {}, overrides[ props[i] ] ); + } + } + + return args; + }; + + cmb.makeListSortable = function() { + var $filelist = cmb.metabox().find( '.cmb2-media-status.cmb-attach-list' ); + if ( $filelist.length ) { + $filelist.sortable({ cursor: 'move' }).disableSelection(); + } + }; + + cmb.makeRepeatableSortable = function() { + var $repeatables = cmb.metabox().find( '.cmb-repeat-table .cmb-field-list' ); + + if ( $repeatables.length ) { + $repeatables.sortable({ + items : '.cmb-repeat-row', + cursor: 'move' + }); + } + }; + + cmb.maybeOembed = function( evt ) { + var $this = $( this ); + + var m = { + focusout : function() { + setTimeout( function() { + // if it's been 2 seconds, hide our spinner + cmb.spinner( '.cmb2-metabox', true ); + }, 2000); + }, + keyup : function() { + var betw = function( min, max ) { + return ( evt.which <= max && evt.which >= min ); + }; + // Only Ajax on normal keystrokes + if ( betw( 48, 90 ) || betw( 96, 111 ) || betw( 8, 9 ) || evt.which === 187 || evt.which === 190 ) { + // fire our ajax function + cmb.doAjax( $this, evt ); + } + }, + paste : function() { + // paste event is fired before the value is filled, so wait a bit + setTimeout( function() { cmb.doAjax( $this ); }, 100); + } + }; + + m[ evt.type ](); + }; + + /** + * Resize oEmbed videos to fit in their respective metaboxes + * + * @since 0.9.4 + * + * @return {return} + */ + cmb.resizeoEmbeds = function() { + cmb.metabox().each( function() { + var $this = $( this ); + var $tableWrap = $this.parents('.inside'); + var isSide = $this.parents('.inner-sidebar').length || $this.parents( '#side-sortables' ).length; + var isSmall = isSide; + var isSmallest = false; + if ( ! $tableWrap.length ) { + return true; // continue + } + + // Calculate new width + var tableW = $tableWrap.width(); + + if ( cmb.styleBreakPoint > tableW ) { + isSmall = true; + isSmallest = ( cmb.styleBreakPoint - 62 ) > tableW; + } + + tableW = isSmall ? tableW : Math.round(($tableWrap.width() * 0.82)*0.97); + var newWidth = tableW - 30; + if ( isSmall && ! isSide && ! isSmallest ) { + newWidth = newWidth - 75; + } + if ( newWidth > 639 ) { + return true; // continue + } + + var $embeds = $this.find('.cmb-type-oembed .embed-status'); + var $children = $embeds.children().not('.cmb2-remove-wrapper'); + if ( ! $children.length ) { + return true; // continue + } + + $children.each( function() { + var $this = $( this ); + var iwidth = $this.width(); + var iheight = $this.height(); + var _newWidth = newWidth; + if ( $this.parents( '.cmb-repeat-row' ).length && ! isSmall ) { + // Make room for our repeatable "remove" button column + _newWidth = newWidth - 91; + _newWidth = 785 > tableW ? _newWidth - 15 : _newWidth; + } + // Calc new height + var newHeight = Math.round((_newWidth * iheight)/iwidth); + $this.width(_newWidth).height(newHeight); + }); + }); + }; + + // function for running our ajax + cmb.doAjax = function( $obj ) { + // get typed value + var oembed_url = $obj.val(); + // only proceed if the field contains more than 6 characters + if ( oembed_url.length < 6 ) { + return; + } + + // get field id + var field_id = $obj.attr('id'); + var $context = $obj.closest( '.cmb-td' ); + var $embed_container = $context.find( '.embed-status' ); + var $embed_wrap = $context.find( '.embed_wrap' ); + var $child_el = $embed_container.find( ':first-child' ); + var oembed_width = $embed_container.length && $child_el.length ? $child_el.width() : $obj.width(); + + cmb.log( 'oembed_url', oembed_url, field_id ); + + // show our spinner + cmb.spinner( $context ); + // clear out previous results + $embed_wrap.html(''); + // and run our ajax function + setTimeout( function() { + // if they haven't typed in 500 ms + if ( $( '.cmb2-oembed:focus' ).val() !== oembed_url ) { + return; + } + $.ajax({ + type : 'post', + dataType : 'json', + url : l10n.ajaxurl, + data : { + 'action' : 'cmb2_oembed_handler', + 'oembed_url' : oembed_url, + 'oembed_width' : oembed_width > 300 ? oembed_width : 300, + 'field_id' : field_id, + 'object_id' : $obj.data( 'objectid' ), + 'object_type' : $obj.data( 'objecttype' ), + 'cmb2_ajax_nonce' : l10n.ajax_nonce + }, + success: function(response) { + cmb.log( response ); + // hide our spinner + cmb.spinner( $context, true ); + // and populate our results from ajax response + $embed_wrap.html( response.data ); + } + }); + + }, 500); + + }; + + /** + * Gets jQuery object containing all CMB metaboxes. Caches the result. + * + * @since 1.0.2 + * + * @return {Object} jQuery object containing all CMB metaboxes. + */ + cmb.metabox = function() { + if ( cmb.$metabox ) { + return cmb.$metabox; + } + cmb.$metabox = $('.cmb2-wrap > .cmb2-metabox'); + return cmb.$metabox; + }; + + /** + * Starts/stops contextual spinner. + * + * @since 1.0.1 + * + * @param {object} $context The jQuery parent/context object. + * @param {bool} hide Whether to hide the spinner (will show by default). + * + * @return {void} + */ + cmb.spinner = function( $context, hide ) { + var m = hide ? 'removeClass' : 'addClass'; + $('.cmb-spinner', $context )[ m ]( 'is-active' ); + }; + + /** + * Triggers a jQuery event on the document object. + * + * @since 2.2.3 + * + * @param {string} evtName The name of the event to trigger. + * + * @return {void} + */ + cmb.trigger = function( evtName ) { + var args = Array.prototype.slice.call( arguments, 1 ); + args.push( cmb ); + $document.trigger( evtName, args ); + }; + + /** + * Triggers a jQuery event on the given jQuery object. + * + * @since 2.2.3 + * + * @param {object} $el The jQuery element object. + * @param {string} evtName The name of the event to trigger. + * + * @return {void} + */ + cmb.triggerElement = function( $el, evtName ) { + var args = Array.prototype.slice.call( arguments, 2 ); + args.push( cmb ); + $el.trigger( evtName, args ); + }; + + /** + * Get an argument for a given field. + * + * @since 2.5.0 + * + * @param {string|object} hash The field hash, id, or a jQuery object for a field. + * @param {string} arg The argument to get on the field. + * + * @return {mixed} The argument value. + */ + cmb.getFieldArg = function( hash, arg ) { + return cmb.getField( hash )[ arg ]; + }; + + /** + * Get a field object instances. Can be filtered by passing in a filter callback function. + * e.g. `const fileFields = CMB2.getFields(f => 'file' === f.type);` + * + * @since 2.5.0 + * + * @param {mixed} filterCb An optional filter callback function. + * + * @return array An array of field object instances. + */ + cmb.getFields = function( filterCb ) { + if ( 'function' === typeof filterCb ) { + var fields = []; + $.each( l10n.fields, function( hash, field ) { + if ( filterCb( field, hash ) ) { + fields.push( field ); + } + }); + return fields; + } + + return l10n.fields; + }; + + /** + * Get a field object instance by hash or id. + * + * @since 2.5.0 + * + * @param {string|object} hash The field hash, id, or a jQuery object for a field. + * + * @return {object} The field object or an empty object. + */ + cmb.getField = function( hash ) { + var field = {}; + hash = hash instanceof jQuery ? hash.data( 'hash' ) : hash; + if ( hash ) { + try { + if ( l10n.fields[ hash ] ) { + throw new Error( hash ); + } + + cmb.getFields( function( field ) { + if ( 'function' === typeof hash ) { + if ( hash( field ) ) { + throw new Error( field.hash ); + } + } else if ( field.id && field.id === hash ) { + throw new Error( field.hash ); + } + }); + } catch( e ) { + field = l10n.fields[ e.message ]; + } + } + + return field; + }; + + /** + * Safely log things if query var is set. Accepts same parameters as console.log. + * + * @since 1.0.0 + * + * @return {void} + */ + cmb.log = function() { + if ( l10n.script_debug && console && 'function' === typeof console.log ) { + console.log.apply(console, arguments); + } + }; + + /** + * Replace the last occurrence of a string. + * + * @since 2.2.6 + * + * @param {string} string String to search/replace. + * @param {string} search String to search. + * @param {string} replace String to replace search with. + * + * @return {string} Possibly modified string. + */ + cmb.replaceLast = function( string, search, replace ) { + // find the index of last time word was used + var n = string.lastIndexOf( search ); + + // slice the string in 2, one from the start to the lastIndexOf + // and then replace the word in the rest + return string.slice( 0, n ) + string.slice( n ).replace( search, replace ); + }; + + // Kick it off! + $( cmb.init ); + +})(window, document, jQuery, window.CMB2); diff --git a/inc/vendors/cmb2-plugins/cmb2/js/cmb2.min.js b/inc/vendors/cmb2-plugins/cmb2/js/cmb2.min.js new file mode 100755 index 00000000..4edf2e59 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/js/cmb2.min.js @@ -0,0 +1 @@ +window.CMB2=window.CMB2||{},function(window,document,$,cmb,undefined){"use strict";var $document,l10n=window.cmb2_l10,setTimeout=window.setTimeout,$id=function(selector){return $(document.getElementById(selector))},defaults={idNumber:!1,repeatEls:'input:not([type="button"],[id^=filelist]),select,textarea,.cmb2-media-status',noEmpty:'input:not([type="button"]):not([type="radio"]):not([type="checkbox"]),textarea',repeatUpdate:'input:not([type="button"]),select,textarea,label',styleBreakPoint:450,mediaHandlers:{},defaults:{time_picker:l10n.defaults.time_picker,date_picker:l10n.defaults.date_picker,color_picker:l10n.defaults.color_picker||{},code_editor:l10n.defaults.code_editor},media:{frames:{}}};cmb.init=function(){$document=$(document),$.extend(cmb,defaults),cmb.trigger("cmb_pre_init");var $metabox=cmb.metabox(),$repeatGroup=$metabox.find(".cmb-repeatable-group");cmb.initPickers($metabox.find('input[type="text"].cmb2-timepicker'),$metabox.find('input[type="text"].cmb2-datepicker'),$metabox.find('input[type="text"].cmb2-colorpicker')),cmb.initCodeEditors($metabox.find(".cmb2-textarea-code:not(.disable-codemirror)")),$('

            '+l10n.strings.check_toggle+"

            ").insertBefore(".cmb2-checkbox-list:not(.no-select-all)"),cmb.makeListSortable(),cmb.makeRepeatableSortable(),$metabox.on("change",".cmb2_upload_file",function(){cmb.media.field=$(this).attr("id"),$id(cmb.media.field+"_id").val("")}).on("click",".cmb-multicheck-toggle",cmb.toggleCheckBoxes).on("click",".cmb2-upload-button",cmb.handleMedia).on("click",".cmb-attach-list li, .cmb2-media-status .img-status img, .cmb2-media-status .file-status > span",cmb.handleFileClick).on("click",".cmb2-remove-file-button",cmb.handleRemoveMedia).on("click",".cmb-add-group-row",cmb.addGroupRow).on("click",".cmb-add-row-button",cmb.addAjaxRow).on("click",".cmb-remove-group-row",cmb.removeGroupRow).on("click",".cmb-remove-row-button",cmb.removeAjaxRow).on("keyup paste focusout",".cmb2-oembed",cmb.maybeOembed).on("cmb2_remove_row",".cmb-repeatable-group",cmb.resetTitlesAndIterator).on("click",".cmbhandle, .cmbhandle + .cmbhandle-title",cmb.toggleHandle),$repeatGroup.length&&$repeatGroup.on("cmb2_add_row",cmb.emptyValue).on("cmb2_add_row",cmb.setDefaults).filter(".sortable").each(function(){$(this).find(".cmb-remove-group-row-button").before(' ')}).on("click",".cmb-shift-rows",cmb.shiftRows),setTimeout(cmb.resizeoEmbeds,500),$(window).on("resize",cmb.resizeoEmbeds),$id("addtag").length&&cmb.listenTagAdd(),$(document).on("cmb_init",cmb.mceEnsureSave),cmb.trigger("cmb_init")},cmb.mceEnsureSave=function(){wp.data&&wp.data.hasOwnProperty("subscribe")&&cmb.canTinyMCE()&&wp.data.subscribe(function(){var editor=wp.data.hasOwnProperty("select")?wp.data.select("core/editor"):null;if(editor&&editor.isSavingPost&&editor.isSavingPost()&&window.tinyMCE.editors.length)for(var i=0;i .cmb2-metabox"))})},cmb.resetBoxes=function($boxes){$.each($boxes,function(){cmb.resetBox($(this))})},cmb.resetBox=function($box){$box.find(".wp-picker-clear").trigger("click"),$box.find(".cmb2-remove-file-button").trigger("click"),$box.find(".cmb-row.cmb-repeatable-grouping:not(:first-of-type) .cmb-remove-group-row").click(),$box.find(".cmb-repeat-row:not(:first-child)").remove(),$box.find('input:not([type="button"]),select,textarea').each(function(){var $element=$(this),tagName=$element.prop("tagName");if("INPUT"===tagName){var elType=$element.attr("type");"checkbox"===elType||"radio"===elType?$element.prop("checked",!1):$element.val("")}"SELECT"===tagName&&$("option:selected",this).prop("selected",!1),"TEXTAREA"===tagName&&$element.html("")})},cmb.resetTitlesAndIterator=function(evt){evt.group&&$(".cmb-repeatable-group.repeatable").each(function(){var $table=$(this),groupTitle=$table.find(".cmb-add-group-row").data("grouptitle");$table.find(".cmb-repeatable-grouping").each(function(rowindex){var $row=$(this),$rowTitle=$row.find("h3.cmb-group-title");$row.data("iterator",rowindex),$rowTitle.length&&$rowTitle.text(groupTitle.replace("{#}",rowindex+1))})})},cmb.toggleHandle=function(evt){evt.preventDefault(),cmb.trigger("postbox-toggled",$(this).parent(".postbox").toggleClass("closed"))},cmb.toggleCheckBoxes=function(evt){evt.preventDefault();var $this=$(this),$multicheck=$this.closest(".cmb-td").find("input[type=checkbox]:not([disabled])");$this.data("checked")?($multicheck.prop("checked",!1),$this.data("checked",!1)):($multicheck.prop("checked",!0),$this.data("checked",!0))},cmb.handleMedia=function(evt){evt.preventDefault();var $el=$(this);cmb.attach_id=!$el.hasClass("cmb2-upload-list")&&$el.closest(".cmb-td").find(".cmb2-upload-file-id").val(),cmb.attach_id="0"!==cmb.attach_id&&cmb.attach_id,cmb._handleMedia($el.prev("input.cmb2-upload-file").attr("id"),$el.hasClass("cmb2-upload-list"))},cmb.handleFileClick=function(evt){if(!$(evt.target).is("a")){evt.preventDefault();var $el=$(this),$td=$el.closest(".cmb-td"),isList=$td.find(".cmb2-upload-button").hasClass("cmb2-upload-list");cmb.attach_id=isList?$el.find('input[type="hidden"]').data("id"):$td.find(".cmb2-upload-file-id").val(),cmb.attach_id&&cmb._handleMedia($td.find("input.cmb2-upload-file").attr("id"),isList,cmb.attach_id)}},cmb._handleMedia=function(id,isList){if(wp){var media,handlers;if(handlers=cmb.mediaHandlers,media=cmb.media,media.field=id,media.$field=$id(media.field),media.fieldData=media.$field.data(),media.previewSize=media.fieldData.previewsize,media.sizeName=media.fieldData.sizename,media.fieldName=media.$field.attr("name"),media.isList=isList,id in media.frames)return media.frames[id].open();media.frames[id]=wp.media({title:cmb.metabox().find('label[for="'+id+'"]').text(),library:media.fieldData.queryargs||{},button:{text:l10n.strings[isList?"upload_files":"upload_file"]},multiple:!!isList&&"add"}),media.frames[id].states.first().set("filterable","all"),cmb.trigger("cmb_media_modal_init",media),handlers.list=function(selection,returnIt){var attachmentHtml,fileGroup=[];if(handlers.list.templates||(handlers.list.templates={image:wp.template("cmb2-list-image"),file:wp.template("cmb2-list-file")}),selection.each(function(attachment){attachmentHtml=handlers.getAttachmentHtml(attachment,"list"),fileGroup.push(attachmentHtml)}),returnIt)return fileGroup;media.$field.siblings(".cmb2-media-status").append(fileGroup)},handlers.single=function(selection){handlers.single.templates||(handlers.single.templates={image:wp.template("cmb2-single-image"),file:wp.template("cmb2-single-file")});var attachment=selection.first();media.$field.val(attachment.get("url")),$id(media.field+"_id").val(attachment.get("id"));var attachmentHtml=handlers.getAttachmentHtml(attachment,"single");media.$field.siblings(".cmb2-media-status").slideDown().html(attachmentHtml)},handlers.getAttachmentHtml=function(attachment,templatesId){var isImage="image"===attachment.get("type"),data=handlers.prepareData(attachment,isImage);return handlers[templatesId].templates[isImage?"image":"file"](data)},handlers.prepareData=function(data,image){return image&&handlers.getImageData.call(data,50),data=data.toJSON(),data.mediaField=media.field,data.mediaFieldName=media.fieldName,data.stringRemoveImage=l10n.strings.remove_image,data.stringFile=l10n.strings.file,data.stringDownload=l10n.strings.download,data.stringRemoveFile=l10n.strings.remove_file,data},handlers.getImageData=function(fallbackSize){var previewW=media.previewSize[0]||fallbackSize,previewH=media.previewSize[1]||fallbackSize,url=this.get("url"),width=this.get("width"),height=this.get("height"),sizes=this.get("sizes");return sizes&&(sizes[media.sizeName]?(url=sizes[media.sizeName].url,width=sizes[media.sizeName].width,height=sizes[media.sizeName].height):sizes.large&&(url=sizes.large.url,width=sizes.large.width,height=sizes.large.height)),width>previewW&&(height=Math.floor(previewW*height/width),width=previewW),height>previewH&&(width=Math.floor(previewH*width/height),height=previewH),width||(width=previewW),height||(height="svg"===this.get("filename").split(".").pop()?"100%":previewH),this.set("sizeUrl",url),this.set("sizeWidth",width),this.set("sizeHeight",height),this},handlers.selectFile=function(){var selection=media.frames[id].state().get("selection"),type=isList?"list":"single";cmb.attach_id&&isList?$('[data-id="'+cmb.attach_id+'"]').parents("li").replaceWith(handlers.list(selection,!0)):handlers[type](selection),cmb.trigger("cmb_media_modal_select",selection,media)},handlers.openModal=function(){var attach,selection=media.frames[id].state().get("selection");cmb.attach_id?(attach=wp.media.attachment(cmb.attach_id),attach.fetch(),selection.set(attach?[attach]:[])):selection.reset(),cmb.trigger("cmb_media_modal_open",selection,media)},media.frames[id].on("select",handlers.selectFile).on("open",handlers.openModal),media.frames[id].open()}},cmb.handleRemoveMedia=function(evt){evt.preventDefault();var $this=$(this);return $this.is(".cmb-attach-list .cmb2-remove-file-button")?($this.parents(".cmb2-media-item").remove(),!1):(cmb.media.field=$this.attr("rel"),cmb.metabox().find(document.getElementById(cmb.media.field)).val(""),cmb.metabox().find(document.getElementById(cmb.media.field+"_id")).val(""),$this.parents(".cmb2-media-status").html(""),!1)},cmb.cleanRow=function($row,prevNum,group){var $elements=$row.find(cmb.repeatUpdate);if(group){var $other=$row.find("[id]").not(cmb.repeatUpdate);$row.find(".cmb-repeat-table .cmb-repeat-row:not(:first-child)").remove(),$other.length&&$other.each(function(){var $_this=$(this),oldID=$_this.attr("id"),newID=oldID.replace("_"+prevNum,"_"+cmb.idNumber),$buttons=$row.find('[data-selector="'+oldID+'"]');$_this.attr("id",newID),$buttons.length&&$buttons.attr("data-selector",newID).data("selector",newID)})}return $elements.filter(":checked").removeAttr("checked"),$elements.find(":checked").removeAttr("checked"),$elements.filter(":selected").removeAttr("selected"),$elements.find(":selected").removeAttr("selected",!1),$row.find("h3.cmb-group-title").length&&$row.find("h3.cmb-group-title").text($row.data("title").replace("{#}",cmb.idNumber+1)),$elements.each(function(){cmb.elReplacements($(this),prevNum,group)}),cmb},cmb.elReplacements=function($newInput,prevNum,group){var newID,oldID,oldFor=$newInput.attr("for"),oldVal=$newInput.val(),type=$newInput.prop("type"),defVal=cmb.getFieldArg($newInput,"default"),newVal=void 0!==defVal&&!1!==defVal?defVal:"",tagName=$newInput.prop("tagName"),checkable=("radio"===type||"checkbox"===type)&&oldVal,attrs={};if(oldFor)attrs={for:oldFor.replace("_"+prevNum,"_"+cmb.idNumber)};else{var newName,oldName=$newInput.attr("name");oldID=$newInput.attr("id"),group?(newName=oldName?oldName.replace("["+prevNum+"][","["+cmb.idNumber+"]["):"",newID=oldID?oldID.replace("_"+prevNum+"_","_"+cmb.idNumber+"_"):""):(newName=oldName?cmb.replaceLast(oldName,"["+prevNum+"]","["+cmb.idNumber+"]"):"",newID=oldID?cmb.replaceLast(oldID,"_"+prevNum,"_"+cmb.idNumber):""),attrs={id:newID,name:newName}}if("TEXTAREA"===tagName&&$newInput.html(newVal),"SELECT"===tagName&&void 0!==defVal){var $toSelect=$newInput.find('[value="'+defVal+'"]');$toSelect.length&&$toSelect.attr("selected","selected").prop("selected","selected")}return checkable&&($newInput.removeAttr("checked"),void 0!==defVal&&oldVal===defVal&&$newInput.attr("checked","checked").prop("checked","checked")),!group&&$newInput[0].hasAttribute("data-iterator")&&(attrs["data-iterator"]=cmb.idNumber),$newInput.removeClass("hasDatepicker").val(checkable||newVal).attr(attrs),$newInput},cmb.newRowHousekeeping=function($row){var $colorPicker=$row.find(".wp-picker-container"),$list=$row.find(".cmb2-media-status");return $colorPicker.length&&$colorPicker.each(function(){var $td=$(this).parent();$td.html($td.find('input[type="text"].cmb2-colorpicker').attr("style",""))}),$list.length&&$list.empty(),cmb},cmb.afterRowInsert=function($row){cmb.initPickers($row.find('input[type="text"].cmb2-timepicker'),$row.find('input[type="text"].cmb2-datepicker'),$row.find('input[type="text"].cmb2-colorpicker'))},cmb.updateNameAttr=function(){var $this=$(this),name=$this.attr("name");if(void 0!==name){var prevNum=parseInt($this.parents(".cmb-repeatable-grouping").data("iterator"),10),newNum=prevNum-1,$newName=name.replace("["+prevNum+"]","["+newNum+"]");$this.attr("name",$newName)}},cmb.emptyValue=function(evt,row){$(cmb.noEmpty,row).val("")},cmb.setDefaults=function(evt,row){$(cmb.noEmpty,row).each(function(){var $el=$(this),defVal=cmb.getFieldArg($el,"default");void 0!==defVal&&!1!==defVal&&$el.val(defVal)})},cmb.addGroupRow=function(evt){evt.preventDefault();var $this=$(this);cmb.triggerElement($this,"cmb2_add_group_row_start",$this);var $table=$id($this.data("selector")),$oldRow=$table.find(".cmb-repeatable-grouping").last(),prevNum=parseInt($oldRow.data("iterator"),10);cmb.idNumber=parseInt(prevNum,10)+1;for(var $row=$oldRow.clone(),nodeName=$row.prop("nodeName")||"div",getRowId=function(id){return id=id.split("-"),id.splice(id.length-1,1),id.push(cmb.idNumber),id.join("-")};$table.find('.cmb-repeatable-grouping[data-iterator="'+cmb.idNumber+'"]').length>0;)cmb.idNumber++;cmb.newRowHousekeeping($row.data("title",$this.data("grouptitle"))).cleanRow($row,prevNum,!0),$row.find(".cmb-add-row-button").prop("disabled",!1);var $newRow=$("<"+nodeName+' id="'+getRowId($oldRow.attr("id"))+'" class="postbox cmb-row cmb-repeatable-grouping" data-iterator="'+cmb.idNumber+'">'+$row.html()+"");$oldRow.after($newRow),cmb.afterRowInsert($newRow),cmb.triggerElement($table,{type:"cmb2_add_row",group:!0},$newRow)},cmb.addAjaxRow=function(evt){evt.preventDefault();var $this=$(this),$table=$id($this.data("selector")),$emptyrow=$table.find(".empty-row"),prevNum=parseInt($emptyrow.find("[data-iterator]").data("iterator"),10);cmb.idNumber=parseInt(prevNum,10)+1;var $row=$emptyrow.clone();cmb.newRowHousekeeping($row).cleanRow($row,prevNum),$emptyrow.removeClass("empty-row hidden").addClass("cmb-repeat-row"),$emptyrow.after($row),cmb.afterRowInsert($row),cmb.triggerElement($table,{type:"cmb2_add_row",group:!1},$row)},cmb.removeGroupRow=function(evt){evt.preventDefault();var $this=$(this),confirmation=$this.data("confirm");if(!confirmation||window.confirm(confirmation)){var $table=$id($this.data("selector")),$parent=$this.parents(".cmb-repeatable-grouping");if($table.find(".cmb-repeatable-grouping").length<2)return cmb.resetRow($parent.parents(".cmb-repeatable-group").find(".cmb-add-group-row"),$this);cmb.triggerElement($table,"cmb2_remove_group_row_start",$this),$parent.nextAll(".cmb-repeatable-grouping").find(cmb.repeatEls).each(cmb.updateNameAttr),$parent.remove(),cmb.triggerElement($table,{type:"cmb2_remove_row",group:!0})}},cmb.removeAjaxRow=function(evt){evt.preventDefault();var $this=$(this);if(!$this.hasClass("button-disabled")){var $parent=$this.parents(".cmb-row"),$table=$this.parents(".cmb-repeat-table");if($table.find(".cmb-row").length<=2)return cmb.resetRow($parent.find(".cmb-add-row-button"),$this);$parent.hasClass("empty-row")&&$parent.prev().addClass("empty-row").removeClass("cmb-repeat-row"),$this.parents(".cmb-repeat-table .cmb-row").remove(),cmb.triggerElement($table,{type:"cmb2_remove_row",group:!1})}},cmb.resetRow=function($addNewBtn,$removeBtn){$addNewBtn.trigger("click"),$removeBtn.trigger("click")},cmb.shiftRows=function(evt){evt.preventDefault();var $this=$(this),$from=$this.parents(".cmb-repeatable-grouping"),$goto=$this.hasClass("move-up")?$from.prev(".cmb-repeatable-grouping"):$from.next(".cmb-repeatable-grouping");if(cmb.triggerElement($this,"cmb2_shift_rows_enter",$this,$from,$goto),$goto.length){cmb.triggerElement($this,"cmb2_shift_rows_start",$this,$from,$goto);var inputVals=[];$from.find(cmb.repeatEls).each(function(){var val,$element=$(this),elType=$element.attr("type");val=$element.hasClass("cmb2-media-status")?$element.html():"checkbox"===elType||"radio"===elType?$element.is(":checked"):"select"===$element.prop("tagName")?$element.is(":selected"):$element.val(),inputVals.push({val:val,$:$element})}),$goto.find(cmb.repeatEls).each(function(index){var val,$element=$(this),elType=$element.attr("type");if($element.hasClass("cmb2-media-status")){var toRowId=$element.closest(".cmb-repeatable-grouping").attr("data-iterator"),fromRowId=inputVals[index].$.closest(".cmb-repeatable-grouping").attr("data-iterator");val=$element.html(),$element.html(inputVals[index].val),inputVals[index].$.html(val),inputVals[index].$.find("input").each(function(){var name=$(this).attr("name");name=name.replace("["+toRowId+"]","["+fromRowId+"]"),$(this).attr("name",name)}),$element.find("input").each(function(){var name=$(this).attr("name");name=name.replace("["+fromRowId+"]","["+toRowId+"]"),$(this).attr("name",name)})}else"checkbox"===elType?(inputVals[index].$.prop("checked",$element.is(":checked")),$element.prop("checked",inputVals[index].val)):"radio"===elType?($element.is(":checked")&&inputVals[index].$.attr("data-checked","true"),inputVals[index].$.is(":checked")&&$element.attr("data-checked","true")):"select"===$element.prop("tagName")?(inputVals[index].$.prop("selected",$element.is(":selected")),$element.prop("selected",inputVals[index].val)):(inputVals[index].$.val($element.val()),$element.val(inputVals[index].val))}),$from.find("input[data-checked=true]").prop("checked",!0).removeAttr("data-checked"),$goto.find("input[data-checked=true]").prop("checked",!0).removeAttr("data-checked"),$from.find('input[type="text"].cmb2-colorpicker').trigger("change"),$goto.find('input[type="text"].cmb2-colorpicker').trigger("change"),cmb.triggerElement($this,"cmb2_shift_rows_complete",$this,$from,$goto)}},cmb.initPickers=function($timePickers,$datePickers,$colorPickers){cmb.trigger("cmb_init_pickers",{time:$timePickers,date:$datePickers,color:$colorPickers}),cmb.initDateTimePickers($timePickers,"timepicker","time_picker"),cmb.initDateTimePickers($datePickers,"datepicker","date_picker"),cmb.initColorPickers($colorPickers)},cmb.initDateTimePickers=function($selector,method,defaultKey){$selector.length&&$selector[method]("destroy").each(function(){var $this=$(this),fieldOpts=$this.data(method)||{},options=$.extend({},cmb.defaults[defaultKey],fieldOpts);$this[method](cmb.datePickerSetupOpts(fieldOpts,options,method))})},cmb.datePickerSetupOpts=function(fieldOpts,options,method){var existing=$.extend({},options);return options.beforeShow=function(input,inst){"timepicker"===method&&cmb.addTimePickerClasses(inst.dpDiv),$id("ui-datepicker-div").addClass("cmb2-element"),"function"==typeof existing.beforeShow&&existing.beforeShow(input,inst)},"timepicker"===method&&(options.onChangeMonthYear=function(year,month,inst,picker){cmb.addTimePickerClasses(inst.dpDiv),"function"==typeof existing.onChangeMonthYear&&existing.onChangeMonthYear(year,month,inst,picker)}),options.onClose=function(dateText,inst){var $picker=$id("ui-datepicker-div").removeClass("cmb2-element").hide();"timepicker"!==method||$(inst.input).val()||inst.input.val($picker.find(".ui_tpicker_time").text()),"function"==typeof existing.onClose&&existing.onClose(dateText,inst)},options},cmb.addTimePickerClasses=function($picker){var func=cmb.addTimePickerClasses;func.count=func.count||0,setTimeout(function(){$picker.find(".ui-priority-secondary").length?($picker.find(".ui-priority-secondary").addClass("button-secondary"),$picker.find(".ui-priority-primary").addClass("button-primary"),func.count=0):func.count<5&&(func.count++,func($picker))},10)},cmb.initColorPickers=function($selector){$selector.length&&("object"==typeof jQuery.wp&&"function"==typeof jQuery.wp.wpColorPicker?$selector.each(function(){var $this=$(this),fieldOpts=$this.data("colorpicker")||{};$this.wpColorPicker($.extend({},cmb.defaults.color_picker,fieldOpts))}):$selector.each(function(i){$(this).after('
            '),$id("picker-"+i).hide().farbtastic($(this))}).focus(function(){$(this).next().show()}).blur(function(){$(this).next().hide()}))},cmb.initCodeEditors=function($selector){cmb.trigger("cmb_init_code_editors",$selector),cmb.defaults.code_editor&&wp&&wp.codeEditor&&$selector.length&&$selector.each(function(){wp.codeEditor.initialize(this.id,cmb.codeEditorArgs($(this).data("codeeditor")))})},cmb.codeEditorArgs=function(overrides){var props=["codemirror","csslint","jshint","htmlhint"],args=$.extend({},cmb.defaults.code_editor);overrides=overrides||{};for(var i=props.length-1;i>=0;i--)overrides.hasOwnProperty(props[i])&&(args[props[i]]=$.extend({},args[props[i]]||{},overrides[props[i]]));return args},cmb.makeListSortable=function(){var $filelist=cmb.metabox().find(".cmb2-media-status.cmb-attach-list");$filelist.length&&$filelist.sortable({cursor:"move"}).disableSelection()},cmb.makeRepeatableSortable=function(){var $repeatables=cmb.metabox().find(".cmb-repeat-table .cmb-field-list");$repeatables.length&&$repeatables.sortable({items:".cmb-repeat-row",cursor:"move"})},cmb.maybeOembed=function(evt){var $this=$(this);({focusout:function(){setTimeout(function(){cmb.spinner(".cmb2-metabox",!0)},2e3)},keyup:function(){var betw=function(min,max){return evt.which<=max&&evt.which>=min};(betw(48,90)||betw(96,111)||betw(8,9)||187===evt.which||190===evt.which)&&cmb.doAjax($this,evt)},paste:function(){setTimeout(function(){cmb.doAjax($this)},100)}})[evt.type]()},cmb.resizeoEmbeds=function(){cmb.metabox().each(function(){var $this=$(this),$tableWrap=$this.parents(".inside"),isSide=$this.parents(".inner-sidebar").length||$this.parents("#side-sortables").length,isSmall=isSide,isSmallest=!1;if(!$tableWrap.length)return!0;var tableW=$tableWrap.width();cmb.styleBreakPoint>tableW&&(isSmall=!0,isSmallest=cmb.styleBreakPoint-62>tableW),tableW=isSmall?tableW:Math.round(.82*$tableWrap.width()*.97);var newWidth=tableW-30;if(!isSmall||isSide||isSmallest||(newWidth-=75),newWidth>639)return!0;var $embeds=$this.find(".cmb-type-oembed .embed-status"),$children=$embeds.children().not(".cmb2-remove-wrapper");if(!$children.length)return!0;$children.each(function(){var $this=$(this),iwidth=$this.width(),iheight=$this.height(),_newWidth=newWidth;$this.parents(".cmb-repeat-row").length&&!isSmall&&(_newWidth=newWidth-91,_newWidth=785>tableW?_newWidth-15:_newWidth);var newHeight=Math.round(_newWidth*iheight/iwidth);$this.width(_newWidth).height(newHeight)})})},cmb.doAjax=function($obj){var oembed_url=$obj.val();if(!(oembed_url.length<6)){var field_id=$obj.attr("id"),$context=$obj.closest(".cmb-td"),$embed_container=$context.find(".embed-status"),$embed_wrap=$context.find(".embed_wrap"),$child_el=$embed_container.find(":first-child"),oembed_width=$embed_container.length&&$child_el.length?$child_el.width():$obj.width();cmb.log("oembed_url",oembed_url,field_id),cmb.spinner($context),$embed_wrap.html(""),setTimeout(function(){$(".cmb2-oembed:focus").val()===oembed_url&&$.ajax({type:"post",dataType:"json",url:l10n.ajaxurl,data:{action:"cmb2_oembed_handler",oembed_url:oembed_url,oembed_width:oembed_width>300?oembed_width:300,field_id:field_id,object_id:$obj.data("objectid"),object_type:$obj.data("objecttype"),cmb2_ajax_nonce:l10n.ajax_nonce},success:function(response){cmb.log(response),cmb.spinner($context,!0),$embed_wrap.html(response.data)}})},500)}},cmb.metabox=function(){return cmb.$metabox?cmb.$metabox:(cmb.$metabox=$(".cmb2-wrap > .cmb2-metabox"),cmb.$metabox)},cmb.spinner=function($context,hide){var m=hide?"removeClass":"addClass";$(".cmb-spinner",$context)[m]("is-active")},cmb.trigger=function(evtName){var args=Array.prototype.slice.call(arguments,1);args.push(cmb),$document.trigger(evtName,args)},cmb.triggerElement=function($el,evtName){var args=Array.prototype.slice.call(arguments,2);args.push(cmb),$el.trigger(evtName,args)},cmb.getFieldArg=function(hash,arg){return cmb.getField(hash)[arg]},cmb.getFields=function(filterCb){if("function"==typeof filterCb){var fields=[];return $.each(l10n.fields,function(hash,field){filterCb(field,hash)&&fields.push(field)}),fields}return l10n.fields},cmb.getField=function(hash){var field={};if(hash=hash instanceof jQuery?hash.data("hash"):hash)try{if(l10n.fields[hash])throw new Error(hash);cmb.getFields(function(field){if("function"==typeof hash){if(hash(field))throw new Error(field.hash)}else if(field.id&&field.id===hash)throw new Error(field.hash)})}catch(e){field=l10n.fields[e.message]}return field},cmb.log=function(){l10n.script_debug&&console&&"function"==typeof console.log&&console.log.apply(console,arguments)},cmb.replaceLast=function(string,search,replace){var n=string.lastIndexOf(search);return string.slice(0,n)+string.slice(n).replace(search,replace)},$(cmb.init)}(window,document,jQuery,window.CMB2),window.CMB2=window.CMB2||{},window.CMB2.wysiwyg=window.CMB2.wysiwyg||{},function(window,document,$,cmb,wysiwyg,undefined){"use strict";function delayedInit(){0===toBeDestroyed.length?toBeInitialized.forEach(function(toInit){toBeInitialized.splice(toBeInitialized.indexOf(toInit),1),wysiwyg.init.apply(wysiwyg,toInit)}):window.setTimeout(delayedInit,100)}function delayedDestroy(){toBeDestroyed.forEach(function(id){toBeDestroyed.splice(toBeDestroyed.indexOf(id),1),wysiwyg.destroy(id)})}function getGroupData(data){var groupid=data.groupid,fieldid=data.fieldid;return all[groupid]&&all[groupid][fieldid]||(all[groupid]=all[groupid]||{},all[groupid][fieldid]={template:wp.template("cmb2-wysiwyg-"+groupid+"-"+fieldid),defaults:{mce:$.extend({},tinyMCEPreInit.mceInit["cmb2_i_"+groupid+fieldid]),qt:$.extend({},tinyMCEPreInit.qtInit["cmb2_i_"+groupid+fieldid])}},delete tinyMCEPreInit.mceInit["cmb2_i_"+groupid+fieldid],delete tinyMCEPreInit.qtInit["cmb2_i_"+groupid+fieldid]),all[groupid][fieldid]}function initOptions(options){var prop,newSettings,newQTS,nameRegex=new RegExp("cmb2_n_"+options.groupid+options.fieldid,"g"),idRegex=new RegExp("cmb2_i_"+options.groupid+options.fieldid,"g");if(void 0===tinyMCEPreInit.mceInit[options.id]){newSettings=$.extend({},options.defaults.mce);for(prop in newSettings)"string"==typeof newSettings[prop]&&(newSettings[prop]=newSettings[prop].replace(idRegex,options.id).replace(nameRegex,options.name));tinyMCEPreInit.mceInit[options.id]=newSettings}if(void 0===tinyMCEPreInit.qtInit[options.id]){newQTS=$.extend({},options.defaults.qt);for(prop in newQTS)"string"==typeof newQTS[prop]&&(newQTS[prop]=newQTS[prop].replace(idRegex,options.id).replace(nameRegex,options.name));tinyMCEPreInit.qtInit[options.id]=newQTS}}var toBeDestroyed=[],toBeInitialized=[],all=wysiwyg.all={};wysiwyg.initAll=function(){var $this,data,initiated;$(".cmb2-wysiwyg-placeholder").each(function(){$this=$(this),data=$this.data(),data.groupid&&(data.id=$this.attr("id"),data.name=$this.attr("name"),data.value=$this.val(),wysiwyg.init($this,data,!1),initiated=!0)}),!0===initiated&&(void 0!==window.QTags&&window.QTags._buttonsInit(),$(document).on("cmb2_add_row",wysiwyg.addRow).on("cmb2_remove_group_row_start",wysiwyg.destroyRowEditors).on("cmb2_shift_rows_start",wysiwyg.shiftStart).on("cmb2_shift_rows_complete",wysiwyg.shiftComplete))},wysiwyg.addRow=function(evt,$row){wysiwyg.initRow($row,evt)},wysiwyg.destroyRowEditors=function(evt,$btn){wysiwyg.destroy($btn.parents(".cmb-repeatable-grouping").find(".wp-editor-area").attr("id"))},wysiwyg.shiftStart=function(evt,$btn,$from,$to){$from.add($to).find(".wp-editor-wrap textarea").each(function(){wysiwyg.destroy($(this).attr("id"))})},wysiwyg.shiftComplete=function(evt,$btn,$from,$to){$from.add($to).each(function(){wysiwyg.initRow($(this),evt)})},wysiwyg.initRow=function($row,evt){var $toReplace,data,defVal;$row.find(".cmb2-wysiwyg-inner-wrap").each(function(){$toReplace=$(this),data=$toReplace.data(),defVal=cmb.getFieldArg(data.hash,"default",""),defVal=void 0!==defVal&&!1!==defVal?defVal:"",data.iterator=$row.data("iterator"),data.fieldid=data.id,data.id=data.groupid+"_"+data.iterator+"_"+data.fieldid,data.name=data.groupid+"["+data.iterator+"]["+data.fieldid+"]",data.value="cmb2_add_row"!==evt.type&&$toReplace.find(".wp-editor-area").length?$toReplace.find(".wp-editor-area").val():defVal,0===toBeDestroyed.length?wysiwyg.init($toReplace,data):(toBeInitialized.push([$toReplace,data]),window.setTimeout(delayedInit,100))})},wysiwyg.init=function($toReplace,data,buttonsInit){if(!data.groupid)return!1;var mceActive=cmb.canTinyMCE(),qtActive="function"==typeof window.quicktags;$.extend(data,getGroupData(data)),initOptions(data),$toReplace.replaceWith(data.template(data)),mceActive&&window.tinyMCE.init(tinyMCEPreInit.mceInit[data.id]),qtActive&&window.quicktags(tinyMCEPreInit.qtInit[data.id]),mceActive&&$(document.getElementById(data.id)).parents(".wp-editor-wrap").removeClass("html-active").addClass("tmce-active"),!1!==buttonsInit&&void 0!==window.QTags&&window.QTags._buttonsInit()},wysiwyg.destroy=function(id){if(cmb.canTinyMCE()){var editor=tinyMCE.get(id);null!==editor&&void 0!==editor?(editor.destroy(),void 0===tinyMCEPreInit.mceInit[id]&&delete tinyMCEPreInit.mceInit[id],void 0===tinyMCEPreInit.qtInit[id]&&delete tinyMCEPreInit.qtInit[id]):-1===toBeDestroyed.indexOf(id)&&(toBeDestroyed.push(id),window.setTimeout(delayedDestroy,100))}},$(document).on("cmb_init",wysiwyg.initAll)}(window,document,jQuery,window.CMB2,window.CMB2.wysiwyg); \ No newline at end of file diff --git a/inc/vendors/cmb2-plugins/cmb2/js/index.php b/inc/vendors/cmb2-plugins/cmb2/js/index.php new file mode 100755 index 00000000..eea59b98 --- /dev/null +++ b/inc/vendors/cmb2-plugins/cmb2/js/index.php @@ -0,0 +1,2 @@ +0&&"object"!=typeof timezoneList[0])for(;tzl>tzi;tzi++)tzv=timezoneList[tzi],timezoneList[tzi]={value:tzv,label:$.timepicker.timezoneOffsetString(tzv,tp_inst.support.iso8601)};return tp_inst._defaults.timezoneList=timezoneList,tp_inst.timezone=null!==tp_inst._defaults.timezone?$.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone):-1*(new Date).getTimezoneOffset(),tp_inst.hour=tp_inst._defaults.hourtp_inst._defaults.hourMax?tp_inst._defaults.hourMax:tp_inst._defaults.hour,tp_inst.minute=tp_inst._defaults.minutetp_inst._defaults.minuteMax?tp_inst._defaults.minuteMax:tp_inst._defaults.minute,tp_inst.second=tp_inst._defaults.secondtp_inst._defaults.secondMax?tp_inst._defaults.secondMax:tp_inst._defaults.second,tp_inst.millisec=tp_inst._defaults.millisectp_inst._defaults.millisecMax?tp_inst._defaults.millisecMax:tp_inst._defaults.millisec,tp_inst.microsec=tp_inst._defaults.microsectp_inst._defaults.microsecMax?tp_inst._defaults.microsecMax:tp_inst._defaults.microsec,tp_inst.ampm="",tp_inst.$input=$input,tp_inst._defaults.altField&&(tp_inst.$altInput=$(tp_inst._defaults.altField),tp_inst._defaults.altRedirectFocus===!0&&tp_inst.$altInput.css({cursor:"pointer"}).focus(function(){$input.trigger("focus")})),(0===tp_inst._defaults.minDate||0===tp_inst._defaults.minDateTime)&&(tp_inst._defaults.minDate=new Date),(0===tp_inst._defaults.maxDate||0===tp_inst._defaults.maxDateTime)&&(tp_inst._defaults.maxDate=new Date),void 0!==tp_inst._defaults.minDate&&tp_inst._defaults.minDate instanceof Date&&(tp_inst._defaults.minDateTime=new Date(tp_inst._defaults.minDate.getTime())),void 0!==tp_inst._defaults.minDateTime&&tp_inst._defaults.minDateTime instanceof Date&&(tp_inst._defaults.minDate=new Date(tp_inst._defaults.minDateTime.getTime())),void 0!==tp_inst._defaults.maxDate&&tp_inst._defaults.maxDate instanceof Date&&(tp_inst._defaults.maxDateTime=new Date(tp_inst._defaults.maxDate.getTime())),void 0!==tp_inst._defaults.maxDateTime&&tp_inst._defaults.maxDateTime instanceof Date&&(tp_inst._defaults.maxDate=new Date(tp_inst._defaults.maxDateTime.getTime())),tp_inst.$input.bind("focus",function(){tp_inst._onFocus()}),tp_inst},_addTimePicker:function(e){var t=this.$altInput&&this._defaults.altFieldTimeOnly?this.$input.val()+" "+this.$altInput.val():this.$input.val();this.timeDefined=this._parseTime(t),this._limitMinMaxDateTime(e,!1),this._injectTimePicker()},_parseTime:function(e,t){if(this.inst||(this.inst=$.datepicker._getInst(this.$input[0])),t||!this._defaults.timeOnly){var i=$.datepicker._get(this.inst,"dateFormat");try{var s=parseDateTimeInternal(i,this._defaults.timeFormat,e,$.datepicker._getFormatConfig(this.inst),this._defaults);if(!s.timeObj)return!1;$.extend(this,s.timeObj)}catch(a){return $.timepicker.log("Error parsing the date/time string: "+a+"\ndate/time string = "+e+"\ntimeFormat = "+this._defaults.timeFormat+"\ndateFormat = "+i),!1}return!0}var n=$.datepicker.parseTime(this._defaults.timeFormat,e,this._defaults);return n?($.extend(this,n),!0):!1},_injectTimePicker:function(){var e=this.inst.dpDiv,t=this.inst.settings,i=this,s="",a="",n=null,r={},l={},o=null,c=0,u=0;if(0===e.find("div.ui-timepicker-div").length&&t.showTimepicker){var m=' style="display:none;"',d='
            '+'
            "+t.timeText+"
            "+'
            ";for(c=0,u=this.units.length;u>c;c++){if(s=this.units[c],a=s.substr(0,1).toUpperCase()+s.substr(1),n=null!==t["show"+a]?t["show"+a]:this.support[s],r[s]=parseInt(t[s+"Max"]-(t[s+"Max"]-t[s+"Min"])%t["step"+a],10),l[s]=0,d+='
            "+t[s+"Text"]+"
            "+'
            ",n&&t[s+"Grid"]>0){if(d+='
            ',"hour"===s)for(var h=t[s+"Min"];r[s]>=h;h+=parseInt(t[s+"Grid"],10)){l[s]++;var p=$.datepicker.formatTime(this.support.ampm?"hht":"HH",{hour:h},t);d+='"}else for(var _=t[s+"Min"];r[s]>=_;_+=parseInt(t[s+"Grid"],10))l[s]++,d+='";d+="
            '+p+"'+(10>_?"0":"")+_+"
            "}d+="
            "}var f=null!==t.showTimezone?t.showTimezone:this.support.timezone;d+='
            "+t.timezoneText+"
            ",d+='
            ",d+="
            ";var g=$(d);for(t.timeOnly===!0&&(g.prepend('
            '+t.timeOnlyTitle+"
            "+"
            "),e.find(".ui-datepicker-header, .ui-datepicker-calendar").hide()),c=0,u=i.units.length;u>c;c++)s=i.units[c],a=s.substr(0,1).toUpperCase()+s.substr(1),n=null!==t["show"+a]?t["show"+a]:this.support[s],i[s+"_slider"]=i.control.create(i,g.find(".ui_tpicker_"+s+"_slider"),s,i[s],t[s+"Min"],r[s],t["step"+a]),n&&t[s+"Grid"]>0&&(o=100*l[s]*t[s+"Grid"]/(r[s]-t[s+"Min"]),g.find(".ui_tpicker_"+s+" table").css({width:o+"%",marginLeft:t.isRTL?"0":o/(-2*l[s])+"%",marginRight:t.isRTL?o/(-2*l[s])+"%":"0",borderCollapse:"collapse"}).find("td").click(function(){var e=$(this),t=e.html(),a=parseInt(t.replace(/[^0-9]/g),10),n=t.replace(/[^apm]/gi),r=e.data("for");"hour"===r&&(-1!==n.indexOf("p")&&12>a?a+=12:-1!==n.indexOf("a")&&12===a&&(a=0)),i.control.value(i,i[r+"_slider"],s,a),i._onTimeChange(),i._onSelectHandler()}).css({cursor:"pointer",width:100/l[s]+"%",textAlign:"center",overflow:"hidden"}));if(this.timezone_select=g.find(".ui_tpicker_timezone").append("").find("select"),$.fn.append.apply(this.timezone_select,$.map(t.timezoneList,function(e){return $("
            ', + _wrap = '
            ', + _button = '', + // Prevent CSS issues in < WordPress 4.9 + _deprecated = ( wpColorPickerL10n.current !== undefined ); + // Declare some global variables when is deprecated or not + if ( _deprecated ) { + var _before = ''; + } else { + var _before = '', + _wrappingLabel = '', + _wrappingLabelText = ''; + } + /** + * Overwrite Color + * for enable support rbga + */ + Color.fn.toString = function() { + if ( this._alpha < 1 ) + return this.toCSS( 'rgba', this._alpha ).replace( /\s+/g, '' ); + + var hex = parseInt( this._color, 10 ).toString( 16 ); + + if ( this.error ) + return ''; + + if ( hex.length < 6 ) + hex = ( '00000' + hex ).substr( -6 ); + + return '#' + hex; + }; + + /** + * Overwrite wpColorPicker + */ + $.widget( 'wp.wpColorPicker', $.wp.wpColorPicker, { + _hasAlpha: true, + /** + * @summary Creates the color picker. + * + * Creates the color picker, sets default values, css classes and wraps it all in HTML. + * + * @since 3.5.0 + * + * @access private + * + * @returns {void} + */ + _create: function() { + // Return early if Iris support is missing. + if ( ! $.support.iris ) { + return; + } + + var self = this, + el = self.element; + + // Override default options with options bound to the element. + $.extend( self.options, el.data() ); + + // Create a color picker which only allows adjustments to the hue. + if ( self.options.type === 'hue' ) { + return self._createHueOnly(); + } + + // Bind the close event. + self.close = $.proxy( self.close, self ); + + self.initialValue = el.val(); + + // Add a CSS class to the input field. + el.addClass( 'wp-color-picker' ); + + if ( _deprecated ) { + el.hide().wrap( _wrap ); + self.wrap = el.parent(); + self.toggler = $( _before ) + .insertBefore( el ) + .css( { backgroundColor : self.initialValue } ) + .attr( 'title', wpColorPickerL10n.pick ) + .attr( 'data-current', wpColorPickerL10n.current ); + self.pickerContainer = $( _after ).insertAfter( el ); + self.button = $( _button ).addClass('hidden'); + } else { + /* + * Check if there's already a wrapping label, e.g. in the Customizer. + * If there's no label, add a default one to match the Customizer template. + */ + if ( ! el.parent( 'label' ).length ) { + // Wrap the input field in the default label. + el.wrap( _wrappingLabel ); + // Insert the default label text. + self.wrappingLabelText = $( _wrappingLabelText ) + .insertBefore( el ) + .text( wpColorPickerL10n.defaultLabel ); + } + + /* + * At this point, either it's the standalone version or the Customizer + * one, we have a wrapping label to use as hook in the DOM, let's store it. + */ + self.wrappingLabel = el.parent(); + + // Wrap the label in the main wrapper. + self.wrappingLabel.wrap( _wrap ); + // Store a reference to the main wrapper. + self.wrap = self.wrappingLabel.parent(); + // Set up the toggle button and insert it before the wrapping label. + self.toggler = $( _before ) + .insertBefore( self.wrappingLabel ) + .css( { backgroundColor: self.initialValue } ); + // Set the toggle button span element text. + self.toggler.find( '.wp-color-result-text' ).text( wpColorPickerL10n.pick ); + // Set up the Iris container and insert it after the wrapping label. + self.pickerContainer = $( _after ).insertAfter( self.wrappingLabel ); + // Store a reference to the Clear/Default button. + self.button = $( _button ); + } + + // Set up the Clear/Default button. + if ( self.options.defaultColor ) { + self.button.addClass( 'wp-picker-default' ).val( wpColorPickerL10n.defaultString ); + if ( ! _deprecated ) { + self.button.attr( 'aria-label', wpColorPickerL10n.defaultAriaLabel ); + } + } else { + self.button.addClass( 'wp-picker-clear' ).val( wpColorPickerL10n.clear ); + if ( ! _deprecated ) { + self.button.attr( 'aria-label', wpColorPickerL10n.clearAriaLabel ); + } + } + + if ( _deprecated ) { + el.wrap( '' ).after( self.button ); + } else { + // Wrap the wrapping label in its wrapper and append the Clear/Default button. + self.wrappingLabel + .wrap( '
            ',d='
            ',e='',f=void 0!==wpColorPickerL10n.current;if(f)var g='';else var g='',h="",i='';Color.fn.toString=function(){if(this._alpha<1)return this.toCSS("rgba",this._alpha).replace(/\s+/g,"");var a=parseInt(this._color,10).toString(16);return this.error?"":(a.length<6&&(a=("00000"+a).substr(-6)),"#"+a)},a.widget("wp.wpColorPicker",a.wp.wpColorPicker,{_hasAlpha:!0,_create:function(){if(a.support.iris){var j=this,k=j.element;if(a.extend(j.options,k.data()),"hue"===j.options.type)return j._createHueOnly();j.close=a.proxy(j.close,j),j.initialValue=k.val(),k.addClass("wp-color-picker"),f?(k.hide().wrap(d),j.wrap=k.parent(),j.toggler=a(g).insertBefore(k).css({backgroundColor:j.initialValue}).attr("title",wpColorPickerL10n.pick).attr("data-current",wpColorPickerL10n.current),j.pickerContainer=a(c).insertAfter(k),j.button=a(e).addClass("hidden")):(k.parent("label").length||(k.wrap(h),j.wrappingLabelText=a(i).insertBefore(k).text(wpColorPickerL10n.defaultLabel)),j.wrappingLabel=k.parent(),j.wrappingLabel.wrap(d),j.wrap=j.wrappingLabel.parent(),j.toggler=a(g).insertBefore(j.wrappingLabel).css({backgroundColor:j.initialValue}),j.toggler.find(".wp-color-result-text").text(wpColorPickerL10n.pick),j.pickerContainer=a(c).insertAfter(j.wrappingLabel),j.button=a(e)),j.options.defaultColor?(j.button.addClass("wp-picker-default").val(wpColorPickerL10n.defaultString),f||j.button.attr("aria-label",wpColorPickerL10n.defaultAriaLabel)):(j.button.addClass("wp-picker-clear").val(wpColorPickerL10n.clear),f||j.button.attr("aria-label",wpColorPickerL10n.clearAriaLabel)),f?k.wrap('').after(j.button):(j.wrappingLabel.wrap('

            + + '.$info['size'].'', ''.$info['number'].'' ); ?> + + +

            + + + + add_category( + 'opalestate-pro', + [ + 'title' => esc_html__( 'Opal Estate', 'opalestate-pro' ), + 'icon' => 'fa fa-plug', + ] + ); + } + + /** + * Includes + */ + public function includes() { + require OPALESTATE_PLUGIN_DIR . 'inc/vendors/elementor/class-opalestate-elementor-widget-base.php'; + } + + /** + * Init Widgets + * + * Include widgets files and register them + * + * @access public + */ + public function register_widgets() { + $this->includes(); + + $widget_paths = glob( OPALESTATE_PLUGIN_DIR . 'inc/vendors/elementor/widgets/*.php' ); + + if ( $widget_paths ) { + foreach ( $widget_paths as $path ) { + require_once $path; + $class_name = ucfirst( str_replace("-","_", basename( $path, '.php' ) ) ).'_Elementor_Widget'; + + if( class_exists($class_name) ){ + \Elementor\Plugin::instance()->widgets_manager->register_widget_type( new $class_name() ); + } + } + } + } +} + +Opalestate_Elementor_Extended::instance(); diff --git a/inc/vendors/elementor/class-opalestate-elementor-widget-base.php b/inc/vendors/elementor/class-opalestate-elementor-widget-base.php new file mode 100755 index 00000000..9f6eade8 --- /dev/null +++ b/inc/vendors/elementor/class-opalestate-elementor-widget-base.php @@ -0,0 +1,470 @@ +get_settings_for_display(); + + $located = $this->locate_template( $this->get_name() . '.php' ); + + if ( ! file_exists( $located ) ) { + return; + } + + if ( ! empty( $located ) && file_exists( $located ) ) { + @ include apply_filters( 'opalestate_elementor_render_widget_templates', $located, $settings, $this ); + } + } + + /** + * Render widget output in the editor. + * + * Written as a Backbone JavaScript template and used to generate the live preview. + * + * @access protected + */ + protected function _content_template() { + $located = $this->locate_template( $this->get_name() . '-preview.php' ); + + if ( ! file_exists( $located ) ) { + return; + } + + if ( ! empty( $located ) && file_exists( $located ) ) { + @ include apply_filters( 'opalestate_elementor_preview_widget_templates', $located, $this ); + } + } + + /** + * Locate template. + * + * @param string $template_name Template name. + * + * @return string + */ + protected function locate_template( $template_name ) { + // Locate in your {theme}/opalestate-elementor. + $template = locate_template( [ + trailingslashit( 'opalestate/elementor-templates/' ) . $template_name, + ] ); + + // Fallback to default template in the plugin. + if ( ! $template ) { + $template = OPALESTATE_PLUGIN_DIR . 'templates/elementor-templates/' . $template_name; + } + + + // Return what we found. + return apply_filters( 'abrs_elementor_locate_template', $template, $template_name ); + } + + + /** + * Register image carousel widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @since 1.0.0 + * @access protected + */ + public function get_settings_json( $settings ) { + + $data = [ + "slides_to_show" => $settings['slides_to_show'], + "slides_to_scroll" => $settings['slides_to_scroll'], + "navigation" => $settings['navigation'], + "pause_on_hover" => $settings['pause_on_hover'], + "autoplay" => $settings['autoplay'], + "autoplay_speed" => $settings['autoplay_speed'], + "infinite" => $settings['infinite'], + "speed" => $settings['speed'], + "direction" => $settings['direction'], + ]; + + return wp_json_encode( $data ); + } + + + public function render_content() { + $settings = $this->get_settings_for_display(); + + if ( ! isset( $settings['enable_carousel'] ) ) { + return parent::render_content(); + } + + if ( $settings['enable_carousel'] === 'yes' ) { + $this->add_render_attribute( 'wrapper-style', 'class', 'elementor-slick-slider-row row-items' ); + + $data = $this->get_settings_json( $settings ); + $this->add_render_attribute( 'wrapper', 'data-settings', $data ); + + echo '
            get_render_attribute_string( 'wrapper' ) . '>'; + } else { + $this->add_render_attribute( 'wrapper-style', 'class', 'elementor-grid row-items elementor-items-container' ); + } + + parent::render_content(); + + if ( $settings['enable_carousel'] === 'yes' ) { + echo '
            '; + } + } + + /** + * Register image carousel widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @since 1.0.0 + * @access protected + */ + public function add_slick_controls( $condition, $slick_class ) { + + $slick_class = ' .elementor-opal-slick-slider '; + + $this->start_controls_section( + 'section_carousel_options', + [ + 'label' => esc_html__( 'Carousel Options', 'opalestate-pro' ), + 'type' => Controls_Manager::SECTION, + 'condition' => $condition, + ] + ); + + + $slides_to_show = range( 1, 10 ); + $slides_to_show = array_combine( $slides_to_show, $slides_to_show ); + + $this->add_responsive_control( + 'slides_to_show', + [ + 'label' => esc_html__( 'Slides to Show', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => [ + '' => esc_html__( 'Default', 'opalestate-pro' ), + ] + $slides_to_show, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'slides_to_scroll', + [ + 'label' => esc_html__( 'Slides to Scroll', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'description' => esc_html__( 'Set how many slides are scrolled per swipe.', 'opalestate-pro' ), + 'default' => '2', + 'options' => $slides_to_show, + 'condition' => [ + 'slides_to_show!' => '1', + ], + 'frontend_available' => true, + ] + ); + + + $this->add_control( + 'navigation', + [ + 'label' => esc_html__( 'Navigation', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'both', + 'options' => [ + 'both' => esc_html__( 'Arrows and Dots', 'opalestate-pro' ), + 'arrows' => esc_html__( 'Arrows', 'opalestate-pro' ), + 'dots' => esc_html__( 'Dots', 'opalestate-pro' ), + 'none' => esc_html__( 'None', 'opalestate-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'view', + [ + 'label' => esc_html__( 'View', 'opalestate-pro' ), + 'type' => Controls_Manager::HIDDEN, + 'default' => 'traditional', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_additional_options', + [ + 'label' => esc_html__( 'Carousel Additional Options', 'opalestate-pro' ), + 'condition' => $condition, + ] + ); + + $this->add_control( + 'pause_on_hover', + [ + 'label' => esc_html__( 'Pause on Hover', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'yes', + 'options' => [ + 'yes' => esc_html__( 'Yes', 'opalestate-pro' ), + 'no' => esc_html__( 'No', 'opalestate-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'autoplay', + [ + 'label' => esc_html__( 'Autoplay', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'yes', + 'options' => [ + 'yes' => esc_html__( 'Yes', 'opalestate-pro' ), + 'no' => esc_html__( 'No', 'opalestate-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'autoplay_speed', + [ + 'label' => esc_html__( 'Autoplay Speed', 'opalestate-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 5000, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'infinite', + [ + 'label' => esc_html__( 'Infinite Loop', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'yes', + 'options' => [ + 'yes' => esc_html__( 'Yes', 'opalestate-pro' ), + 'no' => esc_html__( 'No', 'opalestate-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'effect', + [ + 'label' => esc_html__( 'Effect', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'slide', + 'options' => [ + 'slide' => esc_html__( 'Slide', 'opalestate-pro' ), + 'fade' => esc_html__( 'Fade', 'opalestate-pro' ), + ], + 'condition' => [ + 'slides_to_show' => '1', + ], + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'speed', + [ + 'label' => esc_html__( 'Animation Speed', 'opalestate-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 500, + 'frontend_available' => true, + ] + ); + + $this->add_control( + 'direction', + [ + 'label' => esc_html__( 'Direction', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'ltr', + 'options' => [ + 'ltr' => esc_html__( 'Left', 'opalestate-pro' ), + 'rtl' => esc_html__( 'Right', 'opalestate-pro' ), + ], + 'frontend_available' => true, + ] + ); + + $this->end_controls_section(); + + $a = array_merge( $condition, [ + 'navigation' => [ + 'arrows', + 'dots', + 'both', + + ], + ] ); + $this->start_controls_section( + 'section_style_navigation', + [ + 'label' => esc_html__( 'Navigation', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + 'condition' => $a, + ] + ); + + $this->add_control( + 'heading_style_arrows', + [ + 'label' => esc_html__( 'Arrows', 'opalestate-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_control( + 'arrows_position', + [ + 'label' => esc_html__( 'Position', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'inside', + 'options' => [ + 'inside' => esc_html__( 'Inside', 'opalestate-pro' ), + 'outside' => esc_html__( 'Outside', 'opalestate-pro' ), + ], + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_control( + 'arrows_size', + [ + 'label' => esc_html__( 'Size', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 20, + 'max' => 60, + ], + ], + 'selectors' => [ + '{{WRAPPER}} ' . $slick_class . '.slick-slider .slick-prev:before, {{WRAPPER}} ' . $slick_class . '.slick-slider .slick-next:before' => 'font-size: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_control( + 'arrows_color', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' . $slick_class . '.slick-slider .slick-prev:before, {{WRAPPER}} ' . $slick_class . '.slick-slider .slick-next:before' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'navigation' => [ 'arrows', 'both' ], + ], + ] + ); + + $this->add_control( + 'heading_style_dots', + [ + 'label' => esc_html__( 'Dots', 'opalestate-pro' ), + 'type' => Controls_Manager::HEADING, + 'separator' => 'before', + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_control( + 'dots_position', + [ + 'label' => esc_html__( 'Position', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'outside', + 'options' => [ + 'outside' => esc_html__( 'Outside', 'opalestate-pro' ), + 'inside' => esc_html__( 'Inside', 'opalestate-pro' ), + ], + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_control( + 'dots_size', + [ + 'label' => esc_html__( 'Size', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 5, + 'max' => 10, + ], + ], + 'selectors' => [ + '{{WRAPPER}} ' . $slick_class . ' .slick-dots li button:before' => 'font-size: {{SIZE}}{{UNIT}};', + ], + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->add_control( + 'dots_color', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} ' . $slick_class . ' .slick-dots li button:before' => 'color: {{VALUE}};', + ], + 'condition' => [ + 'navigation' => [ 'dots', 'both' ], + ], + ] + ); + + $this->end_controls_section(); + + // if( $this->image_control ){ + // $this->add_image_control( $condition, $slick_class ); + // } + + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-account-button.php b/inc/vendors/elementor/widgets/opalestate-account-button.php new file mode 100755 index 00000000..4799485e --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-account-button.php @@ -0,0 +1,568 @@ +get_name(), 'eicon-lock-user' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'account', 'button' ]; + } + + private function get_available_menus() { + $menus = wp_get_nav_menus(); + + $options = []; + + foreach ( $menus as $menu ) { + $options[ $menu->slug ] = $menu->name; + } + + return $options; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'account_content', + [ + 'label' => esc_html__( 'Not logged in', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'icon', + [ + 'label' => esc_html__( 'Choose Icon', 'opalestate-pro' ), + 'type' => Controls_Manager::ICON, + 'default' => 'fa fa-user', + ] + ); + + $this->add_control( + 'enable_label', + [ + 'label' => esc_html__( 'Enable Label', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'label_text', + [ + 'label' => esc_html__( 'Label Text', 'opalestate-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Account', 'opalestate-pro' ), + 'condition' => [ 'enable_label' => 'yes' ], + ] + ); + + $this->end_controls_section(); + + + $this->start_controls_section( + 'account_logged_in', + [ + 'label' => esc_html__( 'Logged in', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'logged_in_enable_avatar', + [ + 'label' => esc_html__( 'Enable Avatar', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'on', + ] + ); + + $this->add_control( + 'logged_in_enable_notification', + [ + 'label' => esc_html__( 'Enable Notification', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'logged_in_icon', + [ + 'label' => esc_html__( 'Choose Icon', 'opalestate-pro' ), + 'type' => Controls_Manager::ICON, + 'default' => 'fa fa-user', + ] + ); + + $this->add_control( + 'logged_in_enable_label', + [ + 'label' => esc_html__( 'Enable Label', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'logged_in_label_text', + [ + 'label' => esc_html__( 'Label Text', 'opalestate-pro' ), + 'type' => Controls_Manager::TEXT, + 'default' => esc_html__( 'Account', 'opalestate-pro' ), + 'condition' => [ 'logged_in_enable_label' => 'yes' ], + ] + ); + + $menus = $this->get_available_menus(); + + if ( ! empty( $menus ) ) { + $this->add_control( + 'enable_custom_menu', + [ + 'label' => esc_html__( 'Use Custom Dashboard Menu', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'menu', + [ + 'label' => esc_html__( 'Menu', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => $menus, + 'default' => 'my-account', + 'save_default' => true, + 'separator' => 'after', + 'description' => sprintf( esc_html__( 'Go to the Menus screen to manage your menus.', 'opalestate-pro' ), admin_url( 'nav-menus.php' ) ), + 'condition' => [ 'enable_custom_menu' => 'yes' ], + ] + ); + } + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_general_style_content', + [ + 'label' => esc_html__( 'General', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'toggle_align', + [ + 'label' => esc_html__( 'Alignment', 'opalestate-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'left' => [ + 'title' => esc_html__( 'Left', 'opalestate-pro' ), + 'icon' => 'eicon-h-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'opalestate-pro' ), + 'icon' => 'eicon-h-align-center', + ], + 'right' => [ + 'title' => esc_html__( 'Right', 'opalestate-pro' ), + 'icon' => 'eicon-h-align-right', + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-widget-container' => 'text-align: {{VALUE}}', + ], + + ] + ); + + $this->end_controls_section(); + + + $this->start_controls_section( + 'section_label_style_content', + [ + 'label' => esc_html__( 'Label', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .site-header-account .account-label' => 'color: {{VALUE}};', + ], + 'scheme' => [ + 'type' => Scheme_Color::get_type(), + 'value' => Scheme_Color::COLOR_1, + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'selector' => '{{WRAPPER}} .site-header-account .account-label', + 'scheme' => Scheme_Typography::TYPOGRAPHY_1, + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_icon_style_content', + [ + 'label' => esc_html__( 'Icon', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + $this->start_controls_tabs( 'tabs_icon_style' ); + + $this->start_controls_tab( + 'tab_icon_normal', + [ + 'label' => esc_html__( 'Normal', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'icon_color', + [ + 'label' => esc_html__( 'Icon Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .site-header-account i' => 'color: {{VALUE}};', + ], + 'scheme' => [ + 'type' => Scheme_Color::get_type(), + 'value' => Scheme_Color::COLOR_1, + ], + ] + ); + + $this->add_control( + 'background_color', + [ + 'label' => esc_html__( 'Background Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .site-header-account i' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_responsive_control( + 'icon_fontsize', + [ + 'label' => esc_html__( 'Icon Font Size', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .site-header-account i' => 'font-size: {{SIZE}}{{UNIT}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'icon_border', + 'placeholder' => '1px', + 'default' => '1px', + 'selector' => '{{WRAPPER}} .site-header-account i', + 'separator' => 'before', + + ] + ); + + $this->add_control( + 'icon_border_radius', + [ + 'label' => esc_html__( 'Border Radius', 'opalestate-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'selectors' => [ + '{{WRAPPER}} .site-header-account i' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->add_control( + 'icon_padding', + [ + 'label' => esc_html__( 'Padding', 'opalestate-pro' ), + 'type' => Controls_Manager::DIMENSIONS, + 'size_units' => [ 'px', '%' ], + 'selectors' => [ + '{{WRAPPER}} .site-header-account i' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_icon_hover', + [ + 'label' => esc_html__( 'Hover', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'icon_color_hover', + [ + 'label' => esc_html__( 'Icon Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .site-header-account i:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'background_color_hover', + [ + 'label' => esc_html__( 'Background Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .site-header-account i:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Border::get_type(), + [ + 'name' => 'icon_border_hover', + 'placeholder' => '1px', + 'default' => '1px', + 'selector' => '{{WRAPPER}} .site-header-account i:hover', + 'separator' => 'before', + + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + protected function render() { + $settings = $this->get_settings(); + + $this->show_poup_hover_form( $settings ); + } + + protected function show_poup_hover_form( $settings ) { + $settings = wp_parse_args( $settings, [ + 'enable_label' => false, + 'icon' => '', + 'style' => '', + ] ); + + $account_link = opalestate_my_account_page(); + + $id = rand( 2, 9 ) . rand( 0, 9 ); + + ?> + + + + + + + + + + + + + + + + + get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'agencys_search_form', + [ + 'label' => esc_html__( 'Agencies Search/Collection', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'search_form', + [ + 'label' => esc_html__('Search Form', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => '', + 'options' => array( + '' => esc_html__( 'Advanded', 'opalestate-pro' ), + 'address' => esc_html__( 'Search By Address', 'opalestate-pro' ), + ) + ] + ); + + $this->add_control( + 'enable_sortable_bar', + [ + 'label' => esc_html__('Enable Sortable Bar', 'opalestate-pro'), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'item_layout', + [ + 'label' => esc_html__('Item Layout', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 'grid', + 'options' => array( + 'grid' => esc_html__( 'Grid', 'opalestate-pro' ), + 'list' => esc_html__( 'List', 'opalestate-pro' ), + ) + ] + ); + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__('Columns', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'item_layout' => 'grid' + ] + + ] + ); + + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}' + + ], + 'condition' => [ + 'item_layout' => 'grid' + ] + ] + ); + + $this->add_control( + 'enable_carousel', + [ + 'label' => esc_html__('Enable', 'opalestate-pro'), + 'type' => Controls_Manager::SWITCHER, + ] + ); + $this->end_controls_section(); + + $this->add_slick_controls( array('enable_carousel' => 'yes') , ' .agency-slick-carousel ' ); + + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__('Query', 'opalestate-pro'), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__('Posts Per Page', 'opalestate-pro'), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + ] + ); + + + + $this->add_control( + 'advanced', + [ + 'label' => esc_html__('Advanced', 'opalestate-pro'), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__('Order By', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'post_date' => esc_html__('Date', 'opalestate-pro'), + 'post_title' => esc_html__('Title', 'opalestate-pro'), + 'menu_order' => esc_html__('Menu Order', 'opalestate-pro'), + 'rand' => esc_html__('Random', 'opalestate-pro'), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__('Order', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__('ASC', 'opalestate-pro'), + 'desc' => esc_html__('DESC', 'opalestate-pro'), + ], + ] + ); + + $this->add_control( + 'categories', + [ + 'label' => esc_html__('Categories', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_categories(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'cat_operator', + [ + 'label' => esc_html__('Category Operator', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => 'IN', + 'options' => [ + 'AND' => esc_html__('AND', 'opalestate-pro'), + 'IN' => esc_html__('IN', 'opalestate-pro'), + 'NOT IN' => esc_html__('NOT IN', 'opalestate-pro'), + ], + 'condition' => [ + 'categories!' => '' + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_pagination', + [ + 'label' => esc_html__('Pagination', 'opalestate-pro'), + 'condition' => [ + 'enable_carousel!' => 'yes' + ], + ] + ); + + $this->add_control( + 'pagination_type', + [ + 'label' => esc_html__('Pagination', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__('None', 'opalestate-pro'), + 'numbers' => esc_html__('Numbers', 'opalestate-pro'), + 'prev_next' => esc_html__('Previous/Next', 'opalestate-pro'), + 'numbers_and_prev_next' => esc_html__('Numbers', 'opalestate-pro') . ' + ' . esc_html__('Previous/Next', 'opalestate-pro'), + ] + ] + ); + + $this->add_control( + 'pagination_page_limit', + [ + 'label' => esc_html__('Page Limit', 'opalestate-pro'), + 'default' => '5', + 'condition' => [ + 'pagination_type!' => '' + ], + ] + ); + + $this->add_control( + 'pagination_numbers_shorten', + [ + 'label' => esc_html__('Shorten', 'opalestate-pro'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_prev_label', + [ + 'label' => esc_html__('Previous Label', 'opalestate-pro'), + 'default' => esc_html__('« Previous', 'opalestate-pro'), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_next_label', + [ + 'label' => esc_html__('Next Label', 'opalestate-pro'), + 'default' => esc_html__('Next »', 'opalestate-pro'), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_align', + [ + 'label' => esc_html__('Alignment', 'opalestate-pro'), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'flex-start' => [ + 'title' => esc_html__('Left', 'opalestate-pro'), + 'icon' => 'fa fa-align-left', + ], + 'center' => [ + 'title' => esc_html__('Center', 'opalestate-pro'), + 'icon' => 'fa fa-align-center', + ], + 'flex-end' => [ + 'title' => esc_html__('Right', 'opalestate-pro'), + 'icon' => 'fa fa-align-right', + ], + ], + 'default' => 'flex-start', + 'selectors' => [ + '{{WRAPPER}} .pagination' => 'justify-content: {{VALUE}};', + ], + 'condition' => [ + 'pagination_type!' => '', + ], + ] + ); + + + $this->end_controls_section(); + + } + + public function get_post_categories() { + $list = array(); + return $list; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-agent-collection.php b/inc/vendors/elementor/widgets/opalestate-agent-collection.php new file mode 100755 index 00000000..1229ab4f --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-agent-collection.php @@ -0,0 +1,380 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'agents_search_form', + [ + 'label' => esc_html__( 'Agents Search Collection', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'search_form', + [ + 'label' => esc_html__('Search Form', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => '', + 'options' => array( + '' => esc_html__( 'Advanded', 'opalestate-pro' ), + 'address' => esc_html__( 'Search By Address', 'opalestate-pro' ), + ) + ] + ); + + $this->add_control( + 'enable_sortable_bar', + [ + 'label' => esc_html__('Enable Sortable Bar', 'opalestate-pro'), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'item_layout', + [ + 'label' => esc_html__('Item Layout', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 'grid', + 'options' => array( + 'grid' => esc_html__( 'Grid', 'opalestate-pro' ), + 'list' => esc_html__( 'List', 'opalestate-pro' ), + ) + ] + ); + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__('Columns', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'item_layout' => 'grid' + ] + + ] + ); + + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}' + + ], + 'condition' => [ + 'item_layout' => 'grid' + ] + ] + ); + + $this->add_control( + 'enable_carousel', + [ + 'label' => esc_html__('Enable', 'opalestate-pro'), + 'type' => Controls_Manager::SWITCHER, + ] + ); + $this->end_controls_section(); + + $this->add_slick_controls( array('enable_carousel' => 'yes') , ' .agent-slick-carousel ' ); + + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__('Query', 'opalestate-pro'), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__('Posts Per Page', 'opalestate-pro'), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + ] + ); + + + + $this->add_control( + 'advanced', + [ + 'label' => esc_html__('Advanced', 'opalestate-pro'), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__('Order By', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'post_date' => esc_html__('Date', 'opalestate-pro'), + 'post_title' => esc_html__('Title', 'opalestate-pro'), + 'menu_order' => esc_html__('Menu Order', 'opalestate-pro'), + 'rand' => esc_html__('Random', 'opalestate-pro'), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__('Order', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__('ASC', 'opalestate-pro'), + 'desc' => esc_html__('DESC', 'opalestate-pro'), + ], + ] + ); + + $this->add_control( + 'categories', + [ + 'label' => esc_html__('Categories', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_categories(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'cat_operator', + [ + 'label' => esc_html__('Category Operator', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => 'IN', + 'options' => [ + 'AND' => esc_html__('AND', 'opalestate-pro'), + 'IN' => esc_html__('IN', 'opalestate-pro'), + 'NOT IN' => esc_html__('NOT IN', 'opalestate-pro'), + ], + 'condition' => [ + 'categories!' => '' + ], + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_pagination', + [ + 'label' => esc_html__('Pagination', 'opalestate-pro'), + 'condition' => [ + 'enable_carousel!' => 'yes' + ], + ] + ); + + $this->add_control( + 'pagination_type', + [ + 'label' => esc_html__('Pagination', 'opalestate-pro'), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__('None', 'opalestate-pro'), + 'numbers' => esc_html__('Numbers', 'opalestate-pro'), + 'prev_next' => esc_html__('Previous/Next', 'opalestate-pro'), + 'numbers_and_prev_next' => esc_html__('Numbers', 'opalestate-pro') . ' + ' . esc_html__('Previous/Next', 'opalestate-pro'), + ] + ] + ); + + $this->add_control( + 'pagination_page_limit', + [ + 'label' => esc_html__('Page Limit', 'opalestate-pro'), + 'default' => '5', + 'condition' => [ + 'pagination_type!' => '' + ], + ] + ); + + $this->add_control( + 'pagination_numbers_shorten', + [ + 'label' => esc_html__('Shorten', 'opalestate-pro'), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_prev_label', + [ + 'label' => esc_html__('Previous Label', 'opalestate-pro'), + 'default' => esc_html__('« Previous', 'opalestate-pro'), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_next_label', + [ + 'label' => esc_html__('Next Label', 'opalestate-pro'), + 'default' => esc_html__('Next »', 'opalestate-pro'), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_align', + [ + 'label' => esc_html__('Alignment', 'opalestate-pro'), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'flex-start' => [ + 'title' => esc_html__('Left', 'opalestate-pro'), + 'icon' => 'fa fa-align-left', + ], + 'center' => [ + 'title' => esc_html__('Center', 'opalestate-pro'), + 'icon' => 'fa fa-align-center', + ], + 'flex-end' => [ + 'title' => esc_html__('Right', 'opalestate-pro'), + 'icon' => 'fa fa-align-right', + ], + ], + 'default' => 'flex-start', + 'selectors' => [ + '{{WRAPPER}} .pagination' => 'justify-content: {{VALUE}};', + ], + 'condition' => [ + 'pagination_type!' => '', + ], + ] + ); + + + $this->end_controls_section(); + + } + + public function get_post_categories() { + $list = array(); + return $list; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-category-list.php b/inc/vendors/elementor/widgets/opalestate-category-list.php new file mode 100755 index 00000000..0f8385e0 --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-category-list.php @@ -0,0 +1,238 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'category_search_form', + [ + 'label' => esc_html__( 'Category Collection', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'search_form', + [ + 'label' => esc_html__( 'Search Form', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'Advanded', 'opalestate-pro' ), + 'address' => esc_html__( 'Search By Address', 'opalestate-pro' ), + ], + ] + ); + + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__( 'Columns', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [ 1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6 ], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'enable_carousel!' => 'yes', + ], + + ] + ); + + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}', + + ], + 'condition' => [ + 'enable_carousel!' => 'yes', + ], + + ] + ); + + $this->add_control( + 'enable_carousel', + [ + 'label' => esc_html__( 'Enable Carousel', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + $this->end_controls_section(); + + $this->add_slick_controls( [ 'enable_carousel' => 'yes' ], ' .agency-slick-carousel ' ); + + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'advanced', + [ + 'label' => esc_html__( 'Advanced', 'opalestate-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'term_id' => esc_html__( 'ID', 'opalestate-pro' ), + 'name' => esc_html__( 'Name', 'opalestate-pro' ), + 'count' => esc_html__( 'Count', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'opalestate-pro' ), + 'desc' => esc_html__( 'DESC', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'categories', + [ + 'label' => esc_html__( 'Categories', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_categories(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'limit', + [ + 'label' => esc_html__( 'Limit', 'opalestate-pro' ), + 'description' => esc_html__( 'Maximum number of terms to return.', 'opalestate-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 5, + ] + ); + + $this->end_controls_section(); + } + + protected function get_post_categories() { + $categories = Opalestate_Taxonomy_Categories::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-city-list.php b/inc/vendors/elementor/widgets/opalestate-city-list.php new file mode 100755 index 00000000..d017d304 --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-city-list.php @@ -0,0 +1,238 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'category_search_form', + [ + 'label' => esc_html__( 'City Collection', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'search_form', + [ + 'label' => esc_html__( 'Search Form', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'Advanded', 'opalestate-pro' ), + 'address' => esc_html__( 'Search By Address', 'opalestate-pro' ), + ], + ] + ); + + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__( 'Columns', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [ 1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6 ], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'enable_carousel!' => 'yes', + ], + + ] + ); + + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}', + + ], + 'condition' => [ + 'enable_carousel!' => 'yes', + ], + + ] + ); + + $this->add_control( + 'enable_carousel', + [ + 'label' => esc_html__( 'Enable Carousel', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + $this->end_controls_section(); + + $this->add_slick_controls( [ 'enable_carousel' => 'yes' ], ' .agency-slick-carousel ' ); + + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'advanced', + [ + 'label' => esc_html__( 'Advanced', 'opalestate-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'term_id' => esc_html__( 'ID', 'opalestate-pro' ), + 'name' => esc_html__( 'Name', 'opalestate-pro' ), + 'count' => esc_html__( 'Count', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'opalestate-pro' ), + 'desc' => esc_html__( 'DESC', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'categories', + [ + 'label' => esc_html__( 'Cities', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_cities(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'limit', + [ + 'label' => esc_html__( 'Limit', 'opalestate-pro' ), + 'description' => esc_html__( 'Maximum number of terms to return.', 'opalestate-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 5, + ] + ); + + $this->end_controls_section(); + } + + protected function get_post_cities() { + $categories = Opalestate_Taxonomy_City::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-form-builder.php b/inc/vendors/elementor/widgets/opalestate-form-builder.php new file mode 100755 index 00000000..f40c7ade --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-form-builder.php @@ -0,0 +1,141 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'form_builder_head', + [ + 'label' => esc_html__( 'Agency/Agent Tab Form Search', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'title', + [ + 'label' => esc_html__( 'Title', 'opalestate-pro' ), + 'type' => Controls_Manager::TEXT, + ] + ); + + $this->add_control( + 'fields', + [ + 'label' => esc_html__( 'Brand Items', 'opalestate-pro' ), + 'type' => Controls_Manager::REPEATER, + 'fields' => [ + [ + 'name' => 'field', + 'label' => esc_html__( 'Field', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + + 'options' => $this->field_types() + ], + + [ + 'name' => 'column', + 'label' => esc_html__( 'Column', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'options'=> array( + '1' => 1, + '2' => 2, + '3' => 3, + '4' => 4, + '5' => 5, + '6' => 6, + '7' => 7, + '12' => 12 + ), + 'default' => 4 + ] + ] + ] + ); + $this->end_controls_section(); + } + + public function field_types() { + $files = glob( OPALESTATE_PLUGIN_DIR .'/templates/search-box/fields/*.php'); + + $output = array(); + + foreach ( $files as $field ) { + $name = str_replace(".php", "", basename( $field ) ); + $label = ucfirst( str_replace( "-", " ", $name ) ); + $output[$name] = $label; + } + + return $output; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-map-top-search.php b/inc/vendors/elementor/widgets/opalestate-map-top-search.php new file mode 100755 index 00000000..694aa6bb --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-map-top-search.php @@ -0,0 +1,163 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'map_preview_form', + [ + 'label' => esc_html__( 'Map Preview Form', 'opalestate-pro' ), + 'description' => ' ' + ] + + ); + + $this->add_control( + 's_form_description', + [ + 'raw' => esc_html__( 'This is often used for building seach page, it combines with block => Search: Property Form, Search: Property Results.', 'opalestate-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + + $this->add_control( + 'enable_static', + [ + 'label' => esc_html__('Enable Static Map', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SWITCHER, + 'default' => '' + ] + ); + + $this->add_control( + 'static_mode_right', + [ + 'label' => esc_html__('Map On Right?', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => [ + 'enable_static!' => '' + ] + ] + ); + + + $this->add_responsive_control( + 'map_width', + [ + 'label' => esc_html__( 'Map Width %', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 20, + 'max' => 100, + ], + 'default'=>50 + ], + + 'selectors' => [ + '{{WRAPPER}} .opalestate-map-preview-wrap' => 'Width: {{SIZE}}%' + + ], + 'condition' => [ + 'enable_static!' => '' + ] + ] + ); + + $this->add_responsive_control( + 'map_height', + [ + 'label' => esc_html__( 'Map Height', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 300, + 'max' => 1200, + ], + ], + + 'selectors' => [ + '{{WRAPPER}} #opalestate-map-preview' => 'min-height: {{SIZE}}{{UNIT}}!important' + + ] + ] + ); + + + $this->end_controls_section(); + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-property-collection.php b/inc/vendors/elementor/widgets/opalestate-property-collection.php new file mode 100755 index 00000000..3c04e751 --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-property-collection.php @@ -0,0 +1,483 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'head', + [ + 'label' => esc_html__( 'Property Collection', 'opalestate-pro' ), + ] + ); + + + $this->add_control( + 'style', + [ + 'label' => esc_html__( 'Style Item Layout', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'options' => $this->get_template_post_type(), + 'default' => 'grid', + ] + ); + + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__( 'Columns', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [ 1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6 ], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'enable_carousel' => '', + ], + ] + ); + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}', + + ], + 'condition' => [ + 'enable_carousel' => '', + ], + ] + ); + + $this->add_control( + 'showmode', + [ + 'label' => esc_html__( 'Show', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + 'featured' => esc_html__( 'Featured only', 'opalestate-pro' ), + 'normal' => esc_html__( 'Without Featured', 'opalestate-pro' ), + 'all' => esc_html__( 'All', 'opalestate-pro' ), + ], + ] + ); + $this->add_control( + 'enable_carousel', + [ + 'label' => esc_html__( 'Enable Carousel', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->end_controls_section(); + + + $this->add_slick_controls( [ 'enable_carousel' => 'yes' ], ' .product-slick-carousel ' ); + + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Posts Per Page', 'opalestate-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + ] + ); + + + $this->add_control( + 'advanced', + [ + 'label' => esc_html__( 'Advanced', 'opalestate-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'post_date' => esc_html__( 'Date', 'opalestate-pro' ), + 'post_title' => esc_html__( 'Title', 'opalestate-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'opalestate-pro' ), + 'rand' => esc_html__( 'Random', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'opalestate-pro' ), + 'desc' => esc_html__( 'DESC', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'categories', + [ + 'label' => esc_html__( 'Categories', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_categories(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'cat_operator', + [ + 'label' => esc_html__( 'Category Operator', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'IN', + 'options' => [ + 'AND' => esc_html__( 'AND', 'opalestate-pro' ), + 'IN' => esc_html__( 'IN', 'opalestate-pro' ), + 'NOT IN' => esc_html__( 'NOT IN', 'opalestate-pro' ), + ], + 'condition' => [ + 'categories!' => '', + ], + ] + ); + + + $this->add_control( + 'types', + [ + 'label' => esc_html__( 'Types', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_types(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'labels', + [ + 'label' => esc_html__( 'Lables', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_labels(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'statuses', + [ + 'label' => esc_html__( 'Status', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_statuses(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'cities', + [ + 'label' => esc_html__( 'Cities', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_cities(), + 'multiple' => true, + ] + ); + + + $this->end_controls_section(); + + + $this->start_controls_section( + 'section_pagination', + [ + 'label' => esc_html__( 'Pagination', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'pagination', + [ + 'label' => esc_html__( 'Pagination', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'opalestate-pro' ), + 'show' => esc_html__( 'Show', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'pagination_page_limit', + [ + 'label' => esc_html__( 'Page Limit', 'opalestate-pro' ), + 'default' => '5', + 'condition' => [ + 'pagination_type!' => '', + ], + ] + ); + + // $this->add_control( + // 'pagination_numbers_shorten', + // [ + // 'label' => esc_html__( 'Shorten', 'opalestate-pro' ), + // 'type' => Controls_Manager::SWITCHER, + // 'default' => '', + // 'condition' => [ + // 'pagination_type' => [ + // 'numbers', + // 'numbers_and_prev_next', + // ], + // ], + // ] + // ); + // + // $this->add_control( + // 'pagination_prev_label', + // [ + // 'label' => esc_html__( 'Previous Label', 'opalestate-pro' ), + // 'default' => esc_html__( '« Previous', 'opalestate-pro' ), + // 'condition' => [ + // 'pagination_type' => [ + // 'prev_next', + // 'numbers_and_prev_next', + // ], + // ], + // ] + // ); + // + // $this->add_control( + // 'pagination_next_label', + // [ + // 'label' => esc_html__( 'Next Label', 'opalestate-pro' ), + // 'default' => esc_html__( 'Next »', 'opalestate-pro' ), + // 'condition' => [ + // 'pagination_type' => [ + // 'prev_next', + // 'numbers_and_prev_next', + // ], + // ], + // ] + // ); + + // $this->add_control( + // 'pagination_align', + // [ + // 'label' => esc_html__( 'Alignment', 'opalestate-pro' ), + // 'type' => Controls_Manager::CHOOSE, + // 'options' => [ + // 'flex-start' => [ + // 'title' => esc_html__( 'Left', 'opalestate-pro' ), + // 'icon' => 'fa fa-align-left', + // ], + // 'center' => [ + // 'title' => esc_html__( 'Center', 'opalestate-pro' ), + // 'icon' => 'fa fa-align-center', + // ], + // 'flex-end' => [ + // 'title' => esc_html__( 'Right', 'opalestate-pro' ), + // 'icon' => 'fa fa-align-right', + // ], + // ], + // 'default' => 'flex-start', + // 'selectors' => [ + // '{{WRAPPER}} .pagination' => 'justify-content: {{VALUE}};', + // ], + // 'condition' => [ + // 'pagination_type!' => '', + // ], + // ] + // ); + + $this->end_controls_section(); + } + + protected function get_post_labels() { + $categories = Opalestate_Taxonomy_Label::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + protected function get_post_types() { + $categories = Opalestate_Taxonomy_Type::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + protected function get_post_categories() { + + $categories = Opalestate_Taxonomy_Categories::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + + protected function get_post_statuses() { + + $categories = Opalestate_Taxonomy_Status::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + protected function get_post_cities() { + + $categories = Opalestate_Taxonomy_City::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + + private function get_template_post_type() { + $folderes = glob( OPALESTATE_PLUGIN_DIR . '/templates/content-property-*' ); + $output = []; + + foreach ( $folderes as $folder ) { + $folder = str_replace( "content-property-", '', str_replace( '.php', '', wp_basename( $folder ) ) ); + $value = str_replace( '_', ' ', str_replace( '-', ' ', ucfirst( $folder ) ) ); + $output[ $folder ] = $value; + } + + return $output; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-search-agency.php b/inc/vendors/elementor/widgets/opalestate-search-agency.php new file mode 100755 index 00000000..918e94b3 --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-search-agency.php @@ -0,0 +1,160 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'agency_search_form', + [ + 'label' => esc_html__( 'Agency Search Form', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'search_form', + [ + 'label' => esc_html__('Search Form', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => '', + 'options' => array( + '' => esc_html__( 'Advanded', 'opalestate-pro' ), + 'address' => esc_html__( 'Search By Address', 'opalestate-pro' ), + ) + ] + ); + + $this->add_control( + 'current_uri', + [ + 'label' => esc_html__('Target Submit Page', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 1, + 'options' => array( + 1 => esc_html__( 'Current Page', 'opalestate-pro' ), + 0 => esc_html__( 'Global Agent Search Page', 'opalestate-pro' ), + ) + ] + ); + + $this->add_control( + 'item_layout', + [ + 'label' => esc_html__('Item Layout', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 'grid', + 'options' => array( + 'grid' => esc_html__( 'Grid', 'opalestate-pro' ), + 'list' => esc_html__( 'List', 'opalestate-pro' ), + ) + ] + ); + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__('Columns', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'item_layout' => 'grid' + ] + + ] + ); + + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}' + + ], + 'condition' => [ + 'item_layout' => 'grid' + ] + ] + ); + $this->end_controls_section(); + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-search-agents.php b/inc/vendors/elementor/widgets/opalestate-search-agents.php new file mode 100755 index 00000000..d809a29b --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-search-agents.php @@ -0,0 +1,160 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'agents_search_form', + [ + 'label' => esc_html__( 'Agents Search Form', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'search_form', + [ + 'label' => esc_html__('Search Form', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => '', + 'options' => array( + '' => esc_html__( 'Advanded', 'opalestate-pro' ), + 'address' => esc_html__( 'Search By Address', 'opalestate-pro' ), + ) + ] + ); + + $this->add_control( + 'current_uri', + [ + 'label' => esc_html__('Target Submit Page', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 1, + 'options' => array( + 1 => esc_html__( 'Current Page', 'opalestate-pro' ), + 0 => esc_html__( 'Global Agent Search Page', 'opalestate-pro' ), + ) + ] + ); + + $this->add_control( + 'item_layout', + [ + 'label' => esc_html__('Item Layout', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 'grid', + 'options' => array( + 'grid' => esc_html__( 'Grid', 'opalestate-pro' ), + 'list' => esc_html__( 'List', 'opalestate-pro' ), + ) + ] + ); + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__('Columns', 'opalestate-pro'), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'item_layout' => 'grid' + ] + + ] + ); + + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}' + + ], + 'condition' => [ + 'item_layout' => 'grid' + ] + ] + ); + $this->end_controls_section(); + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-search-property-results.php b/inc/vendors/elementor/widgets/opalestate-search-property-results.php new file mode 100755 index 00000000..6f4900a2 --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-search-property-results.php @@ -0,0 +1,466 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'head', + [ + 'label' => esc_html__( 'Show Collection as Default Results', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 's_form_description', + [ + 'raw' => esc_html__( 'This is often used for building seach page, it combines with block => Search: Property Form, Search:Map Preview.', 'opalestate-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->add_control( + 'style', + [ + 'label' => esc_html__( 'Style Item Layout', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'options' => $this->get_template_post_type(), + 'default' => 'grid', + ] + ); + + $this->add_control( + 'column', + [ + 'label' => esc_html__( 'Columns', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [ 1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6 ], + + ] + ); + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}', + + ], + 'condition' => [ + 'enable_carousel' => '', + ], + ] + ); + + $this->add_control( + 'enable_carousel', + [ + 'label' => esc_html__( 'Enable Carousel', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->end_controls_section(); + + + /// $this->add_slick_controls( array('enable_carousel' => 'yes') , ' .product-slick-carousel ' ); + + $this->start_controls_section( + 'section_query', + [ + 'label' => esc_html__( 'Query', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_CONTENT, + ] + ); + + $this->add_control( + 'posts_per_page', + [ + 'label' => esc_html__( 'Posts Per Page', 'opalestate-pro' ), + 'type' => Controls_Manager::NUMBER, + 'default' => 6, + ] + ); + + + $this->add_control( + 'advanced', + [ + 'label' => esc_html__( 'Advanced', 'opalestate-pro' ), + 'type' => Controls_Manager::HEADING, + ] + ); + + $this->add_control( + 'orderby', + [ + 'label' => esc_html__( 'Order By', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'post_date', + 'options' => [ + 'post_date' => esc_html__( 'Date', 'opalestate-pro' ), + 'post_title' => esc_html__( 'Title', 'opalestate-pro' ), + 'menu_order' => esc_html__( 'Menu Order', 'opalestate-pro' ), + 'rand' => esc_html__( 'Random', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'order', + [ + 'label' => esc_html__( 'Order', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'desc', + 'options' => [ + 'asc' => esc_html__( 'ASC', 'opalestate-pro' ), + 'desc' => esc_html__( 'DESC', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'categories', + [ + 'label' => esc_html__( 'Categories', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_categories(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'cat_operator', + [ + 'label' => esc_html__( 'Category Operator', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => 'IN', + 'options' => [ + 'AND' => esc_html__( 'AND', 'opalestate-pro' ), + 'IN' => esc_html__( 'IN', 'opalestate-pro' ), + 'NOT IN' => esc_html__( 'NOT IN', 'opalestate-pro' ), + ], + 'condition' => [ + 'categories!' => '', + ], + ] + ); + + + $this->add_control( + 'types', + [ + 'label' => esc_html__( 'Types', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_types(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'labels', + [ + 'label' => esc_html__( 'Lables', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_labels(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'statuses', + [ + 'label' => esc_html__( 'Status', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_statuses(), + 'multiple' => true, + ] + ); + + $this->add_control( + 'cities', + [ + 'label' => esc_html__( 'Cities', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT2, + 'options' => $this->get_post_cities(), + 'multiple' => true, + ] + ); + + + $this->end_controls_section(); + + + $this->start_controls_section( + 'section_pagination', + [ + 'label' => esc_html__( 'Pagination', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'pagination_type', + [ + 'label' => esc_html__( 'Pagination', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'default' => '', + 'options' => [ + '' => esc_html__( 'None', 'opalestate-pro' ), + 'numbers' => esc_html__( 'Numbers', 'opalestate-pro' ), + 'prev_next' => esc_html__( 'Previous/Next', 'opalestate-pro' ), + 'numbers_and_prev_next' => esc_html__( 'Numbers', 'opalestate-pro' ) . ' + ' . esc_html__( 'Previous/Next', 'opalestate-pro' ), + ], + ] + ); + + $this->add_control( + 'pagination_page_limit', + [ + 'label' => esc_html__( 'Page Limit', 'opalestate-pro' ), + 'default' => '5', + 'condition' => [ + 'pagination_type!' => '', + ], + ] + ); + + $this->add_control( + 'pagination_numbers_shorten', + [ + 'label' => esc_html__( 'Shorten', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => '', + 'condition' => [ + 'pagination_type' => [ + 'numbers', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_prev_label', + [ + 'label' => esc_html__( 'Previous Label', 'opalestate-pro' ), + 'default' => esc_html__( '« Previous', 'opalestate-pro' ), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_next_label', + [ + 'label' => esc_html__( 'Next Label', 'opalestate-pro' ), + 'default' => esc_html__( 'Next »', 'opalestate-pro' ), + 'condition' => [ + 'pagination_type' => [ + 'prev_next', + 'numbers_and_prev_next', + ], + ], + ] + ); + + $this->add_control( + 'pagination_align', + [ + 'label' => esc_html__( 'Alignment', 'opalestate-pro' ), + 'type' => Controls_Manager::CHOOSE, + 'options' => [ + 'flex-start' => [ + 'title' => esc_html__( 'Left', 'opalestate-pro' ), + 'icon' => 'fa fa-align-left', + ], + 'center' => [ + 'title' => esc_html__( 'Center', 'opalestate-pro' ), + 'icon' => 'fa fa-align-center', + ], + 'flex-end' => [ + 'title' => esc_html__( 'Right', 'opalestate-pro' ), + 'icon' => 'fa fa-align-right', + ], + ], + 'default' => 'flex-start', + 'selectors' => [ + '{{WRAPPER}} .pagination' => 'justify-content: {{VALUE}};', + ], + 'condition' => [ + 'pagination_type!' => '', + ], + ] + ); + + + $this->end_controls_section(); + + } + + protected function get_post_labels() { + $categories = Opalestate_Taxonomy_Label::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + protected function get_post_types() { + $categories = Opalestate_Taxonomy_Type::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + protected function get_post_categories() { + + $categories = Opalestate_Taxonomy_Categories::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + + protected function get_post_statuses() { + + $categories = Opalestate_Taxonomy_Status::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + protected function get_post_cities() { + + $categories = Opalestate_Taxonomy_City::get_list(); + + $results = []; + if ( ! is_wp_error( $categories ) ) { + foreach ( $categories as $category ) { + $results[ $category->slug ] = $category->name; + } + } + + return $results; + } + + + private function get_template_post_type() { + $folderes = glob( OPALESTATE_PLUGIN_DIR . '/templates/content-property-*' ); + $output = []; + + foreach ( $folderes as $folder ) { + $folder = str_replace( "content-property-", '', str_replace( '.php', '', wp_basename( $folder ) ) ); + $value = str_replace( '_', ' ', str_replace( '-', ' ', ucfirst( $folder ) ) ); + $output[ $folder ] = $value; + } + + return $output; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-searchbox.php b/inc/vendors/elementor/widgets/opalestate-searchbox.php new file mode 100755 index 00000000..a63895bc --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-searchbox.php @@ -0,0 +1,386 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'property_search_form', + [ + 'label' => esc_html__( 'Property Search Form', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 's_form_description', + [ + 'raw' => esc_html__( 'This is often used for building seach page, it combines with block => Search: Map Preview, Search: Property Results.', 'opalestate-pro' ), + 'type' => Controls_Manager::RAW_HTML, + 'content_classes' => 'elementor-descriptor', + ] + ); + + $this->add_control( + 'style', + [ + 'label' => esc_html__( 'Layout', 'opalestate-pro' ), + 'type' => Controls_Manager::SELECT, + 'options' => opalestate_search_properties_form_styles(), + 'default' => 'search-form-h', + ] + ); + + $this->add_control( + 'hidden_labels', + [ + 'label' => esc_html__( 'Disable Labels', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $this->add_control( + 'nobutton', + [ + 'label' => esc_html__( 'Disable Search button', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + ] + ); + + $this->add_control( + 'display_country', + [ + 'label' => esc_html__( 'Display Country select', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + 'condition' => [ + 'style' => $this->has_location_fields(), + ], + ] + ); + + $this->add_control( + 'display_state', + [ + 'label' => esc_html__( 'Display State select', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'style' => $this->has_location_fields(), + ], + ] + ); + + $this->add_control( + 'display_city', + [ + 'label' => esc_html__( 'Display City select', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'condition' => [ + 'style' => $this->has_location_fields(), + ], + ] + ); + + $this->add_control( + 'display_more_options', + [ + 'label' => esc_html__( 'Display More Options', 'opalestate-pro' ), + 'type' => Controls_Manager::SWITCHER, + 'default' => 'yes', + ] + ); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_label_style_content', + [ + 'label' => esc_html__( 'Label', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->start_controls_tabs( 'tabs_label_style' ); + + $this->start_controls_tab( + 'tab_label_normal', + [ + 'label' => __( 'Normal', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'title_color', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form label.opalestate-label' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'title_typography', + 'selector' => '{{WRAPPER}} .opalestate-search-form label.opalestate-label', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_label_hover', + [ + 'label' => __( 'Hover', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'title_color_hover', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form label.opalestate-label:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + + $this->start_controls_section( + 'section_input_style_content', + [ + 'label' => esc_html__( 'Input', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->add_control( + 'input_color', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form input, {{WRAPPER}} .opalestate-search-form input::placeholder, {{WRAPPER}} .opalestate-search-form select, {{WRAPPER}} .opalestate-search-form .select2-container--default .select2-selection--single .select2-selection__rendered, {{WRAPPER}} .opalestate-search-form .opalestate-popup .popup-head > span' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'input_background_color', + [ + 'label' => esc_html__( 'Background color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form input, {{WRAPPER}} .opalestate-search-form select, {{WRAPPER}} .opalestate-search-form .select2-container.select2-container--default .select2-selection--single' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'input_border_color', + [ + 'label' => esc_html__( 'Border color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form input, {{WRAPPER}} .opalestate-search-form select, {{WRAPPER}} .opalestate-search-form .select2-container.select2-container--default .select2-selection--single' => 'border-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'input_typography', + 'selector' => '{{WRAPPER}} .opalestate-search-form input, {{WRAPPER}} .opalestate-search-form select, {{WRAPPER}} .opalestate-search-form .select2-container.select2-container--default .select2-selection--single', + ] + ); + + $this->end_controls_section(); + + + + $this->start_controls_section( + 'section_button_style_content', + [ + 'label' => esc_html__( 'Button', 'opalestate-pro' ), + 'tab' => Controls_Manager::TAB_STYLE, + ] + ); + + $this->start_controls_tabs( 'tabs_button_style' ); + + $this->start_controls_tab( + 'tab_button_normal', + [ + 'label' => __( 'Normal', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'button_color', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form .btn' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_background_color', + [ + 'label' => esc_html__( 'Background color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form .btn' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->add_group_control( + Group_Control_Typography::get_type(), + [ + 'name' => 'button_typography', + 'selector' => '{{WRAPPER}} .opalestate-search-form .btn.btn-search', + ] + ); + + $this->end_controls_tab(); + + $this->start_controls_tab( + 'tab_button_hover', + [ + 'label' => __( 'Hover', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'button_color_hover', + [ + 'label' => esc_html__( 'Color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form .btn:hover' => 'color: {{VALUE}};', + ], + ] + ); + + $this->add_control( + 'button_background_color_hover', + [ + 'label' => esc_html__( 'Background color', 'opalestate-pro' ), + 'type' => Controls_Manager::COLOR, + 'default' => '', + 'selectors' => [ + '{{WRAPPER}} .opalestate-search-form .btn:hover' => 'background-color: {{VALUE}};', + ], + ] + ); + + $this->end_controls_tab(); + + $this->end_controls_tabs(); + + $this->end_controls_section(); + } + + protected function has_location_fields() { + return [ + 'search-form-h', + 'advanced-v2', + 'advanced-v3', + 'advanced-v4', + 'search-form-v', + 'search-form-v3', + 'collapse-keyword', + ]; + } +} diff --git a/inc/vendors/elementor/widgets/opalestate-split-maps-search.php b/inc/vendors/elementor/widgets/opalestate-split-maps-search.php new file mode 100755 index 00000000..636fdd7f --- /dev/null +++ b/inc/vendors/elementor/widgets/opalestate-split-maps-search.php @@ -0,0 +1,131 @@ +get_name(), 'eicon-search' ); + } + + /** + * Get widget keywords. + * + * Retrieve the list of keywords the widget belongs to. + * + * @access public + * + * @return array Widget keywords. + */ + public function get_keywords() { + return [ 'opalestate-pro', 'search' ]; + } + + /** + * Register icon box widget controls. + * + * Adds different input fields to allow the user to change and customize the widget settings. + * + * @access protected + */ + protected function _register_controls() { + $this->start_controls_section( + 'agents_search_form', + [ + 'label' => esc_html__( 'Search Form', 'opalestate-pro' ), + ] + ); + + $this->add_control( + 'search_form', + [ + 'label' => esc_html__( 'Search Form', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 'advanced-v2', + 'options' => opalestate_search_properties_form_styles(), + ] + ); + + $this->add_responsive_control( + 'column', + [ + 'label' => esc_html__( 'Columns', 'opalestate-pro' ), + 'type' => \Elementor\Controls_Manager::SELECT, + 'default' => 3, + 'options' => [ 1 => 1, 2 => 2, 3 => 3, 4 => 4, 6 => 6 ], + 'prefix_class' => 'elementor-grid%s-', + 'condition' => [ + 'item_layout' => 'grid', + ], + + ] + ); + + $this->add_control( + 'column_gap', + [ + 'label' => esc_html__( 'Columns Gap', 'opalestate-pro' ), + 'type' => Controls_Manager::SLIDER, + 'range' => [ + 'px' => [ + 'min' => 0, + 'max' => 100, + ], + ], + 'selectors' => [ + '{{WRAPPER}} .elementor-items-container' => 'grid-column-gap: {{SIZE}}{{UNIT}}', + + ], + 'condition' => [ + 'item_layout' => 'grid', + ], + ] + ); + $this->end_controls_section(); + } +} diff --git a/inc/vendors/index.html b/inc/vendors/index.html new file mode 100755 index 00000000..e69de29b diff --git a/inc/vendors/opalmembership/free-package.php b/inc/vendors/opalmembership/free-package.php new file mode 100755 index 00000000..893aa5bc --- /dev/null +++ b/inc/vendors/opalmembership/free-package.php @@ -0,0 +1,114 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +function opalestate_membership_settings_submission( $fields ) { + $tmp = [ + [ + 'name' => esc_html__( 'Free Submission', 'opalestate-pro' ), + 'id' => 'opalestate_title_free_submission_settings', + 'type' => 'title', + 'before_row' => '
            ', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Enable Free Submission', 'opalestate-pro' ), + 'desc' => esc_html__( 'Allow set automatic a free package.', 'opalestate-pro' ), + 'id' => 'enabel_free_submission', + 'type' => 'switch', + 'options' => [ + 1 => esc_html__( 'Yes', 'opalestate-pro' ), + 0 => esc_html__( 'No', 'opalestate-pro' ), + ], + ], + [ + 'name' => esc_html__( 'Number Free Listing', 'opalestate-pro' ), + 'desc' => esc_html__( 'Maximum number of Free Listing that users can submit.', 'opalestate-pro' ), + 'id' => 'free_number_listing', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 3, + ], + [ + 'name' => esc_html__( 'Number Free Featured', 'opalestate-pro' ), + 'desc' => esc_html__( 'Maximum number of Free Featured that users can set.', 'opalestate-pro' ), + 'id' => 'free_number_featured', + 'type' => 'text_small', + 'attributes' => [ + 'type' => 'number', + ], + 'default' => 3, + ], + ]; + + return array_merge( $fields, $tmp ); +} + +add_filter( 'opalestate_settings_submission', 'opalestate_membership_settings_submission' ); + +if ( opalestate_options( 'enabel_free_submission' ) ) { + function opalestate_check_is_membership_valid( $status, $package_id, $user_id ) { + if ( $package_id != -1 ) { + return false; + } + $package_expired = get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_ . 'package_expired', true ); + + if ( ! is_numeric( $package_expired ) ) { + $package_expired = strtotime( $package_expired ); + } + if ( ! $package_expired || $package_expired <= time() ) { + return false; + } + + return true; + } + + add_filter( 'opalmembership_check_is_membership_valid', 'opalestate_check_is_membership_valid', 3, 3 ); + + /** + * + */ + function opalestate_get_freepackage_obj() { + + $object = new Opalmembership_Package(); + $object->post_title = esc_html__( 'Free membership', 'opalestate-pro' ); + + return $object; + + } + + add_filter( 'opalmembership_get_object_membership', 'opalestate_get_freepackage_obj' ); + + /// free account + add_action( 'user_register', 'opalestate_on_create_user', 10, 1 ); + add_action( 'profile_update', 'opalestate_on_update_user' ); + function opalestate_on_create_user( $user_id ) { + if ( $user_id ) { + opalestate_reset_user_free_package( $user_id ); + } + } + + function opalestate_on_update_user( $user_id ) { + $package_id = get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_ . 'package_id', true ); + if ( empty( $package_id ) ) { + opalestate_reset_user_free_package( $user_id ); + } + } +} +?> diff --git a/inc/vendors/opalmembership/functions.php b/inc/vendors/opalmembership/functions.php new file mode 100755 index 00000000..a5fec3cb --- /dev/null +++ b/inc/vendors/opalmembership/functions.php @@ -0,0 +1,201 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + + +/** + * Count Number of listing following user + */ +function opalesate_get_user_current_listings( $user_id ){ + $args = array( + 'post_type' => 'opalestate_property', + 'post_status' => array( 'pending', 'publish' ), + 'author' => $user_id, + + ); + $posts = new WP_Query( $args ); + return $posts->found_posts; + wp_reset_postdata(); +} + +/** + * Count Number of featured listing following user + */ +function opalesate_get_user_current_featured_listings( $user_id ){ + + $args = array( + 'post_type' => 'opalestate_property', + 'post_status' => array( 'pending', 'publish' ), + 'author' => $user_id, + 'meta_query' => array( + array( + 'key' => OPALESTATE_PROPERTY_PREFIX.'featured', + 'value' => 1, + 'meta_compare '=>'=' + ) + ) + ); + $posts = new WP_Query( $args ); + return $posts->found_posts; + wp_reset_postdata(); +} + +/** + * Check current package is downgrade package or not via current number of featured, listing lesser + */ +function opalesate_check_package_downgrade_status( $user_id, $package_id ){ + + $pack_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'package_listings', true ); + $pack_featured_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'package_featured_listings', true ); + $is_unlimited = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'unlimited_listings', true ); + $pack_unlimited_listings = $is_unlimited == 'on' ? 0 : 1; + + $user_current_listings = opalesate_get_user_current_listings( $user_id ); + $user_current_featured_listings = opalesate_get_user_current_featured_listings( $user_id ); + + $current_listings = get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings',true); + + if( $pack_unlimited_listings == 1 ) { + return false; + } + + // if is unlimited and go to non unlimited pack + if ( $current_listings == -1 && $pack_unlimited_listings != 1 ) { + return true; + } + + return ( $user_current_listings > $pack_listings ) || ( $user_current_featured_listings > $pack_featured_listings ) ; +} + +/** + * Check Current User having permission to add new property or not? + */ +function opalesate_check_has_add_listing( $user_id, $package_id=null ){ + + if( !$package_id ){ + $package_id = (int)get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_id', true ); + } + + $package_listings = (int) get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings', true ); + + + $unlimited_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'unlimited_listings', true ); + + $unlimited_listings = !empty( $unlimited_listings ) && $unlimited_listings == 'on' ? 0 : 1; + + if( $package_id > 0 && $unlimited_listings ){ + return true; + } + + if( $package_listings > 0 ){ + return true; + } + return false; +} + +/** + * Check current package is downgrade package or not via current number of featured, listing lesser + */ +function opalesate_get_user_featured_remaining_listing( $user_id ){ + + $count = get_the_author_meta( OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings' , $user_id ); + + return $count; +} + +/** + * + */ +function opalestate_reset_user_free_package( $user_id ){ + + $duration = opalestate_options('free_expired_month', 12); + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_id', -1 ); + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings', opalestate_options('free_number_listing', 3) ); + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings', opalestate_options('free_number_featured', 3) ); + + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_activation', time() ); + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_expired', time() + ($duration*60*60*24*30) ); + + return true; +} + +/** + * Update remaining featured listings + */ +function opalesate_update_package_number_featured_listings( $user_id ) { + + $current = get_the_author_meta( OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings' , $user_id ); + + if( $current-1 >= 0 ) { + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings', $current-1 ) ; + } else { + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings', 0 ); + } +} + +/** + * Update remaining featured listings + */ +function opalesate_update_package_number_listings( $user_id ) { + + $current = get_the_author_meta( OPALMEMBERSHIP_USER_PREFIX_.'package_listings' , $user_id ); + + if( $current-1 >= 0 ) { + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings', $current-1 ) ; + } else { + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings', 0 ); + } +} + + +/** + * Check + */ +function opalesate_is_membership_valid( $user_id = null ){ + // $package_id = (int)get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_id', true ); + return Opalmembership_User::is_membership_valid( $user_id ); +} + + +/** + * + */ +function opalesate_listing_set_to_expire($post_id){ + + $prop = array( + + 'ID' => $post_id, + 'post_type' => 'opalestate_property', + 'post_status' => 'expired' + + ); + + wp_update_post($prop ); + + $post = get_post( $post_id ); + $user_id = $post->post_author; + + $user = get_user_by('id', $user_id); + $user_email = $user->user_email; + + $args = array( + 'expired_listing_url' => get_permalink($post_id), + 'expired_listing_name' => get_the_title($post_id) + ); + + opalesate_email_type( $user_email, 'listing_expired', $args ); +} \ No newline at end of file diff --git a/inc/vendors/opalmembership/membership.php b/inc/vendors/opalmembership/membership.php new file mode 100755 index 00000000..bf190bf8 --- /dev/null +++ b/inc/vendors/opalmembership/membership.php @@ -0,0 +1,630 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +if ( defined( 'OpalMembership' ) ) { + return; +} +/** + * @class OpalEstate_Membership: as vendor class is using for processing logic with update/set permission for user submitting property. + * + * @version 1.0 + */ +class OpalEstate_Membership{ + + /* + * Constructor + */ + public static function init() { + + if( get_current_user_id() ){ + /* estate */ + add_action( 'show_admin_bar' , array( __CLASS__, 'hide_admin_toolbar' ) ); // hide admin toolbar + /* cmb2 meta box hook membership information */ + add_filter( 'opalmembership_postype_membership_metaboxes_fields', array( __CLASS__, 'metabox' ), 10 ); + /* add user agent role after insert new user member */ + // add_filter( 'opalmembership_create_user_data' , array( __CLASS__, 'add_user_role_data' ), 10 ); + // add_action( 'opalmembership_create_new_user_successfully', array( __CLASS__, 'trigger_create_user_agent' ), 10, 3 ); + /** + * save user meta when save user agent post type + */ + add_action( 'cmb2_save_post_fields', array( __CLASS__, 'trigger_update_user_meta' ), 10, 4 ); + add_action( 'profile_update', array( __CLASS__, 'trigger_update_agent_meta' ), 10, 2 ); + /** + * Call Hook after updated membership information in user data. + */ + add_action( 'opalmembership_after_update_user_membership' , array( __CLASS__,'on_set_user_update_membership') , 10, 3 ); + + /** + * HOOK TO My Properties Page Set action to check when user set property as featured. + */ + add_filter( 'opalestate_set_feature_property_checked' , array( __CLASS__,'feature_property_checked') ); + add_action( 'opalestate_toggle_featured_property_before' , array( __CLASS__,'update_featured_remaining_listing'), 10, 2 ); + + /** + * HOOK to Submssion Page: Check permission before submitting + */ + // check validation before + add_action( 'opalestate_process_submission_before' , array( __CLASS__, 'check_membership_validation' ), 1 ); + + add_action( 'opalestate_submission_form_before' , array( __CLASS__ ,'show_membership_warning'), 9 ); + add_action( 'opalestate_submission_form_before' , array( __CLASS__, 'check_membership_validation_message' ) ); + + add_action( 'opalestate_process_edit_submission_before' , array( __CLASS__, 'check_edit_post' ) ); + add_action( 'opalestate_process_add_submission_before' , array( __CLASS__, 'check_add_post' ) ); + /// check before uploading image + add_action( 'opalestate_before_process_ajax_upload_file' , array( __CLASS__, 'check_ajax_upload' ) ); + add_action( 'opalestate_process_submission_after' , array( __CLASS__, 'update_remainng_listing' ) , 10, 3 ); + + /** + * HOOK to user management Menu + */ + add_filter( 'opalestate_management_user_menu' , array( __CLASS__, 'membership_menu' ) ); + + /** + * Hook to widget to show addition about current package. + */ + add_action( 'opalmembership_current_package_summary_after' , array( __CLASS__, 'render_membership_summary' ), 10, 2 ); + + /** + * Add 'opalesate_agent' role to get_users member data + */ + // add_action( 'opalmembership_member_table_arguments', array( __CLASS__, 'member_table_get_user_arguments' ) ); + // show in membership dashboard + add_action( 'opalmembership_dashboard_container_before' , array( __CLASS__, 'check_membership_validation_message' ) ); + // included logic functions + + require_once( 'free-package.php' ); + require_once( 'functions.php' ); + + add_action( 'opalmembership_current_package_summary_after' , array( __CLASS__, 'render_membership_summary' ), 10, 2 ); + + add_action( 'cmb2_admin_init', array( __CLASS__, 'register_user_package_metabox') ); + + + add_action( 'profile_update' , array( __CLASS__, 'on_update_user' ), 10, 1 ); + } + + /** + * Hook to loop of package membership + */ + add_action( 'opalmembership_content_single_before' , array( __CLASS__, 'render_membership_pricing_box' ) ); + + + } + + public static function show_membership_warning(){ + if( isset($_GET['id']) && $_GET['id'] > 0 ){ + return true; + } + if( class_exists("Opalmembership_User") ){ + return Opalmembership_User::show_membership_warning(); + } + } + + public static function render_membership_free_package(){ + echo opalestate_load_template_path( 'parts/membership-free-package', array() ); + } + + public static function render_membership_pricing_box(){ + echo opalestate_load_template_path( 'parts/membership-pricing-info', array() ); + } + + public static function member_table_get_user_arguments( $args ) { + return array_merge_recursive( $args, array( 'role__in' => array( 'opalestate_agent' ) ) ); + } + + + public static function set_properties_expired(){ + + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + + $args = array( + 'post_type' => 'opalestate_agent', + 'author' => $user_id, + 'post_status' => 'any' + ); + + $query = new WP_Query( $args ); + + while( $query->have_posts()) { + $query->the_post(); + + $prop = array( + 'ID' => $post->ID, + 'post_type' => 'opalestate_agent', + 'post_status' => 'expired' + ); + + wp_update_post($prop ); + } + wp_reset_query(); + + } + + /** + * Before upload any file. this is called to check user having package which allows to upload or is not expired. + * + * @return void if everything is ok, or json data if it is not valid. + */ + public static function check_ajax_upload(){ + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + + $has = opalesate_check_has_add_listing( $user_id ); + + + $check = opalesate_is_membership_valid( $user_id ); + + if( ! $check || ! $has ){ + $std = new stdClass(); + $std->status = false ; + $std->message = esc_html__( 'Could not allow uploading image','opalestate-pro' ); + echo json_encode( $std ); exit(); + } + } + + /** + * hide admin toolbar with user role agent + */ + public static function hide_admin_toolbar( $show ) { + if ( ! is_user_logged_in() ) { return $show; } + + $user = wp_get_current_user(); + if ( opalestate_get_option( 'hide_toolbar' ) && $user->roles && in_array( 'opalestate_agent', $user->roles ) ) { + return false; + } + return $show; + } + + /** + * Trigger to extend fields to inject into Metabox of property edit/add form. + */ + public static function metabox( $fields ) { + + if ( ! defined( 'OPALMEMBERSHIP_PACKAGES_PREFIX' ) ) return $fields; + + $prefix = OPALMEMBERSHIP_PACKAGES_PREFIX; + + $fields[] = array( + 'name' => esc_html__( 'Number Of Properties', 'opalestate-pro' ), + 'id' => $prefix . 'package_listings', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + 'min' => 0 + ), + 'std' => '1', + 'description' => esc_html__( 'Number of properties with this package. If not set it will be unlimited.', 'opalestate-pro' ) + ); + + $fields[] = array( + 'name' => esc_html__( 'Number Of Featured Properties', 'opalestate-pro' ), + 'id' => $prefix . 'package_featured_listings', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + 'min' => 0 + ), + 'std' => '1', + 'description' => esc_html__( 'Number of properties can make featured with this package.', 'opalestate-pro' ) + ); + + $fields[] = array( + 'name' => esc_html__( ' Unlimited listings ?', 'opalestate-pro' ), + 'id' => $prefix . 'unlimited_listings', + 'type' => 'checkbox', + 'std' => '1', + 'description' => esc_html__( 'No, it is not unlimited, If not set it will be unlimited. Number of properties can make featured with this package.', 'opalestate-pro' ) + ); + + return $fields; + } + + /** + * Hook Method to add more link for user management + */ + public static function membership_menu( $menu ){ + if( function_exists("opalmembership_get_dashdoard_page_uri") ){ + global $opalmembership_options; + $menu['membership'] = array( + 'icon' => 'fa fa-user', + 'link' => opalmembership_get_dashdoard_page_uri(), + 'title' => esc_html__( 'My Membership', 'opalestate-pro' ), + 'id' => isset( $opalmembership_options['dashboard_page'] ) ? $opalmembership_options['dashboard_page'] : 0 + ); + + $menu['membership_history'] = array( + 'icon' => 'fa fa-user', + 'link' => opalmembership_get_payment_history_page_uri(), + 'title' => esc_html__( 'My Invoices', 'opalestate-pro' ), + 'id' => isset( $opalmembership_options['dashboard_page'] ) ? $opalmembership_options['dashboard_page'] : 0 + ); + + $menu['packages'] = array( + 'icon' => 'fa fa-certificate', + 'link' => opalmembership_get_membership_page_uri(), + 'title' => esc_html__( 'Renew membership', 'opalestate-pro' ), + 'id' => isset( $opalmembership_options['dashboard_page'] ) ? $opalmembership_options['dashboard_page'] : 0 + ); + } + return $menu; + } + + /** + * This function add new user role in this case is add 'opalestate_agent' role to user created + */ + public static function add_user_role_data( $cred ) { + $cred['role'] = 'opalestate_agent'; + return $cred; + } + + /** + * trigger create new post type user agent + */ + public static function trigger_create_user_agent( $user_id, $user_data, $cred ) { + // create new post(opalestate_agent) + $agent_id = opalesate_insert_user_agent( array( + 'first_name' => $cred['first_name'], + 'last_name' => $cred['last_name'], + 'email' => $cred['user_email'] + ) ); + + update_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'user_id', $user_id ); + } + + /** + * save user meta data + */ + public static function trigger_update_user_meta( $agent_id, $cmb_id, $updated, $cmb2 ) { + + if ( $cmb_id !== 'opalestate_agt_info' || empty( $cmb2->data_to_save ) ) return; + $user_id = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'user_id', true ); + + if ( ! $user_id ) return; + foreach ( $cmb2->data_to_save as $name => $value ) { + + + if ( strpos( $name, OPALESTATE_AGENT_PREFIX ) === 0 ) { + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . substr( $name, strlen( OPALESTATE_AGENT_PREFIX ) ), $value ); + } + } + } + + /** + * trigger save agent post meta + */ + public static function trigger_update_agent_meta( $user_id, $old_user_meta ) { + if ( empty( $_POST ) ) return; + global $wpdb; + $sql = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_value = %d AND meta_key = %s", $user_id, OPALESTATE_AGENT_PREFIX . 'user_id' ); + $agent_id = $wpdb->get_var( $sql ); + + if ( ! $agent_id ) return; + foreach ( $_POST as $name => $value ) { + if ( strpos( $name, OPALESTATE_USER_PROFILE_PREFIX ) === 0 ) { + update_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . substr( $name, strlen( OPALESTATE_USER_PROFILE_PREFIX ) ), $value ); + } + } + } + + /** + * This function is called when payment status is completed. It will update new number of featured, listing for user. + * + * @return void + */ + public static function on_set_user_update_membership( $package_id, $user_id=0, $payment_id=0 ){ + /** + * Get some information from selected package. + */ + $pack_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'package_listings', true ); + $pack_featured_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'package_featured_listings', true ); + $is_unlimited_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'unlimited_listings', true ); + + $pack_unlimited_listings = $is_unlimited_listings == 'on' ? 0 : 1; + /** + * Get package information with user logined + */ + $current_listings = get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings',true); + $curent_featured_listings = get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings',true); + $current_pack = get_user_meta( $user_id,OPALMEMBERSHIP_USER_PREFIX_.'package_id', true ); + + $user_current_listings = opalesate_get_user_current_listings ( $user_id ); // get user current listings ( no expired ) + $user_current_featured_listings = opalesate_get_user_current_featured_listings( $user_id ); // get user current featured listings ( no expired ) + + if( opalesate_check_package_downgrade_status( $user_id, $package_id ) ) { + $new_listings = $pack_listings; + $new_featured_listings = $pack_featured_listings; + }else{ + $new_listings = $pack_listings - $user_current_listings ; + $new_featured_listings = $pack_featured_listings - $user_current_featured_listings ; + } + + // in case of downgrade + if( $new_listings < 0 ) { + $new_listings = 0; + } + + if( $new_featured_listings < 0 ) { + $new_featured_listings = 0; + } + + + if ( $pack_unlimited_listings == 1 ) { + $new_listings = -1; + } + + /** + * Update new number of packages listings and featured listing. + */ + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings', $new_listings) ; + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings', $new_featured_listings); + } + + /** + * This function is called when user set property as featured. + * + * @return boolean. true is user having permission. + */ + public static function feature_property_checked(){ + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + + if( isset($_POST['property_id']) ){ + return opalesate_get_user_featured_remaining_listing( $user_id ); + } + return false; + } + + /** + * Reduce -1 when set featured status is done. + */ + public static function update_featured_remaining_listing( $user_id, $property_id ){ + opalesate_update_package_number_featured_listings( $user_id ); + } + + /** + * + */ + public static function update_remainng_listing( $user_id, $property_id , $isedit=true ){ + if( $isedit != true ){ + opalesate_update_package_number_listings( $user_id ); + } + } + + /** + * Check user having any actived package and the package is not expired. + * Auto redirect to membership packages package. + */ + public static function check_membership_validation(){ + $check = opalesate_is_membership_valid(); + if( !$check ){ + + return opalestate_output_msg_json( true, + __('Your membership package is expired or Your package has 0 left listing, please upgrade now.', 'opalestate-pro' ), + array( + 'heading' => esc_html__('Submission Information' ,'opalestate-pro'), + 'redirect' => opalmembership_get_membership_page_uri(array('warning=1')) + )) ; + } + return ; + } + + /** + * Check any action while editing page + */ + public static function check_edit_post(){ + return true; + } + + /** + * Check permission to allow creating any property. The package is not valid, it is automatic redirect to membership page. + */ + public static function check_add_post(){ + + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + + $has = opalesate_check_has_add_listing( $user_id ); + if( $has == false ){ + wp_redirect( opalmembership_get_membership_page_uri( array('warning=2') ) ); exit; + } + } + + /** + * Display membership warning at top of submission form. + */ + public static function check_membership_validation_message(){ + + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + if( isset($_GET['id']) && $_GET['id'] > 0 ){ + return ; + } + + echo opalestate_load_template_path( 'parts/membership-warning', array('user_id' => $user_id) ); + + } + + /** + * Hooked method to display more information about actived package. + */ + public static function render_membership_summary($package_id=0, $payment_id=0){ + + global $current_user; + + wp_get_current_user(); + $user_id = $current_user->ID; + + $current_listings = get_user_meta($user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_listings',true); + $curent_featured_listings = get_user_meta($user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_featured_listings',true); + + /// + $pack_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'package_listings', true ); + $pack_featured_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'package_featured_listings', true ); + $pack_unlimited_listings = get_post_meta( $package_id, OPALMEMBERSHIP_PACKAGES_PREFIX.'unlimited_listings', true ); + $unlimited_listings = $pack_unlimited_listings == 'on' ? 0 : 1; + /// + + $output = ''; + if( $unlimited_listings == 1 && $package_id > 0 ){ + $output .= '
          • '.__('(Package) Listings Included:','opalestate-pro').' '.__( 'Unlimited', 'opalestate-pro' ).'
          • '; + $output .= '
          • '.__('(Package) Featured Included:','opalestate-pro').' '.__( 'Unlimited', 'opalestate-pro' ).'
          • '; + }else { + if( $package_id > 0 ){ + $output .= '
          • '.__('(Package) Listings Included:','opalestate-pro').' '.$pack_listings.'
          • '; + $output .= '
          • '.__('(Package) Featured Included:','opalestate-pro').' '.$pack_featured_listings.'
          • '; + } + $output .= '
          • '.__('Listings Remaining:','opalestate-pro').' '.$current_listings.'
          • '; + $output .= '
          • '.__('Featured Remaining:','opalestate-pro').' '.$curent_featured_listings.'
          • '; + } + + echo $output; + } + + public static function membership_username_actions( $actions, $items ) { + $actions['edit'] = sprintf( '%s', get_edit_post_link( 0 ), esc_html__( 'Edit', 'opalestate-pro' ) ); + return $actions; + } + + /** + * Hook in and add a metabox to add fields to the user profile pages + */ + public static function register_user_package_metabox( ) { + + if( !defined("OPALMEMBERSHIP_USER_PREFIX_") || !current_user_can( 'manage_options' ) ){ + return ; + } + + $prefix = OPALMEMBERSHIP_USER_PREFIX_; + $fields = array(); + + + foreach( $fields as $field ){ + $cmb_user->add_field( $field ); + } + $fields = array(); + $date = null ; + + $current_user = wp_get_current_user(); + + if( (isset($_GET['user_id']) && $_GET['user_id']) ){ + $user_id = (int)$_GET['user_id']; + } else { + $user_id = get_current_user_id(); + } + + $date = get_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_expired', true ); + + /** + * Metabox for the user profile screen + */ + $cmb_user = new_cmb2_box( array( + 'id' => $prefix . 'package', + 'title' => esc_html__( 'Membership Package', 'opalestate-pro' ), // Doesn't output for user boxes + 'object_types' => array( 'user' ), // Tells CMB2 to use user_meta vs post_meta + 'show_names' => true, + 'new_user_section' => 'add-new-user', // where form will show on new user page. 'add-existing-user' is only other valid option. + ) ); + + $fields[] = array( + 'name' => esc_html__( 'Package', 'opalestate-pro' ), + 'id' => $prefix . 'package_id', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + 'min' => 0 + ), + 'std' => '1', + 'description' => esc_html__( 'Set package ID with -1 as free package.', 'opalestate-pro' ), + 'before_row' => '

            '.__( 'Membership Information', 'opalestate-pro' ).'

            ' + ); + + + $fields[] = array( + 'name' => esc_html__( 'Number Of Properties', 'opalestate-pro' ), + 'id' => $prefix . 'package_listings', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + 'min' => 0 + ), + 'std' => '1', + 'description' => esc_html__( 'Number of properties with this package. If not set it will be unlimited.', 'opalestate-pro' ) + ); + + $fields[] = array( + 'name' => esc_html__( 'Number Of Featured Properties', 'opalestate-pro' ), + 'id' => $prefix . 'package_featured_listings', + 'type' => 'text', + 'attributes' => array( + 'type' => 'number', + 'pattern' => '\d*', + 'min' => 0 + ), + 'std' => '1', + 'description' => esc_html__( 'Number of properties can make featured with this package.', 'opalestate-pro' ) + ); + + $fields[] = array( + 'name' => esc_html__( 'Expired', 'opalestate-pro' ), + 'id' => $prefix . 'package_expired_date', + 'type' => 'text_date', + 'default' => $date, + 'std' => '1', + 'description' => esc_html__( 'Show expired time in double format.', 'opalestate-pro' ) + ); + + $fields[] = array( + 'name' => esc_html__( 'Expired', 'opalestate-pro' ), + 'id' => $prefix . 'package_expired', + 'type' => 'text', + 'std' => '1', + 'description' => esc_html__( 'Show expired time in double format.', 'opalestate-pro' ) + ); + + + foreach( $fields as $field ){ + $cmb_user->add_field( $field ); + } + // } + } + + public static function on_update_user( $user_id ) { + if( $user_id ){ + $prefix = OPALMEMBERSHIP_USER_PREFIX_; + $field = $prefix.'package_expired_date'; + if( isset($_POST[$field]) && !empty($_POST[$field]) ) { + $expired_time = strtotime($_POST[$field]); + $_POST[$prefix . 'package_expired'] = $expired_time; + update_user_meta( $user_id, OPALMEMBERSHIP_USER_PREFIX_.'package_expired', $expired_time ); + } + } + } +} + +OpalEstate_Membership::init(); \ No newline at end of file diff --git a/inc/vendors/social-login/Facebook/Authentication/AccessToken.php b/inc/vendors/social-login/Facebook/Authentication/AccessToken.php new file mode 100755 index 00000000..5d700733 --- /dev/null +++ b/inc/vendors/social-login/Facebook/Authentication/AccessToken.php @@ -0,0 +1,160 @@ +value = $accessToken; + if ($expiresAt) { + $this->setExpiresAtFromTimeStamp($expiresAt); + } + } + + /** + * Generate an app secret proof to sign a request to Graph. + * + * @param string $appSecret The app secret. + * + * @return string + */ + public function getAppSecretProof($appSecret) + { + return hash_hmac('sha256', $this->value, $appSecret); + } + + /** + * Getter for expiresAt. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->expiresAt; + } + + /** + * Determines whether or not this is an app access token. + * + * @return bool + */ + public function isAppAccessToken() + { + return strpos($this->value, '|') !== false; + } + + /** + * Determines whether or not this is a long-lived token. + * + * @return bool + */ + public function isLongLived() + { + if ($this->expiresAt) { + return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2); + } + + if ($this->isAppAccessToken()) { + return true; + } + + return false; + } + + /** + * Checks the expiration of the access token. + * + * @return boolean|null + */ + public function isExpired() + { + if ($this->getExpiresAt() instanceof \DateTime) { + return $this->getExpiresAt()->getTimestamp() < time(); + } + + if ($this->isAppAccessToken()) { + return false; + } + + return null; + } + + /** + * Returns the access token as a string. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns the access token as a string. + * + * @return string + */ + public function __toString() + { + return $this->getValue(); + } + + /** + * Setter for expires_at. + * + * @param int $timeStamp + */ + protected function setExpiresAtFromTimeStamp($timeStamp) + { + $dt = new \DateTime(); + $dt->setTimestamp($timeStamp); + $this->expiresAt = $dt; + } +} diff --git a/inc/vendors/social-login/Facebook/Authentication/AccessTokenMetadata.php b/inc/vendors/social-login/Facebook/Authentication/AccessTokenMetadata.php new file mode 100755 index 00000000..165433cb --- /dev/null +++ b/inc/vendors/social-login/Facebook/Authentication/AccessTokenMetadata.php @@ -0,0 +1,390 @@ +metadata = $metadata['data']; + + $this->castTimestampsToDateTime(); + } + + /** + * Returns a value from the metadata. + * + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. + * + * @return mixed + */ + public function getField($field, $default = null) + { + if (isset($this->metadata[$field])) { + return $this->metadata[$field]; + } + + return $default; + } + + /** + * Returns a value from the metadata. + * + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. + * + * @return mixed + * + * @deprecated 5.0.0 getProperty() has been renamed to getField() + * @todo v6: Remove this method + */ + public function getProperty($field, $default = null) + { + return $this->getField($field, $default); + } + + /** + * Returns a value from a child property in the metadata. + * + * @param string $parentField The parent property. + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. + * + * @return mixed + */ + public function getChildProperty($parentField, $field, $default = null) + { + if (!isset($this->metadata[$parentField])) { + return $default; + } + + if (!isset($this->metadata[$parentField][$field])) { + return $default; + } + + return $this->metadata[$parentField][$field]; + } + + /** + * Returns a value from the error metadata. + * + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. + * + * @return mixed + */ + public function getErrorProperty($field, $default = null) + { + return $this->getChildProperty('error', $field, $default); + } + + /** + * Returns a value from the "metadata" metadata. *Brain explodes* + * + * @param string $field The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. + * + * @return mixed + */ + public function getMetadataProperty($field, $default = null) + { + return $this->getChildProperty('metadata', $field, $default); + } + + /** + * The ID of the application this access token is for. + * + * @return string|null + */ + public function getAppId() + { + return $this->getField('app_id'); + } + + /** + * Name of the application this access token is for. + * + * @return string|null + */ + public function getApplication() + { + return $this->getField('application'); + } + + /** + * Any error that a request to the graph api + * would return due to the access token. + * + * @return bool|null + */ + public function isError() + { + return $this->getField('error') !== null; + } + + /** + * The error code for the error. + * + * @return int|null + */ + public function getErrorCode() + { + return $this->getErrorProperty('code'); + } + + /** + * The error message for the error. + * + * @return string|null + */ + public function getErrorMessage() + { + return $this->getErrorProperty('message'); + } + + /** + * The error subcode for the error. + * + * @return int|null + */ + public function getErrorSubcode() + { + return $this->getErrorProperty('subcode'); + } + + /** + * DateTime when this access token expires. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->getField('expires_at'); + } + + /** + * Whether the access token is still valid or not. + * + * @return boolean|null + */ + public function getIsValid() + { + return $this->getField('is_valid'); + } + + /** + * DateTime when this access token was issued. + * + * Note that the issued_at field is not returned + * for short-lived access tokens. + * + * @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug + * + * @return \DateTime|null + */ + public function getIssuedAt() + { + return $this->getField('issued_at'); + } + + /** + * General metadata associated with the access token. + * Can contain data like 'sso', 'auth_type', 'auth_nonce'. + * + * @return array|null + */ + public function getMetadata() + { + return $this->getField('metadata'); + } + + /** + * The 'sso' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getSso() + { + return $this->getMetadataProperty('sso'); + } + + /** + * The 'auth_type' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getAuthType() + { + return $this->getMetadataProperty('auth_type'); + } + + /** + * The 'auth_nonce' child property from the 'metadata' parent property. + * + * @return string|null + */ + public function getAuthNonce() + { + return $this->getMetadataProperty('auth_nonce'); + } + + /** + * For impersonated access tokens, the ID of + * the page this token contains. + * + * @return string|null + */ + public function getProfileId() + { + return $this->getField('profile_id'); + } + + /** + * List of permissions that the user has granted for + * the app in this access token. + * + * @return array + */ + public function getScopes() + { + return $this->getField('scopes'); + } + + /** + * The ID of the user this access token is for. + * + * @return string|null + */ + public function getUserId() + { + return $this->getField('user_id'); + } + + /** + * Ensures the app ID from the access token + * metadata is what we expect. + * + * @param string $appId + * + * @throws FacebookSDKException + */ + public function validateAppId($appId) + { + if ($this->getAppId() !== $appId) { + throw new FacebookSDKException('Access token metadata contains unexpected app ID.', 401); + } + } + + /** + * Ensures the user ID from the access token + * metadata is what we expect. + * + * @param string $userId + * + * @throws FacebookSDKException + */ + public function validateUserId($userId) + { + if ($this->getUserId() !== $userId) { + throw new FacebookSDKException('Access token metadata contains unexpected user ID.', 401); + } + } + + /** + * Ensures the access token has not expired yet. + * + * @throws FacebookSDKException + */ + public function validateExpiration() + { + if (!$this->getExpiresAt() instanceof \DateTime) { + return; + } + + if ($this->getExpiresAt()->getTimestamp() < time()) { + throw new FacebookSDKException('Inspection of access token metadata shows that the access token has expired.', 401); + } + } + + /** + * Converts a unix timestamp into a DateTime entity. + * + * @param int $timestamp + * + * @return \DateTime + */ + private function convertTimestampToDateTime($timestamp) + { + $dt = new \DateTime(); + $dt->setTimestamp($timestamp); + + return $dt; + } + + /** + * Casts the unix timestamps as DateTime entities. + */ + private function castTimestampsToDateTime() + { + foreach (static::$dateProperties as $key) { + if (isset($this->metadata[$key]) && $this->metadata[$key] !== 0) { + $this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]); + } + } + } +} diff --git a/inc/vendors/social-login/Facebook/Authentication/OAuth2Client.php b/inc/vendors/social-login/Facebook/Authentication/OAuth2Client.php new file mode 100755 index 00000000..94df9b7b --- /dev/null +++ b/inc/vendors/social-login/Facebook/Authentication/OAuth2Client.php @@ -0,0 +1,292 @@ +app = $app; + $this->client = $client; + $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; + } + + /** + * Returns the last FacebookRequest that was sent. + * Useful for debugging and testing. + * + * @return FacebookRequest|null + */ + public function getLastRequest() + { + return $this->lastRequest; + } + + /** + * Get the metadata associated with the access token. + * + * @param AccessToken|string $accessToken The access token to debug. + * + * @return AccessTokenMetadata + */ + public function debugToken($accessToken) + { + $accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; + $params = ['input_token' => $accessToken]; + + $this->lastRequest = new FacebookRequest( + $this->app, + $this->app->getAccessToken(), + 'GET', + '/debug_token', + $params, + null, + $this->graphVersion + ); + $response = $this->client->sendRequest($this->lastRequest); + $metadata = $response->getDecodedBody(); + + return new AccessTokenMetadata($metadata); + } + + /** + * Generates an authorization URL to begin the process of authenticating a user. + * + * @param string $redirectUrl The callback URL to redirect to. + * @param string $state The CSPRNG-generated CSRF value. + * @param array $scope An array of permissions to request. + * @param array $params An array of parameters to generate URL. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], array $params = [], $separator = '&') + { + $params += [ + 'client_id' => $this->app->getId(), + 'state' => $state, + 'response_type' => 'code', + 'sdk' => 'php-sdk-' . Facebook::VERSION, + 'redirect_uri' => $redirectUrl, + 'scope' => implode(',', $scope) + ]; + + return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . http_build_query($params, null, $separator); + } + + /** + * Get a valid access token from a code. + * + * @param string $code + * @param string $redirectUri + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getAccessTokenFromCode($code, $redirectUri = '') + { + $params = [ + 'code' => $code, + 'redirect_uri' => $redirectUri, + ]; + + return $this->requestAnAccessToken($params); + } + + /** + * Exchanges a short-lived access token with a long-lived access token. + * + * @param AccessToken|string $accessToken + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getLongLivedAccessToken($accessToken) + { + $accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; + $params = [ + 'grant_type' => 'fb_exchange_token', + 'fb_exchange_token' => $accessToken, + ]; + + return $this->requestAnAccessToken($params); + } + + /** + * Get a valid code from an access token. + * + * @param AccessToken|string $accessToken + * @param string $redirectUri + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') + { + $params = [ + 'redirect_uri' => $redirectUri, + ]; + + $response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken); + $data = $response->getDecodedBody(); + + if (!isset($data['code'])) { + throw new FacebookSDKException('Code was not returned from Graph.', 401); + } + + return $data['code']; + } + + /** + * Send a request to the OAuth endpoint. + * + * @param array $params + * + * @return AccessToken + * + * @throws FacebookSDKException + */ + protected function requestAnAccessToken(array $params) + { + $response = $this->sendRequestWithClientParams('/oauth/access_token', $params); + $data = $response->getDecodedBody(); + + if (!isset($data['access_token'])) { + throw new FacebookSDKException('Access token was not returned from Graph.', 401); + } + + // Graph returns two different key names for expiration time + // on the same endpoint. Doh! :/ + $expiresAt = 0; + if (isset($data['expires'])) { + // For exchanging a short lived token with a long lived token. + // The expiration time in seconds will be returned as "expires". + $expiresAt = time() + $data['expires']; + } elseif (isset($data['expires_in'])) { + // For exchanging a code for a short lived access token. + // The expiration time in seconds will be returned as "expires_in". + // See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code + $expiresAt = time() + $data['expires_in']; + } + + return new AccessToken($data['access_token'], $expiresAt); + } + + /** + * Send a request to Graph with an app access token. + * + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * + * @return FacebookResponse + * + * @throws FacebookResponseException + */ + protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null) + { + $params += $this->getClientParams(); + + $accessToken = $accessToken ?: $this->app->getAccessToken(); + + $this->lastRequest = new FacebookRequest( + $this->app, + $accessToken, + 'GET', + $endpoint, + $params, + null, + $this->graphVersion + ); + + return $this->client->sendRequest($this->lastRequest); + } + + /** + * Returns the client_* params for OAuth requests. + * + * @return array + */ + protected function getClientParams() + { + return [ + 'client_id' => $this->app->getId(), + 'client_secret' => $this->app->getSecret(), + ]; + } +} diff --git a/inc/vendors/social-login/Facebook/Exceptions/FacebookAuthenticationException.php b/inc/vendors/social-login/Facebook/Exceptions/FacebookAuthenticationException.php new file mode 100755 index 00000000..c5e45fa3 --- /dev/null +++ b/inc/vendors/social-login/Facebook/Exceptions/FacebookAuthenticationException.php @@ -0,0 +1,33 @@ +response = $response; + $this->responseData = $response->getDecodedBody(); + + $errorMessage = $this->get('message', 'Unknown error from Graph.'); + $errorCode = $this->get('code', -1); + + parent::__construct($errorMessage, $errorCode, $previousException); + } + + /** + * A factory for creating the appropriate exception based on the response from Graph. + * + * @param FacebookResponse $response The response that threw the exception. + * + * @return FacebookResponseException + */ + public static function create(FacebookResponse $response) + { + $data = $response->getDecodedBody(); + + if (!isset($data['error']['code']) && isset($data['code'])) { + $data = ['error' => $data]; + } + + $code = isset($data['error']['code']) ? $data['error']['code'] : null; + $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; + + if (isset($data['error']['error_subcode'])) { + switch ($data['error']['error_subcode']) { + // Other authentication issues + case 458: + case 459: + case 460: + case 463: + case 464: + case 467: + return new static($response, new FacebookAuthenticationException($message, $code)); + // Video upload resumable error + case 1363030: + case 1363019: + case 1363033: + case 1363021: + case 1363041: + return new static($response, new FacebookResumableUploadException($message, $code)); + case 1363037: + $previousException = new FacebookResumableUploadException($message, $code); + + $startOffset = isset($data['error']['error_data']['start_offset']) ? (int) $data['error']['error_data']['start_offset'] : null; + $previousException->setStartOffset($startOffset); + + $endOffset = isset($data['error']['error_data']['end_offset']) ? (int) $data['error']['error_data']['end_offset'] : null; + $previousException->setEndOffset($endOffset); + + return new static($response, $previousException); + } + } + + switch ($code) { + // Login status or token expired, revoked, or invalid + case 100: + case 102: + case 190: + return new static($response, new FacebookAuthenticationException($message, $code)); + + // Server issue, possible downtime + case 1: + case 2: + return new static($response, new FacebookServerException($message, $code)); + + // API Throttling + case 4: + case 17: + case 32: + case 341: + case 613: + return new static($response, new FacebookThrottleException($message, $code)); + + // Duplicate Post + case 506: + return new static($response, new FacebookClientException($message, $code)); + } + + // Missing Permissions + if ($code == 10 || ($code >= 200 && $code <= 299)) { + return new static($response, new FacebookAuthorizationException($message, $code)); + } + + // OAuth authentication error + if (isset($data['error']['type']) && $data['error']['type'] === 'OAuthException') { + return new static($response, new FacebookAuthenticationException($message, $code)); + } + + // All others + return new static($response, new FacebookOtherException($message, $code)); + } + + /** + * Checks isset and returns that or a default value. + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ + private function get($key, $default = null) + { + if (isset($this->responseData['error'][$key])) { + return $this->responseData['error'][$key]; + } + + return $default; + } + + /** + * Returns the HTTP status code + * + * @return int + */ + public function getHttpStatusCode() + { + return $this->response->getHttpStatusCode(); + } + + /** + * Returns the sub-error code + * + * @return int + */ + public function getSubErrorCode() + { + return $this->get('error_subcode', -1); + } + + /** + * Returns the error type + * + * @return string + */ + public function getErrorType() + { + return $this->get('type', ''); + } + + /** + * Returns the raw response used to create the exception. + * + * @return string + */ + public function getRawResponse() + { + return $this->response->getBody(); + } + + /** + * Returns the decoded response used to create the exception. + * + * @return array + */ + public function getResponseData() + { + return $this->responseData; + } + + /** + * Returns the response entity used to create the exception. + * + * @return FacebookResponse + */ + public function getResponse() + { + return $this->response; + } +} diff --git a/inc/vendors/social-login/Facebook/Exceptions/FacebookResumableUploadException.php b/inc/vendors/social-login/Facebook/Exceptions/FacebookResumableUploadException.php new file mode 100755 index 00000000..6d41c63c --- /dev/null +++ b/inc/vendors/social-login/Facebook/Exceptions/FacebookResumableUploadException.php @@ -0,0 +1,68 @@ +startOffset; + } + + /** + * @param int|null $startOffset + */ + public function setStartOffset($startOffset) + { + $this->startOffset = $startOffset; + } + + /** + * @return int|null + */ + public function getEndOffset() + { + return $this->endOffset; + } + + /** + * @param int|null $endOffset + */ + public function setEndOffset($endOffset) + { + $this->endOffset = $endOffset; + } +} diff --git a/inc/vendors/social-login/Facebook/Exceptions/FacebookSDKException.php b/inc/vendors/social-login/Facebook/Exceptions/FacebookSDKException.php new file mode 100755 index 00000000..d8bef1ab --- /dev/null +++ b/inc/vendors/social-login/Facebook/Exceptions/FacebookSDKException.php @@ -0,0 +1,33 @@ + getenv(static::APP_ID_ENV_NAME), + 'app_secret' => getenv(static::APP_SECRET_ENV_NAME), + 'default_graph_version' => static::DEFAULT_GRAPH_VERSION, + 'enable_beta_mode' => false, + 'http_client_handler' => null, + 'persistent_data_handler' => null, + 'pseudo_random_string_generator' => null, + 'url_detection_handler' => null, + ], $config); + + if (!$config['app_id']) { + throw new FacebookSDKException('Required "app_id" key not supplied in config and could not find fallback environment variable "' . static::APP_ID_ENV_NAME . '"'); + } + if (!$config['app_secret']) { + throw new FacebookSDKException('Required "app_secret" key not supplied in config and could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME . '"'); + } + + $this->app = new FacebookApp($config['app_id'], $config['app_secret']); + $this->client = new FacebookClient( + HttpClientsFactory::createHttpClient($config['http_client_handler']), + $config['enable_beta_mode'] + ); + $this->pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator( + $config['pseudo_random_string_generator'] + ); + $this->setUrlDetectionHandler($config['url_detection_handler'] ?: new FacebookUrlDetectionHandler()); + $this->persistentDataHandler = PersistentDataFactory::createPersistentDataHandler( + $config['persistent_data_handler'] + ); + + if (isset($config['default_access_token'])) { + $this->setDefaultAccessToken($config['default_access_token']); + } + + // @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set + $this->defaultGraphVersion = $config['default_graph_version']; + } + + /** + * Returns the FacebookApp entity. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->app; + } + + /** + * Returns the FacebookClient service. + * + * @return FacebookClient + */ + public function getClient() + { + return $this->client; + } + + /** + * Returns the OAuth 2.0 client service. + * + * @return OAuth2Client + */ + public function getOAuth2Client() + { + if (!$this->oAuth2Client instanceof OAuth2Client) { + $app = $this->getApp(); + $client = $this->getClient(); + $this->oAuth2Client = new OAuth2Client($app, $client, $this->defaultGraphVersion); + } + + return $this->oAuth2Client; + } + + /** + * Returns the last response returned from Graph. + * + * @return FacebookResponse|FacebookBatchResponse|null + */ + public function getLastResponse() + { + return $this->lastResponse; + } + + /** + * Returns the URL detection handler. + * + * @return UrlDetectionInterface + */ + public function getUrlDetectionHandler() + { + return $this->urlDetectionHandler; + } + + /** + * Changes the URL detection handler. + * + * @param UrlDetectionInterface $urlDetectionHandler + */ + private function setUrlDetectionHandler(UrlDetectionInterface $urlDetectionHandler) + { + $this->urlDetectionHandler = $urlDetectionHandler; + } + + /** + * Returns the default AccessToken entity. + * + * @return AccessToken|null + */ + public function getDefaultAccessToken() + { + return $this->defaultAccessToken; + } + + /** + * Sets the default access token to use with requests. + * + * @param AccessToken|string $accessToken The access token to save. + * + * @throws \InvalidArgumentException + */ + public function setDefaultAccessToken($accessToken) + { + if (is_string($accessToken)) { + $this->defaultAccessToken = new AccessToken($accessToken); + + return; + } + + if ($accessToken instanceof AccessToken) { + $this->defaultAccessToken = $accessToken; + + return; + } + + throw new \InvalidArgumentException('The default access token must be of type "string" or Facebook\AccessToken'); + } + + /** + * Returns the default Graph version. + * + * @return string + */ + public function getDefaultGraphVersion() + { + return $this->defaultGraphVersion; + } + + /** + * Returns the redirect login helper. + * + * @return FacebookRedirectLoginHelper + */ + public function getRedirectLoginHelper() + { + return new FacebookRedirectLoginHelper( + $this->getOAuth2Client(), + $this->persistentDataHandler, + $this->urlDetectionHandler, + $this->pseudoRandomStringGenerator + ); + } + + /** + * Returns the JavaScript helper. + * + * @return FacebookJavaScriptHelper + */ + public function getJavaScriptHelper() + { + return new FacebookJavaScriptHelper($this->app, $this->client, $this->defaultGraphVersion); + } + + /** + * Returns the canvas helper. + * + * @return FacebookCanvasHelper + */ + public function getCanvasHelper() + { + return new FacebookCanvasHelper($this->app, $this->client, $this->defaultGraphVersion); + } + + /** + * Returns the page tab helper. + * + * @return FacebookPageTabHelper + */ + public function getPageTabHelper() + { + return new FacebookPageTabHelper($this->app, $this->client, $this->defaultGraphVersion); + } + + /** + * Sends a GET request to Graph and returns the result. + * + * @param string $endpoint + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function get($endpoint, $accessToken = null, $eTag = null, $graphVersion = null) + { + return $this->sendRequest( + 'GET', + $endpoint, + $params = [], + $accessToken, + $eTag, + $graphVersion + ); + } + + /** + * Sends a POST request to Graph and returns the result. + * + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function post($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + { + return $this->sendRequest( + 'POST', + $endpoint, + $params, + $accessToken, + $eTag, + $graphVersion + ); + } + + /** + * Sends a DELETE request to Graph and returns the result. + * + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function delete($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + { + return $this->sendRequest( + 'DELETE', + $endpoint, + $params, + $accessToken, + $eTag, + $graphVersion + ); + } + + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphEdge $graphEdge The GraphEdge to paginate over. + * + * @return GraphEdge|null + * + * @throws FacebookSDKException + */ + public function next(GraphEdge $graphEdge) + { + return $this->getPaginationResults($graphEdge, 'next'); + } + + /** + * Sends a request to Graph for the previous page of results. + * + * @param GraphEdge $graphEdge The GraphEdge to paginate over. + * + * @return GraphEdge|null + * + * @throws FacebookSDKException + */ + public function previous(GraphEdge $graphEdge) + { + return $this->getPaginationResults($graphEdge, 'previous'); + } + + /** + * Sends a request to Graph for the next page of results. + * + * @param GraphEdge $graphEdge The GraphEdge to paginate over. + * @param string $direction The direction of the pagination: next|previous. + * + * @return GraphEdge|null + * + * @throws FacebookSDKException + */ + public function getPaginationResults(GraphEdge $graphEdge, $direction) + { + $paginationRequest = $graphEdge->getPaginationRequest($direction); + if (!$paginationRequest) { + return null; + } + + $this->lastResponse = $this->client->sendRequest($paginationRequest); + + // Keep the same GraphNode subclass + $subClassName = $graphEdge->getSubClassName(); + $graphEdge = $this->lastResponse->getGraphEdge($subClassName, false); + + return count($graphEdge) > 0 ? $graphEdge : null; + } + + /** + * Sends a request to Graph and returns the result. + * + * @param string $method + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function sendRequest($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + $request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); + + return $this->lastResponse = $this->client->sendRequest($request); + } + + /** + * Sends a batched request to Graph and returns the result. + * + * @param array $requests + * @param AccessToken|string|null $accessToken + * @param string|null $graphVersion + * + * @return FacebookBatchResponse + * + * @throws FacebookSDKException + */ + public function sendBatchRequest(array $requests, $accessToken = null, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + $batchRequest = new FacebookBatchRequest( + $this->app, + $requests, + $accessToken, + $graphVersion + ); + + return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); + } + + /** + * Instantiates an empty FacebookBatchRequest entity. + * + * @param AccessToken|string|null $accessToken The top-level access token. Requests with no access token + * will fallback to this. + * @param string|null $graphVersion The Graph API version to use. + * @return FacebookBatchRequest + */ + public function newBatchRequest($accessToken = null, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + + return new FacebookBatchRequest( + $this->app, + [], + $accessToken, + $graphVersion + ); + } + + /** + * Instantiates a new FacebookRequest entity. + * + * @param string $method + * @param string $endpoint + * @param array $params + * @param AccessToken|string|null $accessToken + * @param string|null $eTag + * @param string|null $graphVersion + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function request($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + + return new FacebookRequest( + $this->app, + $accessToken, + $method, + $endpoint, + $params, + $eTag, + $graphVersion + ); + } + + /** + * Factory to create FacebookFile's. + * + * @param string $pathToFile + * + * @return FacebookFile + * + * @throws FacebookSDKException + */ + public function fileToUpload($pathToFile) + { + return new FacebookFile($pathToFile); + } + + /** + * Factory to create FacebookVideo's. + * + * @param string $pathToFile + * + * @return FacebookVideo + * + * @throws FacebookSDKException + */ + public function videoToUpload($pathToFile) + { + return new FacebookVideo($pathToFile); + } + + /** + * Upload a video in chunks. + * + * @param int $target The id of the target node before the /videos edge. + * @param string $pathToFile The full path to the file. + * @param array $metadata The metadata associated with the video file. + * @param string|null $accessToken The access token. + * @param int $maxTransferTries The max times to retry a failed upload chunk. + * @param string|null $graphVersion The Graph API version to use. + * + * @return array + * + * @throws FacebookSDKException + */ + public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken = null, $maxTransferTries = 5, $graphVersion = null) + { + $accessToken = $accessToken ?: $this->defaultAccessToken; + $graphVersion = $graphVersion ?: $this->defaultGraphVersion; + + $uploader = new FacebookResumableUploader($this->app, $this->client, $accessToken, $graphVersion); + $endpoint = '/'.$target.'/videos'; + $file = $this->videoToUpload($pathToFile); + $chunk = $uploader->start($endpoint, $file); + + do { + $chunk = $this->maxTriesTransfer($uploader, $endpoint, $chunk, $maxTransferTries); + } while (!$chunk->isLastChunk()); + + return [ + 'video_id' => $chunk->getVideoId(), + 'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId(), $metadata), + ]; + } + + /** + * Attempts to upload a chunk of a file in $retryCountdown tries. + * + * @param FacebookResumableUploader $uploader + * @param string $endpoint + * @param FacebookTransferChunk $chunk + * @param int $retryCountdown + * + * @return FacebookTransferChunk + * + * @throws FacebookSDKException + */ + private function maxTriesTransfer(FacebookResumableUploader $uploader, $endpoint, FacebookTransferChunk $chunk, $retryCountdown) + { + $newChunk = $uploader->transfer($endpoint, $chunk, $retryCountdown < 1); + + if ($newChunk !== $chunk) { + return $newChunk; + } + + $retryCountdown--; + + // If transfer() returned the same chunk entity, the transfer failed but is resumable. + return $this->maxTriesTransfer($uploader, $endpoint, $chunk, $retryCountdown); + } +} diff --git a/inc/vendors/social-login/Facebook/FacebookApp.php b/inc/vendors/social-login/Facebook/FacebookApp.php new file mode 100755 index 00000000..804c9bb5 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FacebookApp.php @@ -0,0 +1,110 @@ +id = (string) $id; + $this->secret = $secret; + } + + /** + * Returns the app ID. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Returns the app secret. + * + * @return string + */ + public function getSecret() + { + return $this->secret; + } + + /** + * Returns an app access token. + * + * @return AccessToken + */ + public function getAccessToken() + { + return new AccessToken($this->id . '|' . $this->secret); + } + + /** + * Serializes the FacebookApp entity as a string. + * + * @return string + */ + public function serialize() + { + return implode('|', [$this->id, $this->secret]); + } + + /** + * Unserializes a string as a FacebookApp entity. + * + * @param string $serialized + */ + public function unserialize($serialized) + { + list($id, $secret) = explode('|', $serialized); + + $this->__construct($id, $secret); + } +} diff --git a/inc/vendors/social-login/Facebook/FacebookBatchRequest.php b/inc/vendors/social-login/Facebook/FacebookBatchRequest.php new file mode 100755 index 00000000..9297e77d --- /dev/null +++ b/inc/vendors/social-login/Facebook/FacebookBatchRequest.php @@ -0,0 +1,322 @@ +add($requests); + } + + /** + * Adds a new request to the array. + * + * @param FacebookRequest|array $request + * @param string|null|array $options Array of batch request options e.g. 'name', 'omit_response_on_success'. + * If a string is given, it is the value of the 'name' option. + * + * @return FacebookBatchRequest + * + * @throws \InvalidArgumentException + */ + public function add($request, $options = null) + { + if (is_array($request)) { + foreach ($request as $key => $req) { + $this->add($req, $key); + } + + return $this; + } + + if (!$request instanceof FacebookRequest) { + throw new \InvalidArgumentException('Argument for add() must be of type array or FacebookRequest.'); + } + + if (null === $options) { + $options = []; + } elseif (!is_array($options)) { + $options = ['name' => $options]; + } + + $this->addFallbackDefaults($request); + + // File uploads + $attachedFiles = $this->extractFileAttachments($request); + + $name = isset($options['name']) ? $options['name'] : null; + + unset($options['name']); + + $requestToAdd = [ + 'name' => $name, + 'request' => $request, + 'options' => $options, + 'attached_files' => $attachedFiles, + ]; + + $this->requests[] = $requestToAdd; + + return $this; + } + + /** + * Ensures that the FacebookApp and access token fall back when missing. + * + * @param FacebookRequest $request + * + * @throws FacebookSDKException + */ + public function addFallbackDefaults(FacebookRequest $request) + { + if (!$request->getApp()) { + $app = $this->getApp(); + if (!$app) { + throw new FacebookSDKException('Missing FacebookApp on FacebookRequest and no fallback detected on FacebookBatchRequest.'); + } + $request->setApp($app); + } + + if (!$request->getAccessToken()) { + $accessToken = $this->getAccessToken(); + if (!$accessToken) { + throw new FacebookSDKException('Missing access token on FacebookRequest and no fallback detected on FacebookBatchRequest.'); + } + $request->setAccessToken($accessToken); + } + } + + /** + * Extracts the files from a request. + * + * @param FacebookRequest $request + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function extractFileAttachments(FacebookRequest $request) + { + if (!$request->containsFileUploads()) { + return null; + } + + $files = $request->getFiles(); + $fileNames = []; + foreach ($files as $file) { + $fileName = uniqid(); + $this->addFile($fileName, $file); + $fileNames[] = $fileName; + } + + $request->resetFiles(); + + // @TODO Does Graph support multiple uploads on one endpoint? + return implode(',', $fileNames); + } + + /** + * Return the FacebookRequest entities. + * + * @return array + */ + public function getRequests() + { + return $this->requests; + } + + /** + * Prepares the requests to be sent as a batch request. + */ + public function prepareRequestsForBatch() + { + $this->validateBatchRequestCount(); + + $params = [ + 'batch' => $this->convertRequestsToJson(), + 'include_headers' => true, + ]; + $this->setParams($params); + } + + /** + * Converts the requests into a JSON(P) string. + * + * @return string + */ + public function convertRequestsToJson() + { + $requests = []; + foreach ($this->requests as $request) { + $options = []; + + if (null !== $request['name']) { + $options['name'] = $request['name']; + } + + $options += $request['options']; + + $requests[] = $this->requestEntityToBatchArray($request['request'], $options, $request['attached_files']); + } + + return json_encode($requests); + } + + /** + * Validate the request count before sending them as a batch. + * + * @throws FacebookSDKException + */ + public function validateBatchRequestCount() + { + $batchCount = count($this->requests); + if ($batchCount === 0) { + throw new FacebookSDKException('There are no batch requests to send.'); + } elseif ($batchCount > 50) { + // Per: https://developers.facebook.com/docs/graph-api/making-multiple-requests#limits + throw new FacebookSDKException('You cannot send more than 50 batch requests at a time.'); + } + } + + /** + * Converts a Request entity into an array that is batch-friendly. + * + * @param FacebookRequest $request The request entity to convert. + * @param string|null|array $options Array of batch request options e.g. 'name', 'omit_response_on_success'. + * If a string is given, it is the value of the 'name' option. + * @param string|null $attachedFiles Names of files associated with the request. + * + * @return array + */ + public function requestEntityToBatchArray(FacebookRequest $request, $options = null, $attachedFiles = null) + { + + if (null === $options) { + $options = []; + } elseif (!is_array($options)) { + $options = ['name' => $options]; + } + + $compiledHeaders = []; + $headers = $request->getHeaders(); + foreach ($headers as $name => $value) { + $compiledHeaders[] = $name . ': ' . $value; + } + + $batch = [ + 'headers' => $compiledHeaders, + 'method' => $request->getMethod(), + 'relative_url' => $request->getUrl(), + ]; + + // Since file uploads are moved to the root request of a batch request, + // the child requests will always be URL-encoded. + $body = $request->getUrlEncodedBody()->getBody(); + if ($body) { + $batch['body'] = $body; + } + + $batch += $options; + + if (null !== $attachedFiles) { + $batch['attached_files'] = $attachedFiles; + } + + return $batch; + } + + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->requests); + } + + /** + * @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->add($value, $offset); + } + + /** + * @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->requests[$offset]); + } + + /** + * @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->requests[$offset]); + } + + /** + * @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->requests[$offset]) ? $this->requests[$offset] : null; + } +} diff --git a/inc/vendors/social-login/Facebook/FacebookBatchResponse.php b/inc/vendors/social-login/Facebook/FacebookBatchResponse.php new file mode 100755 index 00000000..8e1464c9 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FacebookBatchResponse.php @@ -0,0 +1,174 @@ +batchRequest = $batchRequest; + + $request = $response->getRequest(); + $body = $response->getBody(); + $httpStatusCode = $response->getHttpStatusCode(); + $headers = $response->getHeaders(); + parent::__construct($request, $body, $httpStatusCode, $headers); + + $responses = $response->getDecodedBody(); + $this->setResponses($responses); + } + + /** + * Returns an array of FacebookResponse entities. + * + * @return array + */ + public function getResponses() + { + return $this->responses; + } + + /** + * The main batch response will be an array of requests so + * we need to iterate over all the responses. + * + * @param array $responses + */ + public function setResponses(array $responses) + { + $this->responses = []; + + foreach ($responses as $key => $graphResponse) { + $this->addResponse($key, $graphResponse); + } + } + + /** + * Add a response to the list. + * + * @param int $key + * @param array|null $response + */ + public function addResponse($key, $response) + { + $originalRequestName = isset($this->batchRequest[$key]['name']) ? $this->batchRequest[$key]['name'] : $key; + $originalRequest = isset($this->batchRequest[$key]['request']) ? $this->batchRequest[$key]['request'] : null; + + $httpResponseBody = isset($response['body']) ? $response['body'] : null; + $httpResponseCode = isset($response['code']) ? $response['code'] : null; + // @TODO With PHP 5.5 support, this becomes array_column($response['headers'], 'value', 'name') + $httpResponseHeaders = isset($response['headers']) ? $this->normalizeBatchHeaders($response['headers']) : []; + + $this->responses[$originalRequestName] = new FacebookResponse( + $originalRequest, + $httpResponseBody, + $httpResponseCode, + $httpResponseHeaders + ); + } + + /** + * @inheritdoc + */ + public function getIterator() + { + return new ArrayIterator($this->responses); + } + + /** + * @inheritdoc + */ + public function offsetSet($offset, $value) + { + $this->addResponse($offset, $value); + } + + /** + * @inheritdoc + */ + public function offsetExists($offset) + { + return isset($this->responses[$offset]); + } + + /** + * @inheritdoc + */ + public function offsetUnset($offset) + { + unset($this->responses[$offset]); + } + + /** + * @inheritdoc + */ + public function offsetGet($offset) + { + return isset($this->responses[$offset]) ? $this->responses[$offset] : null; + } + + /** + * Converts the batch header array into a standard format. + * @TODO replace with array_column() when PHP 5.5 is supported. + * + * @param array $batchHeaders + * + * @return array + */ + private function normalizeBatchHeaders(array $batchHeaders) + { + $headers = []; + + foreach ($batchHeaders as $header) { + $headers[$header['name']] = $header['value']; + } + + return $headers; + } +} diff --git a/inc/vendors/social-login/Facebook/FacebookClient.php b/inc/vendors/social-login/Facebook/FacebookClient.php new file mode 100755 index 00000000..dbf75923 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FacebookClient.php @@ -0,0 +1,250 @@ +httpClientHandler = $httpClientHandler ?: $this->detectHttpClientHandler(); + $this->enableBetaMode = $enableBeta; + } + + /** + * Sets the HTTP client handler. + * + * @param FacebookHttpClientInterface $httpClientHandler + */ + public function setHttpClientHandler(FacebookHttpClientInterface $httpClientHandler) + { + $this->httpClientHandler = $httpClientHandler; + } + + /** + * Returns the HTTP client handler. + * + * @return FacebookHttpClientInterface + */ + public function getHttpClientHandler() + { + return $this->httpClientHandler; + } + + /** + * Detects which HTTP client handler to use. + * + * @return FacebookHttpClientInterface + */ + public function detectHttpClientHandler() + { + return extension_loaded('curl') ? new FacebookCurlHttpClient() : new FacebookStreamHttpClient(); + } + + /** + * Toggle beta mode. + * + * @param boolean $betaMode + */ + public function enableBetaMode($betaMode = true) + { + $this->enableBetaMode = $betaMode; + } + + /** + * Returns the base Graph URL. + * + * @param boolean $postToVideoUrl Post to the video API if videos are being uploaded. + * + * @return string + */ + public function getBaseGraphUrl($postToVideoUrl = false) + { + if ($postToVideoUrl) { + return $this->enableBetaMode ? static::BASE_GRAPH_VIDEO_URL_BETA : static::BASE_GRAPH_VIDEO_URL; + } + + return $this->enableBetaMode ? static::BASE_GRAPH_URL_BETA : static::BASE_GRAPH_URL; + } + + /** + * Prepares the request for sending to the client handler. + * + * @param FacebookRequest $request + * + * @return array + */ + public function prepareRequestMessage(FacebookRequest $request) + { + $postToVideoUrl = $request->containsVideoUploads(); + $url = $this->getBaseGraphUrl($postToVideoUrl) . $request->getUrl(); + + // If we're sending files they should be sent as multipart/form-data + if ($request->containsFileUploads()) { + $requestBody = $request->getMultipartBody(); + $request->setHeaders([ + 'Content-Type' => 'multipart/form-data; boundary=' . $requestBody->getBoundary(), + ]); + } else { + $requestBody = $request->getUrlEncodedBody(); + $request->setHeaders([ + 'Content-Type' => 'application/x-www-form-urlencoded', + ]); + } + + return [ + $url, + $request->getMethod(), + $request->getHeaders(), + $requestBody->getBody(), + ]; + } + + /** + * Makes the request to Graph and returns the result. + * + * @param FacebookRequest $request + * + * @return FacebookResponse + * + * @throws FacebookSDKException + */ + public function sendRequest(FacebookRequest $request) + { + if (get_class($request) === 'Facebook\FacebookRequest') { + $request->validateAccessToken(); + } + + list($url, $method, $headers, $body) = $this->prepareRequestMessage($request); + + // Since file uploads can take a while, we need to give more time for uploads + $timeOut = static::DEFAULT_REQUEST_TIMEOUT; + if ($request->containsFileUploads()) { + $timeOut = static::DEFAULT_FILE_UPLOAD_REQUEST_TIMEOUT; + } elseif ($request->containsVideoUploads()) { + $timeOut = static::DEFAULT_VIDEO_UPLOAD_REQUEST_TIMEOUT; + } + + // Should throw `FacebookSDKException` exception on HTTP client error. + // Don't catch to allow it to bubble up. + $rawResponse = $this->httpClientHandler->send($url, $method, $body, $headers, $timeOut); + + static::$requestCount++; + + $returnResponse = new FacebookResponse( + $request, + $rawResponse->getBody(), + $rawResponse->getHttpResponseCode(), + $rawResponse->getHeaders() + ); + + if ($returnResponse->isError()) { + throw $returnResponse->getThrownException(); + } + + return $returnResponse; + } + + /** + * Makes a batched request to Graph and returns the result. + * + * @param FacebookBatchRequest $request + * + * @return FacebookBatchResponse + * + * @throws FacebookSDKException + */ + public function sendBatchRequest(FacebookBatchRequest $request) + { + $request->prepareRequestsForBatch(); + $facebookResponse = $this->sendRequest($request); + + return new FacebookBatchResponse($request, $facebookResponse); + } +} diff --git a/inc/vendors/social-login/Facebook/FacebookRequest.php b/inc/vendors/social-login/Facebook/FacebookRequest.php new file mode 100755 index 00000000..2b100899 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FacebookRequest.php @@ -0,0 +1,534 @@ +setApp($app); + $this->setAccessToken($accessToken); + $this->setMethod($method); + $this->setEndpoint($endpoint); + $this->setParams($params); + $this->setETag($eTag); + $this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; + } + + /** + * Set the access token for this request. + * + * @param AccessToken|string|null + * + * @return FacebookRequest + */ + public function setAccessToken($accessToken) + { + $this->accessToken = $accessToken; + if ($accessToken instanceof AccessToken) { + $this->accessToken = $accessToken->getValue(); + } + + return $this; + } + + /** + * Sets the access token with one harvested from a URL or POST params. + * + * @param string $accessToken The access token. + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setAccessTokenFromParams($accessToken) + { + $existingAccessToken = $this->getAccessToken(); + if (!$existingAccessToken) { + $this->setAccessToken($accessToken); + } elseif ($accessToken !== $existingAccessToken) { + throw new FacebookSDKException('Access token mismatch. The access token provided in the FacebookRequest and the one provided in the URL or POST params do not match.'); + } + + return $this; + } + + /** + * Return the access token for this request. + * + * @return string|null + */ + public function getAccessToken() + { + return $this->accessToken; + } + + /** + * Return the access token for this request as an AccessToken entity. + * + * @return AccessToken|null + */ + public function getAccessTokenEntity() + { + return $this->accessToken ? new AccessToken($this->accessToken) : null; + } + + /** + * Set the FacebookApp entity used for this request. + * + * @param FacebookApp|null $app + */ + public function setApp(FacebookApp $app = null) + { + $this->app = $app; + } + + /** + * Return the FacebookApp entity used for this request. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->app; + } + + /** + * Generate an app secret proof to sign this request. + * + * @return string|null + */ + public function getAppSecretProof() + { + if (!$accessTokenEntity = $this->getAccessTokenEntity()) { + return null; + } + + return $accessTokenEntity->getAppSecretProof($this->app->getSecret()); + } + + /** + * Validate that an access token exists for this request. + * + * @throws FacebookSDKException + */ + public function validateAccessToken() + { + $accessToken = $this->getAccessToken(); + if (!$accessToken) { + throw new FacebookSDKException('You must provide an access token.'); + } + } + + /** + * Set the HTTP method for this request. + * + * @param string + */ + public function setMethod($method) + { + $this->method = strtoupper($method); + } + + /** + * Return the HTTP method for this request. + * + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Validate that the HTTP method is set. + * + * @throws FacebookSDKException + */ + public function validateMethod() + { + if (!$this->method) { + throw new FacebookSDKException('HTTP method not specified.'); + } + + if (!in_array($this->method, ['GET', 'POST', 'DELETE'])) { + throw new FacebookSDKException('Invalid HTTP method specified.'); + } + } + + /** + * Set the endpoint for this request. + * + * @param string + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setEndpoint($endpoint) + { + // Harvest the access token from the endpoint to keep things in sync + $params = FacebookUrlManipulator::getParamsAsArray($endpoint); + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); + } + + // Clean the token & app secret proof from the endpoint. + $filterParams = ['access_token', 'appsecret_proof']; + $this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint, $filterParams); + + return $this; + } + + /** + * Return the endpoint for this request. + * + * @return string + */ + public function getEndpoint() + { + // For batch requests, this will be empty + return $this->endpoint; + } + + /** + * Generate and return the headers for this request. + * + * @return array + */ + public function getHeaders() + { + $headers = static::getDefaultHeaders(); + + if ($this->eTag) { + $headers['If-None-Match'] = $this->eTag; + } + + return array_merge($this->headers, $headers); + } + + /** + * Set the headers for this request. + * + * @param array $headers + */ + public function setHeaders(array $headers) + { + $this->headers = array_merge($this->headers, $headers); + } + + /** + * Sets the eTag value. + * + * @param string $eTag + */ + public function setETag($eTag) + { + $this->eTag = $eTag; + } + + /** + * Set the params for this request. + * + * @param array $params + * + * @return FacebookRequest + * + * @throws FacebookSDKException + */ + public function setParams(array $params = []) + { + if (isset($params['access_token'])) { + $this->setAccessTokenFromParams($params['access_token']); + } + + // Don't let these buggers slip in. + unset($params['access_token'], $params['appsecret_proof']); + + // @TODO Refactor code above with this + //$params = $this->sanitizeAuthenticationParams($params); + $params = $this->sanitizeFileParams($params); + $this->dangerouslySetParams($params); + + return $this; + } + + /** + * Set the params for this request without filtering them first. + * + * @param array $params + * + * @return FacebookRequest + */ + public function dangerouslySetParams(array $params = []) + { + $this->params = array_merge($this->params, $params); + + return $this; + } + + /** + * Iterate over the params and pull out the file uploads. + * + * @param array $params + * + * @return array + */ + public function sanitizeFileParams(array $params) + { + foreach ($params as $key => $value) { + if ($value instanceof FacebookFile) { + $this->addFile($key, $value); + unset($params[$key]); + } + } + + return $params; + } + + /** + * Add a file to be uploaded. + * + * @param string $key + * @param FacebookFile $file + */ + public function addFile($key, FacebookFile $file) + { + $this->files[$key] = $file; + } + + /** + * Removes all the files from the upload queue. + */ + public function resetFiles() + { + $this->files = []; + } + + /** + * Get the list of files to be uploaded. + * + * @return array + */ + public function getFiles() + { + return $this->files; + } + + /** + * Let's us know if there is a file upload with this request. + * + * @return boolean + */ + public function containsFileUploads() + { + return !empty($this->files); + } + + /** + * Let's us know if there is a video upload with this request. + * + * @return boolean + */ + public function containsVideoUploads() + { + foreach ($this->files as $file) { + if ($file instanceof FacebookVideo) { + return true; + } + } + + return false; + } + + /** + * Returns the body of the request as multipart/form-data. + * + * @return RequestBodyMultipart + */ + public function getMultipartBody() + { + $params = $this->getPostParams(); + + return new RequestBodyMultipart($params, $this->files); + } + + /** + * Returns the body of the request as URL-encoded. + * + * @return RequestBodyUrlEncoded + */ + public function getUrlEncodedBody() + { + $params = $this->getPostParams(); + + return new RequestBodyUrlEncoded($params); + } + + /** + * Generate and return the params for this request. + * + * @return array + */ + public function getParams() + { + $params = $this->params; + + $accessToken = $this->getAccessToken(); + if ($accessToken) { + $params['access_token'] = $accessToken; + $params['appsecret_proof'] = $this->getAppSecretProof(); + } + + return $params; + } + + /** + * Only return params on POST requests. + * + * @return array + */ + public function getPostParams() + { + if ($this->getMethod() === 'POST') { + return $this->getParams(); + } + + return []; + } + + /** + * The graph version used for this request. + * + * @return string + */ + public function getGraphVersion() + { + return $this->graphVersion; + } + + /** + * Generate and return the URL for this request. + * + * @return string + */ + public function getUrl() + { + $this->validateMethod(); + + $graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion); + $endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint()); + + $url = $graphVersion . $endpoint; + + if ($this->getMethod() !== 'POST') { + $params = $this->getParams(); + $url = FacebookUrlManipulator::appendParamsToUrl($url, $params); + } + + return $url; + } + + /** + * Return the default headers that every request should use. + * + * @return array + */ + public static function getDefaultHeaders() + { + return [ + 'User-Agent' => 'fb-php-' . Facebook::VERSION, + 'Accept-Encoding' => '*', + ]; + } +} diff --git a/inc/vendors/social-login/Facebook/FacebookResponse.php b/inc/vendors/social-login/Facebook/FacebookResponse.php new file mode 100755 index 00000000..251ca2f7 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FacebookResponse.php @@ -0,0 +1,410 @@ +request = $request; + $this->body = $body; + $this->httpStatusCode = $httpStatusCode; + $this->headers = $headers; + + $this->decodeBody(); + } + + /** + * Return the original request that returned this response. + * + * @return FacebookRequest + */ + public function getRequest() + { + return $this->request; + } + + /** + * Return the FacebookApp entity used for this response. + * + * @return FacebookApp + */ + public function getApp() + { + return $this->request->getApp(); + } + + /** + * Return the access token that was used for this response. + * + * @return string|null + */ + public function getAccessToken() + { + return $this->request->getAccessToken(); + } + + /** + * Return the HTTP status code for this response. + * + * @return int + */ + public function getHttpStatusCode() + { + return $this->httpStatusCode; + } + + /** + * Return the HTTP headers for this response. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Return the raw body response. + * + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * Return the decoded body response. + * + * @return array + */ + public function getDecodedBody() + { + return $this->decodedBody; + } + + /** + * Get the app secret proof that was used for this response. + * + * @return string|null + */ + public function getAppSecretProof() + { + return $this->request->getAppSecretProof(); + } + + /** + * Get the ETag associated with the response. + * + * @return string|null + */ + public function getETag() + { + return isset($this->headers['ETag']) ? $this->headers['ETag'] : null; + } + + /** + * Get the version of Graph that returned this response. + * + * @return string|null + */ + public function getGraphVersion() + { + return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-Version'] : null; + } + + /** + * Returns true if Graph returned an error message. + * + * @return boolean + */ + public function isError() + { + return isset($this->decodedBody['error']); + } + + /** + * Throws the exception. + * + * @throws FacebookSDKException + */ + public function throwException() + { + throw $this->thrownException; + } + + /** + * Instantiates an exception to be thrown later. + */ + public function makeException() + { + $this->thrownException = FacebookResponseException::create($this); + } + + /** + * Returns the exception that was thrown for this request. + * + * @return FacebookResponseException|null + */ + public function getThrownException() + { + return $this->thrownException; + } + + /** + * Convert the raw response into an array if possible. + * + * Graph will return 2 types of responses: + * - JSON(P) + * Most responses from Graph are JSON(P) + * - application/x-www-form-urlencoded key/value pairs + * Happens on the `/oauth/access_token` endpoint when exchanging + * a short-lived access token for a long-lived access token + * - And sometimes nothing :/ but that'd be a bug. + */ + public function decodeBody() + { + $this->decodedBody = json_decode($this->body, true); + + if ($this->decodedBody === null) { + $this->decodedBody = []; + parse_str($this->body, $this->decodedBody); + } elseif (is_bool($this->decodedBody)) { + // Backwards compatibility for Graph < 2.1. + // Mimics 2.1 responses. + // @TODO Remove this after Graph 2.0 is no longer supported + $this->decodedBody = ['success' => $this->decodedBody]; + } elseif (is_numeric($this->decodedBody)) { + $this->decodedBody = ['id' => $this->decodedBody]; + } + + if (!is_array($this->decodedBody)) { + $this->decodedBody = []; + } + + if ($this->isError()) { + $this->makeException(); + } + } + + /** + * Instantiate a new GraphObject from response. + * + * @param string|null $subclassName The GraphNode subclass to cast to. + * + * @return \Facebook\GraphNodes\GraphObject + * + * @throws FacebookSDKException + * + * @deprecated 5.0.0 getGraphObject() has been renamed to getGraphNode() + * @todo v6: Remove this method + */ + public function getGraphObject($subclassName = null) + { + return $this->getGraphNode($subclassName); + } + + /** + * Instantiate a new GraphNode from response. + * + * @param string|null $subclassName The GraphNode subclass to cast to. + * + * @return \Facebook\GraphNodes\GraphNode + * + * @throws FacebookSDKException + */ + public function getGraphNode($subclassName = null) + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphNode($subclassName); + } + + /** + * Convenience method for creating a GraphAlbum collection. + * + * @return \Facebook\GraphNodes\GraphAlbum + * + * @throws FacebookSDKException + */ + public function getGraphAlbum() + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphAlbum(); + } + + /** + * Convenience method for creating a GraphPage collection. + * + * @return \Facebook\GraphNodes\GraphPage + * + * @throws FacebookSDKException + */ + public function getGraphPage() + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphPage(); + } + + /** + * Convenience method for creating a GraphSessionInfo collection. + * + * @return \Facebook\GraphNodes\GraphSessionInfo + * + * @throws FacebookSDKException + */ + public function getGraphSessionInfo() + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphSessionInfo(); + } + + /** + * Convenience method for creating a GraphUser collection. + * + * @return \Facebook\GraphNodes\GraphUser + * + * @throws FacebookSDKException + */ + public function getGraphUser() + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphUser(); + } + + /** + * Convenience method for creating a GraphEvent collection. + * + * @return \Facebook\GraphNodes\GraphEvent + * + * @throws FacebookSDKException + */ + public function getGraphEvent() + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphEvent(); + } + + /** + * Convenience method for creating a GraphGroup collection. + * + * @return \Facebook\GraphNodes\GraphGroup + * + * @throws FacebookSDKException + */ + public function getGraphGroup() + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphGroup(); + } + + /** + * Instantiate a new GraphList from response. + * + * @param string|null $subclassName The GraphNode subclass to cast list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return \Facebook\GraphNodes\GraphList + * + * @throws FacebookSDKException + * + * @deprecated 5.0.0 getGraphList() has been renamed to getGraphEdge() + * @todo v6: Remove this method + */ + public function getGraphList($subclassName = null, $auto_prefix = true) + { + return $this->getGraphEdge($subclassName, $auto_prefix); + } + + /** + * Instantiate a new GraphEdge from response. + * + * @param string|null $subclassName The GraphNode subclass to cast list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return \Facebook\GraphNodes\GraphEdge + * + * @throws FacebookSDKException + */ + public function getGraphEdge($subclassName = null, $auto_prefix = true) + { + $factory = new GraphNodeFactory($this); + + return $factory->makeGraphEdge($subclassName, $auto_prefix); + } +} diff --git a/inc/vendors/social-login/Facebook/FileUpload/FacebookFile.php b/inc/vendors/social-login/Facebook/FileUpload/FacebookFile.php new file mode 100755 index 00000000..3c1536d4 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FileUpload/FacebookFile.php @@ -0,0 +1,169 @@ +path = $filePath; + $this->maxLength = $maxLength; + $this->offset = $offset; + $this->open(); + } + + /** + * Closes the stream when destructed. + */ + public function __destruct() + { + $this->close(); + } + + /** + * Opens a stream for the file. + * + * @throws FacebookSDKException + */ + public function open() + { + if (!$this->isRemoteFile($this->path) && !is_readable($this->path)) { + throw new FacebookSDKException('Failed to create FacebookFile entity. Unable to read resource: ' . $this->path . '.'); + } + + $this->stream = fopen($this->path, 'r'); + + if (!$this->stream) { + throw new FacebookSDKException('Failed to create FacebookFile entity. Unable to open resource: ' . $this->path . '.'); + } + } + + /** + * Stops the file stream. + */ + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + } + + /** + * Return the contents of the file. + * + * @return string + */ + public function getContents() + { + return stream_get_contents($this->stream, $this->maxLength, $this->offset); + } + + /** + * Return the name of the file. + * + * @return string + */ + public function getFileName() + { + return basename($this->path); + } + + /** + * Return the path of the file. + * + * @return string + */ + public function getFilePath() + { + return $this->path; + } + + /** + * Return the size of the file. + * + * @return int + */ + public function getSize() + { + return filesize($this->path); + } + + /** + * Return the mimetype of the file. + * + * @return string + */ + public function getMimetype() + { + return Mimetypes::getInstance()->fromFilename($this->path) ?: 'text/plain'; + } + + /** + * Returns true if the path to the file is remote. + * + * @param string $pathToFile + * + * @return boolean + */ + protected function isRemoteFile($pathToFile) + { + return preg_match('/^(https?|ftp):\/\/.*/', $pathToFile) === 1; + } +} diff --git a/inc/vendors/social-login/Facebook/FileUpload/FacebookResumableUploader.php b/inc/vendors/social-login/Facebook/FileUpload/FacebookResumableUploader.php new file mode 100755 index 00000000..46a2727b --- /dev/null +++ b/inc/vendors/social-login/Facebook/FileUpload/FacebookResumableUploader.php @@ -0,0 +1,177 @@ +app = $app; + $this->client = $client; + $this->accessToken = $accessToken; + $this->graphVersion = $graphVersion; + } + + /** + * Upload by chunks - start phase + * + * @param string $endpoint + * @param FacebookFile $file + * + * @return FacebookTransferChunk + * + * @throws FacebookSDKException + */ + public function start($endpoint, FacebookFile $file) + { + $params = [ + 'upload_phase' => 'start', + 'file_size' => $file->getSize(), + ]; + $response = $this->sendUploadRequest($endpoint, $params); + + return new FacebookTransferChunk($file, $response['upload_session_id'], $response['video_id'], $response['start_offset'], $response['end_offset']); + } + + /** + * Upload by chunks - transfer phase + * + * @param string $endpoint + * @param FacebookTransferChunk $chunk + * @param boolean $allowToThrow + * + * @return FacebookTransferChunk + * + * @throws FacebookResponseException + */ + public function transfer($endpoint, FacebookTransferChunk $chunk, $allowToThrow = false) + { + $params = [ + 'upload_phase' => 'transfer', + 'upload_session_id' => $chunk->getUploadSessionId(), + 'start_offset' => $chunk->getStartOffset(), + 'video_file_chunk' => $chunk->getPartialFile(), + ]; + + try { + $response = $this->sendUploadRequest($endpoint, $params); + } catch (FacebookResponseException $e) { + $preException = $e->getPrevious(); + if ($allowToThrow || !$preException instanceof FacebookResumableUploadException) { + throw $e; + } + + if (null !== $preException->getStartOffset() && null !== $preException->getEndOffset()) { + return new FacebookTransferChunk( + $chunk->getFile(), + $chunk->getUploadSessionId(), + $chunk->getVideoId(), + $preException->getStartOffset(), + $preException->getEndOffset() + ); + } + + // Return the same chunk entity so it can be retried. + return $chunk; + } + + return new FacebookTransferChunk($chunk->getFile(), $chunk->getUploadSessionId(), $chunk->getVideoId(), $response['start_offset'], $response['end_offset']); + } + + /** + * Upload by chunks - finish phase + * + * @param string $endpoint + * @param string $uploadSessionId + * @param array $metadata The metadata associated with the file. + * + * @return boolean + * + * @throws FacebookSDKException + */ + public function finish($endpoint, $uploadSessionId, $metadata = []) + { + $params = array_merge($metadata, [ + 'upload_phase' => 'finish', + 'upload_session_id' => $uploadSessionId, + ]); + $response = $this->sendUploadRequest($endpoint, $params); + + return $response['success']; + } + + /** + * Helper to make a FacebookRequest and send it. + * + * @param string $endpoint The endpoint to POST to. + * @param array $params The params to send with the request. + * + * @return array + */ + private function sendUploadRequest($endpoint, $params = []) + { + $request = new FacebookRequest($this->app, $this->accessToken, 'POST', $endpoint, $params, null, $this->graphVersion); + + return $this->client->sendRequest($request)->getDecodedBody(); + } +} diff --git a/inc/vendors/social-login/Facebook/FileUpload/FacebookTransferChunk.php b/inc/vendors/social-login/Facebook/FileUpload/FacebookTransferChunk.php new file mode 100755 index 00000000..99ea7752 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FileUpload/FacebookTransferChunk.php @@ -0,0 +1,141 @@ +file = $file; + $this->uploadSessionId = $uploadSessionId; + $this->videoId = $videoId; + $this->startOffset = $startOffset; + $this->endOffset = $endOffset; + } + + /** + * Return the file entity. + * + * @return FacebookFile + */ + public function getFile() + { + return $this->file; + } + + /** + * Return a FacebookFile entity with partial content. + * + * @return FacebookFile + */ + public function getPartialFile() + { + $maxLength = $this->endOffset - $this->startOffset; + + return new FacebookFile($this->file->getFilePath(), $maxLength, $this->startOffset); + } + + /** + * Return upload session Id + * + * @return int + */ + public function getUploadSessionId() + { + return $this->uploadSessionId; + } + + /** + * Check whether is the last chunk + * + * @return bool + */ + public function isLastChunk() + { + return $this->startOffset === $this->endOffset; + } + + /** + * @return int + */ + public function getStartOffset() + { + return $this->startOffset; + } + + /** + * @return int + */ + public function getEndOffset() + { + return $this->endOffset; + } + + /** + * Get uploaded video Id + * + * @return int + */ + public function getVideoId() + { + return $this->videoId; + } +} diff --git a/inc/vendors/social-login/Facebook/FileUpload/FacebookVideo.php b/inc/vendors/social-login/Facebook/FileUpload/FacebookVideo.php new file mode 100755 index 00000000..ee6dd538 --- /dev/null +++ b/inc/vendors/social-login/Facebook/FileUpload/FacebookVideo.php @@ -0,0 +1,33 @@ + 'text/vnd.in3d.3dml', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gpp', + '7z' => 'application/x-7z-compressed', + 'aab' => 'application/x-authorware-bin', + 'aac' => 'audio/x-aac', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abw' => 'application/x-abiword', + 'ac' => 'application/pkix-attr-cert', + 'acc' => 'application/vnd.americandynamics.acc', + 'ace' => 'application/x-ace-compressed', + 'acu' => 'application/vnd.acucobol', + 'acutc' => 'application/vnd.acucorp', + 'adp' => 'audio/adpcm', + 'aep' => 'application/vnd.audiograph', + 'afm' => 'application/x-font-type1', + 'afp' => 'application/vnd.ibm.modcap', + 'ahead' => 'application/vnd.ahead.space', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'air' => 'application/vnd.adobe.air-application-installer-package+zip', + 'ait' => 'application/vnd.dvb.ait', + 'ami' => 'application/vnd.amiga.ami', + 'apk' => 'application/vnd.android.package-archive', + 'application' => 'application/x-ms-application', + 'apr' => 'application/vnd.lotus-approach', + 'asa' => 'text/plain', + 'asax' => 'application/octet-stream', + 'asc' => 'application/pgp-signature', + 'ascx' => 'text/plain', + 'asf' => 'video/x-ms-asf', + 'ashx' => 'text/plain', + 'asm' => 'text/x-asm', + 'asmx' => 'text/plain', + 'aso' => 'application/vnd.accpac.simply.aso', + 'asp' => 'text/plain', + 'aspx' => 'text/plain', + 'asx' => 'video/x-ms-asf', + 'atc' => 'application/vnd.acucorp', + 'atom' => 'application/atom+xml', + 'atomcat' => 'application/atomcat+xml', + 'atomsvc' => 'application/atomsvc+xml', + 'atx' => 'application/vnd.antix.game-component', + 'au' => 'audio/basic', + 'avi' => 'video/x-msvideo', + 'aw' => 'application/applixware', + 'axd' => 'text/plain', + 'azf' => 'application/vnd.airzip.filesecure.azf', + 'azs' => 'application/vnd.airzip.filesecure.azs', + 'azw' => 'application/vnd.amazon.ebook', + 'bat' => 'application/x-msdownload', + 'bcpio' => 'application/x-bcpio', + 'bdf' => 'application/x-font-bdf', + 'bdm' => 'application/vnd.syncml.dm+wbxml', + 'bed' => 'application/vnd.realvnc.bed', + 'bh2' => 'application/vnd.fujitsu.oasysprs', + 'bin' => 'application/octet-stream', + 'bmi' => 'application/vnd.bmi', + 'bmp' => 'image/bmp', + 'book' => 'application/vnd.framemaker', + 'box' => 'application/vnd.previewsystems.box', + 'boz' => 'application/x-bzip2', + 'bpk' => 'application/octet-stream', + 'btif' => 'image/prs.btif', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', + 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', + 'c4d' => 'application/vnd.clonk.c4group', + 'c4f' => 'application/vnd.clonk.c4group', + 'c4g' => 'application/vnd.clonk.c4group', + 'c4p' => 'application/vnd.clonk.c4group', + 'c4u' => 'application/vnd.clonk.c4group', + 'cab' => 'application/vnd.ms-cab-compressed', + 'car' => 'application/vnd.curl.car', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cc' => 'text/x-c', + 'cct' => 'application/x-director', + 'ccxml' => 'application/ccxml+xml', + 'cdbcmsg' => 'application/vnd.contact.cmsg', + 'cdf' => 'application/x-netcdf', + 'cdkey' => 'application/vnd.mediastation.cdkey', + 'cdmia' => 'application/cdmi-capability', + 'cdmic' => 'application/cdmi-container', + 'cdmid' => 'application/cdmi-domain', + 'cdmio' => 'application/cdmi-object', + 'cdmiq' => 'application/cdmi-queue', + 'cdx' => 'chemical/x-cdx', + 'cdxml' => 'application/vnd.chemdraw+xml', + 'cdy' => 'application/vnd.cinderella', + 'cer' => 'application/pkix-cert', + 'cfc' => 'application/x-coldfusion', + 'cfm' => 'application/x-coldfusion', + 'cgm' => 'image/cgm', + 'chat' => 'application/x-chat', + 'chm' => 'application/vnd.ms-htmlhelp', + 'chrt' => 'application/vnd.kde.kchart', + 'cif' => 'chemical/x-cif', + 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', + 'cil' => 'application/vnd.ms-artgalry', + 'cla' => 'application/vnd.claymore', + 'class' => 'application/java-vm', + 'clkk' => 'application/vnd.crick.clicker.keyboard', + 'clkp' => 'application/vnd.crick.clicker.palette', + 'clkt' => 'application/vnd.crick.clicker.template', + 'clkw' => 'application/vnd.crick.clicker.wordbank', + 'clkx' => 'application/vnd.crick.clicker', + 'clp' => 'application/x-msclip', + 'cmc' => 'application/vnd.cosmocaller', + 'cmdf' => 'chemical/x-cmdf', + 'cml' => 'chemical/x-cml', + 'cmp' => 'application/vnd.yellowriver-custom-menu', + 'cmx' => 'image/x-cmx', + 'cod' => 'application/vnd.rim.cod', + 'com' => 'application/x-msdownload', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/mac-compactpro', + 'crd' => 'application/x-mscardfile', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'cryptonote' => 'application/vnd.rig.cryptonote', + 'cs' => 'text/plain', + 'csh' => 'application/x-csh', + 'csml' => 'chemical/x-csml', + 'csp' => 'application/vnd.commonspace', + 'css' => 'text/css', + 'cst' => 'application/x-director', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'curl' => 'text/vnd.curl', + 'cww' => 'application/prs.cww', + 'cxt' => 'application/x-director', + 'cxx' => 'text/x-c', + 'dae' => 'model/vnd.collada+xml', + 'daf' => 'application/vnd.mobius.daf', + 'dataless' => 'application/vnd.fdsn.seed', + 'davmount' => 'application/davmount+xml', + 'dcr' => 'application/x-director', + 'dcurl' => 'text/vnd.curl.dcurl', + 'dd2' => 'application/vnd.oma.dd2+xml', + 'ddd' => 'application/vnd.fujixerox.ddd', + 'deb' => 'application/x-debian-package', + 'def' => 'text/plain', + 'deploy' => 'application/octet-stream', + 'der' => 'application/x-x509-ca-cert', + 'dfac' => 'application/vnd.dreamfactory', + 'dic' => 'text/x-c', + 'dir' => 'application/x-director', + 'dis' => 'application/vnd.mobius.dis', + 'dist' => 'application/octet-stream', + 'distz' => 'application/octet-stream', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/x-msdownload', + 'dmg' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'dna' => 'application/vnd.dna', + 'doc' => 'application/msword', + 'docm' => 'application/vnd.ms-word.document.macroenabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot' => 'application/msword', + 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'dp' => 'application/vnd.osgi.dp', + 'dpg' => 'application/vnd.dpgraph', + 'dra' => 'audio/vnd.dra', + 'dsc' => 'text/prs.lines.tag', + 'dssc' => 'application/dssc+der', + 'dtb' => 'application/x-dtbook+xml', + 'dtd' => 'application/xml-dtd', + 'dts' => 'audio/vnd.dts', + 'dtshd' => 'audio/vnd.dts.hd', + 'dump' => 'application/octet-stream', + 'dvi' => 'application/x-dvi', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/vnd.dwg', + 'dxf' => 'image/vnd.dxf', + 'dxp' => 'application/vnd.spotfire.dxp', + 'dxr' => 'application/x-director', + 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', + 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', + 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', + 'ecma' => 'application/ecmascript', + 'edm' => 'application/vnd.novadigm.edm', + 'edx' => 'application/vnd.novadigm.edx', + 'efif' => 'application/vnd.picsel', + 'ei6' => 'application/vnd.pg.osasli', + 'elc' => 'application/octet-stream', + 'eml' => 'message/rfc822', + 'emma' => 'application/emma+xml', + 'eol' => 'audio/vnd.digital-winds', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'es3' => 'application/vnd.eszigno3+xml', + 'esf' => 'application/vnd.epson.esf', + 'et3' => 'application/vnd.eszigno3+xml', + 'etx' => 'text/x-setext', + 'exe' => 'application/x-msdownload', + 'exi' => 'application/exi', + 'ext' => 'application/vnd.novadigm.ext', + 'ez' => 'application/andrew-inset', + 'ez2' => 'application/vnd.ezpix-album', + 'ez3' => 'application/vnd.ezpix-package', + 'f' => 'text/x-fortran', + 'f4v' => 'video/x-f4v', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fbs' => 'image/vnd.fastbidsheet', + 'fcs' => 'application/vnd.isac.fcs', + 'fdf' => 'application/vnd.fdf', + 'fe_launch' => 'application/vnd.denovo.fcselayout-link', + 'fg5' => 'application/vnd.fujitsu.oasysgp', + 'fgd' => 'application/x-director', + 'fh' => 'image/x-freehand', + 'fh4' => 'image/x-freehand', + 'fh5' => 'image/x-freehand', + 'fh7' => 'image/x-freehand', + 'fhc' => 'image/x-freehand', + 'fig' => 'application/x-xfig', + 'fli' => 'video/x-fli', + 'flo' => 'application/vnd.micrografx.flo', + 'flv' => 'video/x-flv', + 'flw' => 'application/vnd.kde.kivio', + 'flx' => 'text/vnd.fmi.flexstor', + 'fly' => 'text/vnd.fly', + 'fm' => 'application/vnd.framemaker', + 'fnc' => 'application/vnd.frogans.fnc', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frame' => 'application/vnd.framemaker', + 'fsc' => 'application/vnd.fsc.weblaunch', + 'fst' => 'image/vnd.fst', + 'ftc' => 'application/vnd.fluxtime.clip', + 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', + 'fvt' => 'video/vnd.fvt', + 'fxp' => 'application/vnd.adobe.fxp', + 'fxpl' => 'application/vnd.adobe.fxp', + 'fzs' => 'application/vnd.fuzzysheet', + 'g2w' => 'application/vnd.geoplan', + 'g3' => 'image/g3fax', + 'g3w' => 'application/vnd.geospace', + 'gac' => 'application/vnd.groove-account', + 'gdl' => 'model/vnd.gdl', + 'geo' => 'application/vnd.dynageo', + 'gex' => 'application/vnd.geometry-explorer', + 'ggb' => 'application/vnd.geogebra.file', + 'ggt' => 'application/vnd.geogebra.tool', + 'ghf' => 'application/vnd.groove-help', + 'gif' => 'image/gif', + 'gim' => 'application/vnd.groove-identity-message', + 'gmx' => 'application/vnd.gmx', + 'gnumeric' => 'application/x-gnumeric', + 'gph' => 'application/vnd.flographit', + 'gqf' => 'application/vnd.grafeq', + 'gqs' => 'application/vnd.grafeq', + 'gram' => 'application/srgs', + 'gre' => 'application/vnd.geometry-explorer', + 'grv' => 'application/vnd.groove-injector', + 'grxml' => 'application/srgs+xml', + 'gsf' => 'application/x-font-ghostscript', + 'gtar' => 'application/x-gtar', + 'gtm' => 'application/vnd.groove-tool-message', + 'gtw' => 'model/vnd.gtw', + 'gv' => 'text/vnd.graphviz', + 'gxt' => 'application/vnd.geonext', + 'h' => 'text/x-c', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'hal' => 'application/vnd.hal+xml', + 'hbci' => 'application/vnd.hbci', + 'hdf' => 'application/x-hdf', + 'hh' => 'text/x-c', + 'hlp' => 'application/winhlp', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hpid' => 'application/vnd.hp-hpid', + 'hps' => 'application/vnd.hp-hps', + 'hqx' => 'application/mac-binhex40', + 'hta' => 'application/octet-stream', + 'htc' => 'text/html', + 'htke' => 'application/vnd.kenameaapp', + 'htm' => 'text/html', + 'html' => 'text/html', + 'hvd' => 'application/vnd.yamaha.hv-dic', + 'hvp' => 'application/vnd.yamaha.hv-voice', + 'hvs' => 'application/vnd.yamaha.hv-script', + 'i2g' => 'application/vnd.intergeo', + 'icc' => 'application/vnd.iccprofile', + 'ice' => 'x-conference/x-cooltalk', + 'icm' => 'application/vnd.iccprofile', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ief' => 'image/ief', + 'ifb' => 'text/calendar', + 'ifm' => 'application/vnd.shana.informed.formdata', + 'iges' => 'model/iges', + 'igl' => 'application/vnd.igloader', + 'igm' => 'application/vnd.insors.igm', + 'igs' => 'model/iges', + 'igx' => 'application/vnd.micrografx.igx', + 'iif' => 'application/vnd.shana.informed.interchange', + 'imp' => 'application/vnd.accpac.simply.imp', + 'ims' => 'application/vnd.ms-ims', + 'in' => 'text/plain', + 'ini' => 'text/plain', + 'ipfix' => 'application/ipfix', + 'ipk' => 'application/vnd.shana.informed.package', + 'irm' => 'application/vnd.ibm.rights-management', + 'irp' => 'application/vnd.irepository.package+xml', + 'iso' => 'application/octet-stream', + 'itp' => 'application/vnd.shana.informed.formtemplate', + 'ivp' => 'application/vnd.immervision-ivp', + 'ivu' => 'application/vnd.immervision-ivu', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'jam' => 'application/vnd.jam', + 'jar' => 'application/java-archive', + 'java' => 'text/x-java-source', + 'jisp' => 'application/vnd.jisp', + 'jlt' => 'application/vnd.hp-jlyt', + 'jnlp' => 'application/x-java-jnlp-file', + 'joda' => 'application/vnd.joost.joda-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpgm' => 'video/jpm', + 'jpgv' => 'video/jpeg', + 'jpm' => 'video/jpm', + 'js' => 'text/javascript', + 'json' => 'application/json', + 'kar' => 'audio/midi', + 'karbon' => 'application/vnd.kde.karbon', + 'kfo' => 'application/vnd.kde.kformula', + 'kia' => 'application/vnd.kidspiration', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kne' => 'application/vnd.kinar', + 'knp' => 'application/vnd.kinar', + 'kon' => 'application/vnd.kde.kontour', + 'kpr' => 'application/vnd.kde.kpresenter', + 'kpt' => 'application/vnd.kde.kpresenter', + 'ksp' => 'application/vnd.kde.kspread', + 'ktr' => 'application/vnd.kahootz', + 'ktx' => 'image/ktx', + 'ktz' => 'application/vnd.kahootz', + 'kwd' => 'application/vnd.kde.kword', + 'kwt' => 'application/vnd.kde.kword', + 'lasxml' => 'application/vnd.las.las+xml', + 'latex' => 'application/x-latex', + 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', + 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', + 'les' => 'application/vnd.hhe.lesson-player', + 'lha' => 'application/octet-stream', + 'link66' => 'application/vnd.route66.link66+xml', + 'list' => 'text/plain', + 'list3820' => 'application/vnd.ibm.modcap', + 'listafp' => 'application/vnd.ibm.modcap', + 'log' => 'text/plain', + 'lostxml' => 'application/lost+xml', + 'lrf' => 'application/octet-stream', + 'lrm' => 'application/vnd.ms-lrm', + 'ltf' => 'application/vnd.frogans.ltf', + 'lvp' => 'audio/vnd.lucent.voice', + 'lwp' => 'application/vnd.lotus-wordpro', + 'lzh' => 'application/octet-stream', + 'm13' => 'application/x-msmediaview', + 'm14' => 'application/x-msmediaview', + 'm1v' => 'video/mpeg', + 'm21' => 'application/mp21', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3a' => 'audio/mpeg', + 'm3u' => 'audio/x-mpegurl', + 'm3u8' => 'application/vnd.apple.mpegurl', + 'm4a' => 'audio/mp4', + 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/mp4', + 'ma' => 'application/mathematica', + 'mads' => 'application/mads+xml', + 'mag' => 'application/vnd.ecowin.chart', + 'maker' => 'application/vnd.framemaker', + 'man' => 'text/troff', + 'mathml' => 'application/mathml+xml', + 'mb' => 'application/mathematica', + 'mbk' => 'application/vnd.mobius.mbk', + 'mbox' => 'application/mbox', + 'mc1' => 'application/vnd.medcalcdata', + 'mcd' => 'application/vnd.mcd', + 'mcurl' => 'text/vnd.curl.mcurl', + 'mdb' => 'application/x-msaccess', + 'mdi' => 'image/vnd.ms-modi', + 'me' => 'text/troff', + 'mesh' => 'model/mesh', + 'meta4' => 'application/metalink4+xml', + 'mets' => 'application/mets+xml', + 'mfm' => 'application/vnd.mfmp', + 'mgp' => 'application/vnd.osgeo.mapguide.package', + 'mgz' => 'application/vnd.proteus.magazine', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mif' => 'application/vnd.mif', + 'mime' => 'message/rfc822', + 'mj2' => 'video/mj2', + 'mjp2' => 'video/mj2', + 'mlp' => 'application/vnd.dolby.mlp', + 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', + 'mmf' => 'application/vnd.smaf', + 'mmr' => 'image/vnd.fujixerox.edmics-mmr', + 'mny' => 'application/x-msmoney', + 'mobi' => 'application/x-mobipocket-ebook', + 'mods' => 'application/mods+xml', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp21' => 'application/mp21', + 'mp2a' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4s' => 'application/mp4', + 'mp4v' => 'video/mp4', + 'mpc' => 'application/vnd.mophun.certificate', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'mpga' => 'audio/mpeg', + 'mpkg' => 'application/vnd.apple.installer+xml', + 'mpm' => 'application/vnd.blueice.multipass', + 'mpn' => 'application/vnd.mophun.application', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/vnd.ms-project', + 'mpy' => 'application/vnd.ibm.minipay', + 'mqy' => 'application/vnd.mobius.mqy', + 'mrc' => 'application/marc', + 'mrcx' => 'application/marcxml+xml', + 'ms' => 'text/troff', + 'mscml' => 'application/mediaservercontrol+xml', + 'mseed' => 'application/vnd.fdsn.mseed', + 'mseq' => 'application/vnd.mseq', + 'msf' => 'application/vnd.epson.msf', + 'msh' => 'model/mesh', + 'msi' => 'application/x-msdownload', + 'msl' => 'application/vnd.mobius.msl', + 'msty' => 'application/vnd.muvee.style', + 'mts' => 'model/vnd.mts', + 'mus' => 'application/vnd.musician', + 'musicxml' => 'application/vnd.recordare.musicxml+xml', + 'mvb' => 'application/x-msmediaview', + 'mwf' => 'application/vnd.mfer', + 'mxf' => 'application/mxf', + 'mxl' => 'application/vnd.recordare.musicxml', + 'mxml' => 'application/xv+xml', + 'mxs' => 'application/vnd.triscape.mxs', + 'mxu' => 'video/vnd.mpegurl', + 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', + 'n3' => 'text/n3', + 'nb' => 'application/mathematica', + 'nbp' => 'application/vnd.wolfram.player', + 'nc' => 'application/x-netcdf', + 'ncx' => 'application/x-dtbncx+xml', + 'ngdat' => 'application/vnd.nokia.n-gage.data', + 'nlu' => 'application/vnd.neurolanguage.nlu', + 'nml' => 'application/vnd.enliven', + 'nnd' => 'application/vnd.noblenet-directory', + 'nns' => 'application/vnd.noblenet-sealer', + 'nnw' => 'application/vnd.noblenet-web', + 'npx' => 'image/vnd.net-fpx', + 'nsf' => 'application/vnd.lotus-notes', + 'oa2' => 'application/vnd.fujitsu.oasys2', + 'oa3' => 'application/vnd.fujitsu.oasys3', + 'oas' => 'application/vnd.fujitsu.oasys', + 'obd' => 'application/x-msbinder', + 'oda' => 'application/oda', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odft' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'onepkg' => 'application/onenote', + 'onetmp' => 'application/onenote', + 'onetoc' => 'application/onenote', + 'onetoc2' => 'application/onenote', + 'opf' => 'application/oebps-package+xml', + 'oprc' => 'application/vnd.palm', + 'org' => 'application/vnd.lotus-organizer', + 'osf' => 'application/vnd.yamaha.openscoreformat', + 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'otf' => 'application/x-font-otf', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oxt' => 'application/vnd.openofficeorg.extension', + 'p' => 'text/x-pascal', + 'p10' => 'application/pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7b' => 'application/x-pkcs7-certificates', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'p8' => 'application/pkcs8', + 'pas' => 'text/x-pascal', + 'paw' => 'application/vnd.pawaafile', + 'pbd' => 'application/vnd.powerbuilder6', + 'pbm' => 'image/x-portable-bitmap', + 'pcf' => 'application/x-font-pcf', + 'pcl' => 'application/vnd.hp-pcl', + 'pclxl' => 'application/vnd.hp-pclxl', + 'pct' => 'image/x-pict', + 'pcurl' => 'application/vnd.curl.pcurl', + 'pcx' => 'image/x-pcx', + 'pdb' => 'application/vnd.palm', + 'pdf' => 'application/pdf', + 'pfa' => 'application/x-font-type1', + 'pfb' => 'application/x-font-type1', + 'pfm' => 'application/x-font-type1', + 'pfr' => 'application/font-tdpfr', + 'pfx' => 'application/x-pkcs12', + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', + 'pgp' => 'application/pgp-encrypted', + 'php' => 'text/x-php', + 'phps' => 'application/x-httpd-phps', + 'pic' => 'image/x-pict', + 'pkg' => 'application/octet-stream', + 'pki' => 'application/pkixcmp', + 'pkipath' => 'application/pkix-pkipath', + 'plb' => 'application/vnd.3gpp.pic-bw-large', + 'plc' => 'application/vnd.mobius.plc', + 'plf' => 'application/vnd.pocketlearn', + 'pls' => 'application/pls+xml', + 'pml' => 'application/vnd.ctc-posml', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'portpkg' => 'application/vnd.macports.portpkg', + 'pot' => 'application/vnd.ms-powerpoint', + 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', + 'ppd' => 'application/vnd.cups-ppd', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/vnd.ms-powerpoint', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'pqa' => 'application/vnd.palm', + 'prc' => 'application/x-mobipocket-ebook', + 'pre' => 'application/vnd.lotus-freelance', + 'prf' => 'application/pics-rules', + 'ps' => 'application/postscript', + 'psb' => 'application/vnd.3gpp.pic-bw-small', + 'psd' => 'image/vnd.adobe.photoshop', + 'psf' => 'application/x-font-linux-psf', + 'pskcxml' => 'application/pskc+xml', + 'ptid' => 'application/vnd.pvi.ptid1', + 'pub' => 'application/x-mspublisher', + 'pvb' => 'application/vnd.3gpp.pic-bw-var', + 'pwn' => 'application/vnd.3m.post-it-notes', + 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyv' => 'video/vnd.ms-playready.media.pyv', + 'qam' => 'application/vnd.epson.quickanime', + 'qbo' => 'application/vnd.intu.qbo', + 'qfx' => 'application/vnd.intu.qfx', + 'qps' => 'application/vnd.publishare-delta-tree', + 'qt' => 'video/quicktime', + 'qwd' => 'application/vnd.quark.quarkxpress', + 'qwt' => 'application/vnd.quark.quarkxpress', + 'qxb' => 'application/vnd.quark.quarkxpress', + 'qxd' => 'application/vnd.quark.quarkxpress', + 'qxl' => 'application/vnd.quark.quarkxpress', + 'qxt' => 'application/vnd.quark.quarkxpress', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rb' => 'text/plain', + 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', + 'rdf' => 'application/rdf+xml', + 'rdz' => 'application/vnd.data-vision.rdz', + 'rep' => 'application/vnd.businessobjects', + 'res' => 'application/x-dtbresource+xml', + 'resx' => 'text/xml', + 'rgb' => 'image/x-rgb', + 'rif' => 'application/reginfo+xml', + 'rip' => 'audio/vnd.rip', + 'rl' => 'application/resource-lists+xml', + 'rlc' => 'image/vnd.fujixerox.edmics-rlc', + 'rld' => 'application/resource-lists-diff+xml', + 'rm' => 'application/vnd.rn-realmedia', + 'rmi' => 'audio/midi', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'rms' => 'application/vnd.jcp.javame.midlet-rms', + 'rnc' => 'application/relax-ng-compact-syntax', + 'roff' => 'text/troff', + 'rp9' => 'application/vnd.cloanto.rp9', + 'rpss' => 'application/vnd.nokia.radio-presets', + 'rpst' => 'application/vnd.nokia.radio-preset', + 'rq' => 'application/sparql-query', + 'rs' => 'application/rls-services+xml', + 'rsd' => 'application/rsd+xml', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'rtx' => 'text/richtext', + 's' => 'text/x-asm', + 'saf' => 'application/vnd.yamaha.smaf-audio', + 'sbml' => 'application/sbml+xml', + 'sc' => 'application/vnd.ibm.secure-container', + 'scd' => 'application/x-msschedule', + 'scm' => 'application/vnd.lotus-screencam', + 'scq' => 'application/scvp-cv-request', + 'scs' => 'application/scvp-cv-response', + 'scurl' => 'text/vnd.curl.scurl', + 'sda' => 'application/vnd.stardivision.draw', + 'sdc' => 'application/vnd.stardivision.calc', + 'sdd' => 'application/vnd.stardivision.impress', + 'sdkd' => 'application/vnd.solent.sdkm+xml', + 'sdkm' => 'application/vnd.solent.sdkm+xml', + 'sdp' => 'application/sdp', + 'sdw' => 'application/vnd.stardivision.writer', + 'see' => 'application/vnd.seemail', + 'seed' => 'application/vnd.fdsn.seed', + 'sema' => 'application/vnd.sema', + 'semd' => 'application/vnd.semd', + 'semf' => 'application/vnd.semf', + 'ser' => 'application/java-serialized-object', + 'setpay' => 'application/set-payment-initiation', + 'setreg' => 'application/set-registration-initiation', + 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', + 'sfs' => 'application/vnd.spotfire.sfs', + 'sgl' => 'application/vnd.stardivision.writer-global', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'shf' => 'application/shf+xml', + 'sig' => 'application/pgp-signature', + 'silo' => 'model/mesh', + 'sis' => 'application/vnd.symbian.install', + 'sisx' => 'application/vnd.symbian.install', + 'sit' => 'application/x-stuffit', + 'sitx' => 'application/x-stuffitx', + 'skd' => 'application/vnd.koan', + 'skm' => 'application/vnd.koan', + 'skp' => 'application/vnd.koan', + 'skt' => 'application/vnd.koan', + 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'slt' => 'application/vnd.epson.salt', + 'sm' => 'application/vnd.stepmania.stepchart', + 'smf' => 'application/vnd.stardivision.math', + 'smi' => 'application/smil+xml', + 'smil' => 'application/smil+xml', + 'snd' => 'audio/basic', + 'snf' => 'application/x-font-snf', + 'so' => 'application/octet-stream', + 'spc' => 'application/x-pkcs7-certificates', + 'spf' => 'application/vnd.yamaha.smaf-phrase', + 'spl' => 'application/x-futuresplash', + 'spot' => 'text/vnd.in3d.spot', + 'spp' => 'application/scvp-vp-response', + 'spq' => 'application/scvp-vp-request', + 'spx' => 'audio/ogg', + 'src' => 'application/x-wais-source', + 'srt' => 'application/octet-stream', + 'sru' => 'application/sru+xml', + 'srx' => 'application/sparql-results+xml', + 'sse' => 'application/vnd.kodak-descriptor', + 'ssf' => 'application/vnd.epson.ssf', + 'ssml' => 'application/ssml+xml', + 'st' => 'application/vnd.sailingtracker.track', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'std' => 'application/vnd.sun.xml.draw.template', + 'stf' => 'application/vnd.wt.stf', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'stk' => 'application/hyperstudio', + 'stl' => 'application/vnd.ms-pki.stl', + 'str' => 'application/vnd.pg.format', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sub' => 'image/vnd.dvb.subtitle', + 'sus' => 'application/vnd.sus-calendar', + 'susp' => 'application/vnd.sus-calendar', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svc' => 'application/vnd.dvb.service', + 'svd' => 'application/vnd.svd', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'swa' => 'application/x-director', + 'swf' => 'application/x-shockwave-flash', + 'swi' => 'application/vnd.aristanetworks.swi', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxd' => 'application/vnd.sun.xml.draw', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sxm' => 'application/vnd.sun.xml.math', + 'sxw' => 'application/vnd.sun.xml.writer', + 't' => 'text/troff', + 'tao' => 'application/vnd.tao.intent-module-archive', + 'tar' => 'application/x-tar', + 'tcap' => 'application/vnd.3gpp2.tcap', + 'tcl' => 'application/x-tcl', + 'teacher' => 'application/vnd.smart.teacher', + 'tei' => 'application/tei+xml', + 'teicorpus' => 'application/tei+xml', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tfi' => 'application/thraud+xml', + 'tfm' => 'application/x-tex-tfm', + 'thmx' => 'application/vnd.ms-officetheme', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tmo' => 'application/vnd.tmobile-livetv', + 'torrent' => 'application/x-bittorrent', + 'tpl' => 'application/vnd.groove-tool-template', + 'tpt' => 'application/vnd.trid.tpt', + 'tr' => 'text/troff', + 'tra' => 'application/vnd.trueapp', + 'trm' => 'application/x-msterminal', + 'tsd' => 'application/timestamped-data', + 'tsv' => 'text/tab-separated-values', + 'ttc' => 'application/x-font-ttf', + 'ttf' => 'application/x-font-ttf', + 'ttl' => 'text/turtle', + 'twd' => 'application/vnd.simtech-mindmapper', + 'twds' => 'application/vnd.simtech-mindmapper', + 'txd' => 'application/vnd.genomatix.tuxedo', + 'txf' => 'application/vnd.mobius.txf', + 'txt' => 'text/plain', + 'u32' => 'application/x-authorware-bin', + 'udeb' => 'application/x-debian-package', + 'ufd' => 'application/vnd.ufdl', + 'ufdl' => 'application/vnd.ufdl', + 'umj' => 'application/vnd.umajin', + 'unityweb' => 'application/vnd.unity', + 'uoml' => 'application/vnd.uoml+xml', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'urls' => 'text/uri-list', + 'ustar' => 'application/x-ustar', + 'utz' => 'application/vnd.uiq.theme', + 'uu' => 'text/x-uuencode', + 'uva' => 'audio/vnd.dece.audio', + 'uvd' => 'application/vnd.dece.data', + 'uvf' => 'application/vnd.dece.data', + 'uvg' => 'image/vnd.dece.graphic', + 'uvh' => 'video/vnd.dece.hd', + 'uvi' => 'image/vnd.dece.graphic', + 'uvm' => 'video/vnd.dece.mobile', + 'uvp' => 'video/vnd.dece.pd', + 'uvs' => 'video/vnd.dece.sd', + 'uvt' => 'application/vnd.dece.ttml+xml', + 'uvu' => 'video/vnd.uvvu.mp4', + 'uvv' => 'video/vnd.dece.video', + 'uvva' => 'audio/vnd.dece.audio', + 'uvvd' => 'application/vnd.dece.data', + 'uvvf' => 'application/vnd.dece.data', + 'uvvg' => 'image/vnd.dece.graphic', + 'uvvh' => 'video/vnd.dece.hd', + 'uvvi' => 'image/vnd.dece.graphic', + 'uvvm' => 'video/vnd.dece.mobile', + 'uvvp' => 'video/vnd.dece.pd', + 'uvvs' => 'video/vnd.dece.sd', + 'uvvt' => 'application/vnd.dece.ttml+xml', + 'uvvu' => 'video/vnd.uvvu.mp4', + 'uvvv' => 'video/vnd.dece.video', + 'uvvx' => 'application/vnd.dece.unspecified', + 'uvx' => 'application/vnd.dece.unspecified', + 'vcd' => 'application/x-cdlink', + 'vcf' => 'text/x-vcard', + 'vcg' => 'application/vnd.groove-vcard', + 'vcs' => 'text/x-vcalendar', + 'vcx' => 'application/vnd.vcx', + 'vis' => 'application/vnd.visionary', + 'viv' => 'video/vnd.vivo', + 'vor' => 'application/vnd.stardivision.writer', + 'vox' => 'application/x-authorware-bin', + 'vrml' => 'model/vrml', + 'vsd' => 'application/vnd.visio', + 'vsf' => 'application/vnd.vsf', + 'vss' => 'application/vnd.visio', + 'vst' => 'application/vnd.visio', + 'vsw' => 'application/vnd.visio', + 'vtu' => 'model/vnd.vtu', + 'vxml' => 'application/voicexml+xml', + 'w3d' => 'application/x-director', + 'wad' => 'application/x-doom', + 'wav' => 'audio/x-wav', + 'wax' => 'audio/x-ms-wax', + 'wbmp' => 'image/vnd.wap.wbmp', + 'wbs' => 'application/vnd.criticaltools.wbs+xml', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wcm' => 'application/vnd.ms-works', + 'wdb' => 'application/vnd.ms-works', + 'weba' => 'audio/webm', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wg' => 'application/vnd.pmi.widget', + 'wgt' => 'application/widget', + 'wks' => 'application/vnd.ms-works', + 'wm' => 'video/x-ms-wm', + 'wma' => 'audio/x-ms-wma', + 'wmd' => 'application/x-ms-wmd', + 'wmf' => 'application/x-msmetafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wmz' => 'application/x-ms-wmz', + 'woff' => 'application/x-font-woff', + 'wpd' => 'application/vnd.wordperfect', + 'wpl' => 'application/vnd.ms-wpl', + 'wps' => 'application/vnd.ms-works', + 'wqd' => 'application/vnd.wqd', + 'wri' => 'application/x-mswrite', + 'wrl' => 'model/vrml', + 'wsdl' => 'application/wsdl+xml', + 'wspolicy' => 'application/wspolicy+xml', + 'wtb' => 'application/vnd.webturbo', + 'wvx' => 'video/x-ms-wvx', + 'x32' => 'application/x-authorware-bin', + 'x3d' => 'application/vnd.hzn-3d-crossword', + 'xap' => 'application/x-silverlight-app', + 'xar' => 'application/vnd.xara', + 'xbap' => 'application/x-ms-xbap', + 'xbd' => 'application/vnd.fujixerox.docuworks.binder', + 'xbm' => 'image/x-xbitmap', + 'xdf' => 'application/xcap-diff+xml', + 'xdm' => 'application/vnd.syncml.dm+xml', + 'xdp' => 'application/vnd.adobe.xdp+xml', + 'xdssc' => 'application/dssc+xml', + 'xdw' => 'application/vnd.fujixerox.docuworks', + 'xenc' => 'application/xenc+xml', + 'xer' => 'application/patch-ops-error+xml', + 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdl' => 'application/vnd.xfdl', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xhvml' => 'application/xv+xml', + 'xif' => 'image/vnd.xiff', + 'xla' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', + 'xlc' => 'application/vnd.ms-excel', + 'xlm' => 'application/vnd.ms-excel', + 'xls' => 'application/vnd.ms-excel', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xlt' => 'application/vnd.ms-excel', + 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'xlw' => 'application/vnd.ms-excel', + 'xml' => 'application/xml', + 'xo' => 'application/vnd.olpc-sugar', + 'xop' => 'application/xop+xml', + 'xpi' => 'application/x-xpinstall', + 'xpm' => 'image/x-xpixmap', + 'xpr' => 'application/vnd.is-xpr', + 'xps' => 'application/vnd.ms-xpsdocument', + 'xpw' => 'application/vnd.intercon.formnet', + 'xpx' => 'application/vnd.intercon.formnet', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xsm' => 'application/vnd.syncml+xml', + 'xspf' => 'application/xspf+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xvm' => 'application/xv+xml', + 'xvml' => 'application/xv+xml', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-xyz', + 'yaml' => 'text/yaml', + 'yang' => 'application/yang', + 'yin' => 'application/yin+xml', + 'yml' => 'text/yaml', + 'zaz' => 'application/vnd.zzazz.deck+xml', + 'zip' => 'application/zip', + 'zir' => 'application/vnd.zul', + 'zirz' => 'application/vnd.zul', + 'zmm' => 'application/vnd.handheld-entertainment+xml' + ]; + + /** + * Get a singleton instance of the class + * + * @return self + * @codeCoverageIgnore + */ + public static function getInstance() + { + if (!self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Get a mimetype value from a file extension + * + * @param string $extension File extension + * + * @return string|null + */ + public function fromExtension($extension) + { + $extension = strtolower($extension); + + return isset($this->mimetypes[$extension]) ? $this->mimetypes[$extension] : null; + } + + /** + * Get a mimetype from a filename + * + * @param string $filename Filename to generate a mimetype from + * + * @return string|null + */ + public function fromFilename($filename) + { + return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION)); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/Birthday.php b/inc/vendors/social-login/Facebook/GraphNodes/Birthday.php new file mode 100755 index 00000000..4338b65e --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/Birthday.php @@ -0,0 +1,85 @@ +hasYear = count($parts) === 3 || count($parts) === 1; + $this->hasDate = count($parts) === 3 || count($parts) === 2; + + parent::__construct($date); + } + + /** + * Returns whether date object contains birth day and month + * + * @return bool + */ + public function hasDate() + { + return $this->hasDate; + } + + /** + * Returns whether date object contains birth year + * + * @return bool + */ + public function hasYear() + { + return $this->hasYear; + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/Collection.php b/inc/vendors/social-login/Facebook/GraphNodes/Collection.php new file mode 100755 index 00000000..424b7cf3 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/Collection.php @@ -0,0 +1,242 @@ +items = $items; + } + + /** + * Gets the value of a field from the Graph node. + * + * @param string $name The field to retrieve. + * @param mixed $default The default to return if the field doesn't exist. + * + * @return mixed + */ + public function getField($name, $default = null) + { + if (isset($this->items[$name])) { + return $this->items[$name]; + } + + return $default; + } + + /** + * Gets the value of the named property for this graph object. + * + * @param string $name The property to retrieve. + * @param mixed $default The default to return if the property doesn't exist. + * + * @return mixed + * + * @deprecated 5.0.0 getProperty() has been renamed to getField() + * @todo v6: Remove this method + */ + public function getProperty($name, $default = null) + { + return $this->getField($name, $default); + } + + /** + * Returns a list of all fields set on the object. + * + * @return array + */ + public function getFieldNames() + { + return array_keys($this->items); + } + + /** + * Returns a list of all properties set on the object. + * + * @return array + * + * @deprecated 5.0.0 getPropertyNames() has been renamed to getFieldNames() + * @todo v6: Remove this method + */ + public function getPropertyNames() + { + return $this->getFieldNames(); + } + + /** + * Get all of the items in the collection. + * + * @return array + */ + public function all() + { + return $this->items; + } + + /** + * Get the collection of items as a plain array. + * + * @return array + */ + public function asArray() + { + return array_map(function ($value) { + return $value instanceof Collection ? $value->asArray() : $value; + }, $this->items); + } + + /** + * Run a map over each of the items. + * + * @param \Closure $callback + * + * @return static + */ + public function map(\Closure $callback) + { + return new static(array_map($callback, $this->items, array_keys($this->items))); + } + + /** + * Get the collection of items as JSON. + * + * @param int $options + * + * @return string + */ + public function asJson($options = 0) + { + return json_encode($this->asArray(), $options); + } + + /** + * Count the number of items in the collection. + * + * @return int + */ + public function count() + { + return count($this->items); + } + + /** + * Get an iterator for the items. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->items); + } + + /** + * Determine if an item exists at an offset. + * + * @param mixed $key + * + * @return bool + */ + public function offsetExists($key) + { + return array_key_exists($key, $this->items); + } + + /** + * Get an item at a given offset. + * + * @param mixed $key + * + * @return mixed + */ + public function offsetGet($key) + { + return $this->items[$key]; + } + + /** + * Set the item at a given offset. + * + * @param mixed $key + * @param mixed $value + * + * @return void + */ + public function offsetSet($key, $value) + { + if (is_null($key)) { + $this->items[] = $value; + } else { + $this->items[$key] = $value; + } + } + + /** + * Unset the item at a given offset. + * + * @param string $key + * + * @return void + */ + public function offsetUnset($key) + { + unset($this->items[$key]); + } + + /** + * Convert the collection to its string representation. + * + * @return string + */ + public function __toString() + { + return $this->asJson(); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphAchievement.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphAchievement.php new file mode 100755 index 00000000..31508ee4 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphAchievement.php @@ -0,0 +1,112 @@ + '\Facebook\GraphNodes\GraphUser', + 'application' => '\Facebook\GraphNodes\GraphApplication', + ]; + + /** + * Returns the ID for the achievement. + * + * @return string|null + */ + public function getId() + { + return $this->getField('id'); + } + + /** + * Returns the user who achieved this. + * + * @return GraphUser|null + */ + public function getFrom() + { + return $this->getField('from'); + } + + /** + * Returns the time at which this was achieved. + * + * @return \DateTime|null + */ + public function getPublishTime() + { + return $this->getField('publish_time'); + } + + /** + * Returns the app in which the user achieved this. + * + * @return GraphApplication|null + */ + public function getApplication() + { + return $this->getField('application'); + } + + /** + * Returns information about the achievement type this instance is connected with. + * + * @return array|null + */ + public function getData() + { + return $this->getField('data'); + } + + /** + * Returns the type of achievement. + * + * @see https://developers.facebook.com/docs/graph-api/reference/achievement + * + * @return string + */ + public function getType() + { + return 'game.achievement'; + } + + /** + * Indicates whether gaining the achievement published a feed story for the user. + * + * @return boolean|null + */ + public function isNoFeedStory() + { + return $this->getField('no_feed_story'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphAlbum.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphAlbum.php new file mode 100755 index 00000000..52f19b51 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphAlbum.php @@ -0,0 +1,183 @@ + '\Facebook\GraphNodes\GraphUser', + 'place' => '\Facebook\GraphNodes\GraphPage', + ]; + + /** + * Returns the ID for the album. + * + * @return string|null + */ + public function getId() + { + return $this->getField('id'); + } + + /** + * Returns whether the viewer can upload photos to this album. + * + * @return boolean|null + */ + public function getCanUpload() + { + return $this->getField('can_upload'); + } + + /** + * Returns the number of photos in this album. + * + * @return int|null + */ + public function getCount() + { + return $this->getField('count'); + } + + /** + * Returns the ID of the album's cover photo. + * + * @return string|null + */ + public function getCoverPhoto() + { + return $this->getField('cover_photo'); + } + + /** + * Returns the time the album was initially created. + * + * @return \DateTime|null + */ + public function getCreatedTime() + { + return $this->getField('created_time'); + } + + /** + * Returns the time the album was updated. + * + * @return \DateTime|null + */ + public function getUpdatedTime() + { + return $this->getField('updated_time'); + } + + /** + * Returns the description of the album. + * + * @return string|null + */ + public function getDescription() + { + return $this->getField('description'); + } + + /** + * Returns profile that created the album. + * + * @return GraphUser|null + */ + public function getFrom() + { + return $this->getField('from'); + } + + /** + * Returns profile that created the album. + * + * @return GraphPage|null + */ + public function getPlace() + { + return $this->getField('place'); + } + + /** + * Returns a link to this album on Facebook. + * + * @return string|null + */ + public function getLink() + { + return $this->getField('link'); + } + + /** + * Returns the textual location of the album. + * + * @return string|null + */ + public function getLocation() + { + return $this->getField('location'); + } + + /** + * Returns the title of the album. + * + * @return string|null + */ + public function getName() + { + return $this->getField('name'); + } + + /** + * Returns the privacy settings for the album. + * + * @return string|null + */ + public function getPrivacy() + { + return $this->getField('privacy'); + } + + /** + * Returns the type of the album. + * + * enum{ profile, mobile, wall, normal, album } + * + * @return string|null + */ + public function getType() + { + return $this->getField('type'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphApplication.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphApplication.php new file mode 100755 index 00000000..aa07c825 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphApplication.php @@ -0,0 +1,43 @@ +getField('id'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphCoverPhoto.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphCoverPhoto.php new file mode 100755 index 00000000..824275bb --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphCoverPhoto.php @@ -0,0 +1,72 @@ +getField('id'); + } + + /** + * Returns the source of cover if it exists + * + * @return string|null + */ + public function getSource() + { + return $this->getField('source'); + } + + /** + * Returns the offset_x of cover if it exists + * + * @return int|null + */ + public function getOffsetX() + { + return $this->getField('offset_x'); + } + + /** + * Returns the offset_y of cover if it exists + * + * @return int|null + */ + public function getOffsetY() + { + return $this->getField('offset_y'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphEdge.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphEdge.php new file mode 100755 index 00000000..f6f4970c --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphEdge.php @@ -0,0 +1,252 @@ +request = $request; + $this->metaData = $metaData; + $this->parentEdgeEndpoint = $parentEdgeEndpoint; + $this->subclassName = $subclassName; + + parent::__construct($data); + } + + /** + * Gets the parent Graph edge endpoint that generated the list. + * + * @return string|null + */ + public function getParentGraphEdge() + { + return $this->parentEdgeEndpoint; + } + + /** + * Gets the subclass name that the child GraphNode's are cast as. + * + * @return string|null + */ + public function getSubClassName() + { + return $this->subclassName; + } + + /** + * Returns the raw meta data associated with this GraphEdge. + * + * @return array + */ + public function getMetaData() + { + return $this->metaData; + } + + /** + * Returns the next cursor if it exists. + * + * @return string|null + */ + public function getNextCursor() + { + return $this->getCursor('after'); + } + + /** + * Returns the previous cursor if it exists. + * + * @return string|null + */ + public function getPreviousCursor() + { + return $this->getCursor('before'); + } + + /** + * Returns the cursor for a specific direction if it exists. + * + * @param string $direction The direction of the page: after|before + * + * @return string|null + */ + public function getCursor($direction) + { + if (isset($this->metaData['paging']['cursors'][$direction])) { + return $this->metaData['paging']['cursors'][$direction]; + } + + return null; + } + + /** + * Generates a pagination URL based on a cursor. + * + * @param string $direction The direction of the page: next|previous + * + * @return string|null + * + * @throws FacebookSDKException + */ + public function getPaginationUrl($direction) + { + $this->validateForPagination(); + + // Do we have a paging URL? + if (!isset($this->metaData['paging'][$direction])) { + return null; + } + + $pageUrl = $this->metaData['paging'][$direction]; + + return FacebookUrlManipulator::baseGraphUrlEndpoint($pageUrl); + } + + /** + * Validates whether or not we can paginate on this request. + * + * @throws FacebookSDKException + */ + public function validateForPagination() + { + if ($this->request->getMethod() !== 'GET') { + throw new FacebookSDKException('You can only paginate on a GET request.', 720); + } + } + + /** + * Gets the request object needed to make a next|previous page request. + * + * @param string $direction The direction of the page: next|previous + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getPaginationRequest($direction) + { + $pageUrl = $this->getPaginationUrl($direction); + if (!$pageUrl) { + return null; + } + + $newRequest = clone $this->request; + $newRequest->setEndpoint($pageUrl); + + return $newRequest; + } + + /** + * Gets the request object needed to make a "next" page request. + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getNextPageRequest() + { + return $this->getPaginationRequest('next'); + } + + /** + * Gets the request object needed to make a "previous" page request. + * + * @return FacebookRequest|null + * + * @throws FacebookSDKException + */ + public function getPreviousPageRequest() + { + return $this->getPaginationRequest('previous'); + } + + /** + * The total number of results according to Graph if it exists. + * + * This will be returned if the summary=true modifier is present in the request. + * + * @return int|null + */ + public function getTotalCount() + { + if (isset($this->metaData['summary']['total_count'])) { + return $this->metaData['summary']['total_count']; + } + + return null; + } + + /** + * @inheritDoc + */ + public function map(\Closure $callback) + { + return new static( + $this->request, + array_map($callback, $this->items, array_keys($this->items)), + $this->metaData, + $this->parentEdgeEndpoint, + $this->subclassName + ); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphEvent.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphEvent.php new file mode 100755 index 00000000..a470d89f --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphEvent.php @@ -0,0 +1,242 @@ + '\Facebook\GraphNodes\GraphCoverPhoto', + 'place' => '\Facebook\GraphNodes\GraphPage', + 'picture' => '\Facebook\GraphNodes\GraphPicture', + 'parent_group' => '\Facebook\GraphNodes\GraphGroup', + ]; + + /** + * Returns the `id` (The event ID) as string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getField('id'); + } + + /** + * Returns the `cover` (Cover picture) as GraphCoverPhoto if present. + * + * @return GraphCoverPhoto|null + */ + public function getCover() + { + return $this->getField('cover'); + } + + /** + * Returns the `description` (Long-form description) as string if present. + * + * @return string|null + */ + public function getDescription() + { + return $this->getField('description'); + } + + /** + * Returns the `end_time` (End time, if one has been set) as DateTime if present. + * + * @return \DateTime|null + */ + public function getEndTime() + { + return $this->getField('end_time'); + } + + /** + * Returns the `is_date_only` (Whether the event only has a date specified, but no time) as bool if present. + * + * @return bool|null + */ + public function getIsDateOnly() + { + return $this->getField('is_date_only'); + } + + /** + * Returns the `name` (Event name) as string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getField('name'); + } + + /** + * Returns the `owner` (The profile that created the event) as GraphNode if present. + * + * @return GraphNode|null + */ + public function getOwner() + { + return $this->getField('owner'); + } + + /** + * Returns the `parent_group` (The group the event belongs to) as GraphGroup if present. + * + * @return GraphGroup|null + */ + public function getParentGroup() + { + return $this->getField('parent_group'); + } + + /** + * Returns the `place` (Event Place information) as GraphPage if present. + * + * @return GraphPage|null + */ + public function getPlace() + { + return $this->getField('place'); + } + + /** + * Returns the `privacy` (Who can see the event) as string if present. + * + * @return string|null + */ + public function getPrivacy() + { + return $this->getField('privacy'); + } + + /** + * Returns the `start_time` (Start time) as DateTime if present. + * + * @return \DateTime|null + */ + public function getStartTime() + { + return $this->getField('start_time'); + } + + /** + * Returns the `ticket_uri` (The link users can visit to buy a ticket to this event) as string if present. + * + * @return string|null + */ + public function getTicketUri() + { + return $this->getField('ticket_uri'); + } + + /** + * Returns the `timezone` (Timezone) as string if present. + * + * @return string|null + */ + public function getTimezone() + { + return $this->getField('timezone'); + } + + /** + * Returns the `updated_time` (Last update time) as DateTime if present. + * + * @return \DateTime|null + */ + public function getUpdatedTime() + { + return $this->getField('updated_time'); + } + + /** + * Returns the `picture` (Event picture) as GraphPicture if present. + * + * @return GraphPicture|null + */ + public function getPicture() + { + return $this->getField('picture'); + } + + /** + * Returns the `attending_count` (Number of people attending the event) as int if present. + * + * @return int|null + */ + public function getAttendingCount() + { + return $this->getField('attending_count'); + } + + /** + * Returns the `declined_count` (Number of people who declined the event) as int if present. + * + * @return int|null + */ + public function getDeclinedCount() + { + return $this->getField('declined_count'); + } + + /** + * Returns the `maybe_count` (Number of people who maybe going to the event) as int if present. + * + * @return int|null + */ + public function getMaybeCount() + { + return $this->getField('maybe_count'); + } + + /** + * Returns the `noreply_count` (Number of people who did not reply to the event) as int if present. + * + * @return int|null + */ + public function getNoreplyCount() + { + return $this->getField('noreply_count'); + } + + /** + * Returns the `invited_count` (Number of people invited to the event) as int if present. + * + * @return int|null + */ + public function getInvitedCount() + { + return $this->getField('invited_count'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphGroup.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphGroup.php new file mode 100755 index 00000000..6217bd4d --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphGroup.php @@ -0,0 +1,170 @@ + '\Facebook\GraphNodes\GraphCoverPhoto', + 'venue' => '\Facebook\GraphNodes\GraphLocation', + ]; + + /** + * Returns the `id` (The Group ID) as string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getField('id'); + } + + /** + * Returns the `cover` (The cover photo of the Group) as GraphCoverPhoto if present. + * + * @return GraphCoverPhoto|null + */ + public function getCover() + { + return $this->getField('cover'); + } + + /** + * Returns the `description` (A brief description of the Group) as string if present. + * + * @return string|null + */ + public function getDescription() + { + return $this->getField('description'); + } + + /** + * Returns the `email` (The email address to upload content to the Group. Only current members of the Group can use this) as string if present. + * + * @return string|null + */ + public function getEmail() + { + return $this->getField('email'); + } + + /** + * Returns the `icon` (The URL for the Group's icon) as string if present. + * + * @return string|null + */ + public function getIcon() + { + return $this->getField('icon'); + } + + /** + * Returns the `link` (The Group's website) as string if present. + * + * @return string|null + */ + public function getLink() + { + return $this->getField('link'); + } + + /** + * Returns the `name` (The name of the Group) as string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getField('name'); + } + + /** + * Returns the `member_request_count` (Number of people asking to join the group.) as int if present. + * + * @return int|null + */ + public function getMemberRequestCount() + { + return $this->getField('member_request_count'); + } + + /** + * Returns the `owner` (The profile that created this Group) as GraphNode if present. + * + * @return GraphNode|null + */ + public function getOwner() + { + return $this->getField('owner'); + } + + /** + * Returns the `parent` (The parent Group of this Group, if it exists) as GraphNode if present. + * + * @return GraphNode|null + */ + public function getParent() + { + return $this->getField('parent'); + } + + /** + * Returns the `privacy` (The privacy setting of the Group) as string if present. + * + * @return string|null + */ + public function getPrivacy() + { + return $this->getField('privacy'); + } + + /** + * Returns the `updated_time` (The last time the Group was updated (this includes changes in the Group's properties and changes in posts and comments if user can see them)) as \DateTime if present. + * + * @return \DateTime|null + */ + public function getUpdatedTime() + { + return $this->getField('updated_time'); + } + + /** + * Returns the `venue` (The location for the Group) as GraphLocation if present. + * + * @return GraphLocation|null + */ + public function getVenue() + { + return $this->getField('venue'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphList.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphList.php new file mode 100755 index 00000000..3dfbd497 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphList.php @@ -0,0 +1,36 @@ +getField('street'); + } + + /** + * Returns the city component of the location + * + * @return string|null + */ + public function getCity() + { + return $this->getField('city'); + } + + /** + * Returns the state component of the location + * + * @return string|null + */ + public function getState() + { + return $this->getField('state'); + } + + /** + * Returns the country component of the location + * + * @return string|null + */ + public function getCountry() + { + return $this->getField('country'); + } + + /** + * Returns the zipcode component of the location + * + * @return string|null + */ + public function getZip() + { + return $this->getField('zip'); + } + + /** + * Returns the latitude component of the location + * + * @return float|null + */ + public function getLatitude() + { + return $this->getField('latitude'); + } + + /** + * Returns the street component of the location + * + * @return float|null + */ + public function getLongitude() + { + return $this->getField('longitude'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphNode.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphNode.php new file mode 100755 index 00000000..a81c47b7 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphNode.php @@ -0,0 +1,198 @@ +castItems($data)); + } + + /** + * Iterates over an array and detects the types each node + * should be cast to and returns all the items as an array. + * + * @TODO Add auto-casting to AccessToken entities. + * + * @param array $data The array to iterate over. + * + * @return array + */ + public function castItems(array $data) + { + $items = []; + + foreach ($data as $k => $v) { + if ($this->shouldCastAsDateTime($k) + && (is_numeric($v) + || $this->isIso8601DateString($v)) + ) { + $items[$k] = $this->castToDateTime($v); + } elseif ($k === 'birthday') { + $items[$k] = $this->castToBirthday($v); + } else { + $items[$k] = $v; + } + } + + return $items; + } + + /** + * Uncasts any auto-casted datatypes. + * Basically the reverse of castItems(). + * + * @return array + */ + public function uncastItems() + { + $items = $this->asArray(); + + return array_map(function ($v) { + if ($v instanceof \DateTime) { + return $v->format(\DateTime::ISO8601); + } + + return $v; + }, $items); + } + + /** + * Get the collection of items as JSON. + * + * @param int $options + * + * @return string + */ + public function asJson($options = 0) + { + return json_encode($this->uncastItems(), $options); + } + + /** + * Detects an ISO 8601 formatted string. + * + * @param string $string + * + * @return boolean + * + * @see https://developers.facebook.com/docs/graph-api/using-graph-api/#readmodifiers + * @see http://www.cl.cam.ac.uk/~mgk25/iso-time.html + * @see http://en.wikipedia.org/wiki/ISO_8601 + */ + public function isIso8601DateString($string) + { + // This insane regex was yoinked from here: + // http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/ + // ...and I'm all like: + // http://thecodinglove.com/post/95378251969/when-code-works-and-i-dont-know-why + $crazyInsaneRegexThatSomehowDetectsIso8601 = '/^([\+-]?\d{4}(?!\d{2}\b))' + . '((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?' + . '|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d' + . '|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])' + . '((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d' + . '([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/'; + + return preg_match($crazyInsaneRegexThatSomehowDetectsIso8601, $string) === 1; + } + + /** + * Determines if a value from Graph should be cast to DateTime. + * + * @param string $key + * + * @return boolean + */ + public function shouldCastAsDateTime($key) + { + return in_array($key, [ + 'created_time', + 'updated_time', + 'start_time', + 'end_time', + 'backdated_time', + 'issued_at', + 'expires_at', + 'publish_time', + 'joined' + ], true); + } + + /** + * Casts a date value from Graph to DateTime. + * + * @param int|string $value + * + * @return \DateTime + */ + public function castToDateTime($value) + { + if (is_int($value)) { + $dt = new \DateTime(); + $dt->setTimestamp($value); + } else { + $dt = new \DateTime($value); + } + + return $dt; + } + + /** + * Casts a birthday value from Graph to Birthday + * + * @param string $value + * + * @return Birthday + */ + public function castToBirthday($value) + { + return new Birthday($value); + } + + /** + * Getter for $graphObjectMap. + * + * @return array + */ + public static function getObjectMap() + { + return static::$graphObjectMap; + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphNodeFactory.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphNodeFactory.php new file mode 100755 index 00000000..937128bb --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphNodeFactory.php @@ -0,0 +1,394 @@ +response = $response; + $this->decodedBody = $response->getDecodedBody(); + } + + /** + * Tries to convert a FacebookResponse entity into a GraphNode. + * + * @param string|null $subclassName The GraphNode sub class to cast to. + * + * @return GraphNode + * + * @throws FacebookSDKException + */ + public function makeGraphNode($subclassName = null) + { + $this->validateResponseAsArray(); + $this->validateResponseCastableAsGraphNode(); + + return $this->castAsGraphNodeOrGraphEdge($this->decodedBody, $subclassName); + } + + /** + * Convenience method for creating a GraphAchievement collection. + * + * @return GraphAchievement + * + * @throws FacebookSDKException + */ + public function makeGraphAchievement() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAchievement'); + } + + /** + * Convenience method for creating a GraphAlbum collection. + * + * @return GraphAlbum + * + * @throws FacebookSDKException + */ + public function makeGraphAlbum() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphAlbum'); + } + + /** + * Convenience method for creating a GraphPage collection. + * + * @return GraphPage + * + * @throws FacebookSDKException + */ + public function makeGraphPage() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphPage'); + } + + /** + * Convenience method for creating a GraphSessionInfo collection. + * + * @return GraphSessionInfo + * + * @throws FacebookSDKException + */ + public function makeGraphSessionInfo() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphSessionInfo'); + } + + /** + * Convenience method for creating a GraphUser collection. + * + * @return GraphUser + * + * @throws FacebookSDKException + */ + public function makeGraphUser() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphUser'); + } + + /** + * Convenience method for creating a GraphEvent collection. + * + * @return GraphEvent + * + * @throws FacebookSDKException + */ + public function makeGraphEvent() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphEvent'); + } + + /** + * Convenience method for creating a GraphGroup collection. + * + * @return GraphGroup + * + * @throws FacebookSDKException + */ + public function makeGraphGroup() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphGroup'); + } + + /** + * Tries to convert a FacebookResponse entity into a GraphEdge. + * + * @param string|null $subclassName The GraphNode sub class to cast the list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return GraphEdge + * + * @throws FacebookSDKException + */ + public function makeGraphEdge($subclassName = null, $auto_prefix = true) + { + $this->validateResponseAsArray(); + $this->validateResponseCastableAsGraphEdge(); + + if ($subclassName && $auto_prefix) { + $subclassName = static::BASE_GRAPH_OBJECT_PREFIX . $subclassName; + } + + return $this->castAsGraphNodeOrGraphEdge($this->decodedBody, $subclassName); + } + + /** + * Validates the decoded body. + * + * @throws FacebookSDKException + */ + public function validateResponseAsArray() + { + if (!is_array($this->decodedBody)) { + throw new FacebookSDKException('Unable to get response from Graph as array.', 620); + } + } + + /** + * Validates that the return data can be cast as a GraphNode. + * + * @throws FacebookSDKException + */ + public function validateResponseCastableAsGraphNode() + { + if (isset($this->decodedBody['data']) && static::isCastableAsGraphEdge($this->decodedBody['data'])) { + throw new FacebookSDKException( + 'Unable to convert response from Graph to a GraphNode because the response looks like a GraphEdge. Try using GraphNodeFactory::makeGraphEdge() instead.', + 620 + ); + } + } + + /** + * Validates that the return data can be cast as a GraphEdge. + * + * @throws FacebookSDKException + */ + public function validateResponseCastableAsGraphEdge() + { + if (!(isset($this->decodedBody['data']) && static::isCastableAsGraphEdge($this->decodedBody['data']))) { + throw new FacebookSDKException( + 'Unable to convert response from Graph to a GraphEdge because the response does not look like a GraphEdge. Try using GraphNodeFactory::makeGraphNode() instead.', + 620 + ); + } + } + + /** + * Safely instantiates a GraphNode of $subclassName. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The subclass to cast this collection to. + * + * @return GraphNode + * + * @throws FacebookSDKException + */ + public function safelyMakeGraphNode(array $data, $subclassName = null) + { + $subclassName = $subclassName ?: static::BASE_GRAPH_NODE_CLASS; + static::validateSubclass($subclassName); + + // Remember the parent node ID + $parentNodeId = isset($data['id']) ? $data['id'] : null; + + $items = []; + + foreach ($data as $k => $v) { + // Array means could be recurable + if (is_array($v)) { + // Detect any smart-casting from the $graphObjectMap array. + // This is always empty on the GraphNode collection, but subclasses can define + // their own array of smart-casting types. + $graphObjectMap = $subclassName::getObjectMap(); + $objectSubClass = isset($graphObjectMap[$k]) + ? $graphObjectMap[$k] + : null; + + // Could be a GraphEdge or GraphNode + $items[$k] = $this->castAsGraphNodeOrGraphEdge($v, $objectSubClass, $k, $parentNodeId); + } else { + $items[$k] = $v; + } + } + + return new $subclassName($items); + } + + /** + * Takes an array of values and determines how to cast each node. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The subclass to cast this collection to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. + * + * @return GraphNode|GraphEdge + * + * @throws FacebookSDKException + */ + public function castAsGraphNodeOrGraphEdge(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + { + if (isset($data['data'])) { + // Create GraphEdge + if (static::isCastableAsGraphEdge($data['data'])) { + return $this->safelyMakeGraphEdge($data, $subclassName, $parentKey, $parentNodeId); + } + // Sometimes Graph is a weirdo and returns a GraphNode under the "data" key + $outerData = $data; + unset($outerData['data']); + $data = $data['data'] + $outerData; + } + + // Create GraphNode + return $this->safelyMakeGraphNode($data, $subclassName); + } + + /** + * Return an array of GraphNode's. + * + * @param array $data The array of data to iterate over. + * @param string|null $subclassName The GraphNode subclass to cast each item in the list to. + * @param string|null $parentKey The key of this data (Graph edge). + * @param string|null $parentNodeId The parent Graph node ID. + * + * @return GraphEdge + * + * @throws FacebookSDKException + */ + public function safelyMakeGraphEdge(array $data, $subclassName = null, $parentKey = null, $parentNodeId = null) + { + if (!isset($data['data'])) { + throw new FacebookSDKException('Cannot cast data to GraphEdge. Expected a "data" key.', 620); + } + + $dataList = []; + foreach ($data['data'] as $graphNode) { + $dataList[] = $this->safelyMakeGraphNode($graphNode, $subclassName); + } + + $metaData = $this->getMetaData($data); + + // We'll need to make an edge endpoint for this in case it's a GraphEdge (for cursor pagination) + $parentGraphEdgeEndpoint = $parentNodeId && $parentKey ? '/' . $parentNodeId . '/' . $parentKey : null; + $className = static::BASE_GRAPH_EDGE_CLASS; + + return new $className($this->response->getRequest(), $dataList, $metaData, $parentGraphEdgeEndpoint, $subclassName); + } + + /** + * Get the meta data from a list in a Graph response. + * + * @param array $data The Graph response. + * + * @return array + */ + public function getMetaData(array $data) + { + unset($data['data']); + + return $data; + } + + /** + * Determines whether or not the data should be cast as a GraphEdge. + * + * @param array $data + * + * @return boolean + */ + public static function isCastableAsGraphEdge(array $data) + { + if ($data === []) { + return true; + } + + // Checks for a sequential numeric array which would be a GraphEdge + return array_keys($data) === range(0, count($data) - 1); + } + + /** + * Ensures that the subclass in question is valid. + * + * @param string $subclassName The GraphNode subclass to validate. + * + * @throws FacebookSDKException + */ + public static function validateSubclass($subclassName) + { + if ($subclassName == static::BASE_GRAPH_NODE_CLASS || is_subclass_of($subclassName, static::BASE_GRAPH_NODE_CLASS)) { + return; + } + + throw new FacebookSDKException('The given subclass "' . $subclassName . '" is not valid. Cannot cast to an object that is not a GraphNode subclass.', 620); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphObject.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphObject.php new file mode 100755 index 00000000..0633c405 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphObject.php @@ -0,0 +1,36 @@ +makeGraphNode($subclassName); + } + + /** + * Convenience method for creating a GraphEvent collection. + * + * @return GraphEvent + * + * @throws FacebookSDKException + */ + public function makeGraphEvent() + { + return $this->makeGraphNode(static::BASE_GRAPH_OBJECT_PREFIX . 'GraphEvent'); + } + + /** + * Tries to convert a FacebookResponse entity into a GraphEdge. + * + * @param string|null $subclassName The GraphNode sub class to cast the list items to. + * @param boolean $auto_prefix Toggle to auto-prefix the subclass name. + * + * @return GraphEdge + * + * @deprecated 5.0.0 GraphObjectFactory has been renamed to GraphNodeFactory + */ + public function makeGraphList($subclassName = null, $auto_prefix = true) + { + return $this->makeGraphEdge($subclassName, $auto_prefix); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphPage.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphPage.php new file mode 100755 index 00000000..503b96b5 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphPage.php @@ -0,0 +1,157 @@ + '\Facebook\GraphNodes\GraphPage', + 'global_brand_parent_page' => '\Facebook\GraphNodes\GraphPage', + 'location' => '\Facebook\GraphNodes\GraphLocation', + 'cover' => '\Facebook\GraphNodes\GraphCoverPhoto', + 'picture' => '\Facebook\GraphNodes\GraphPicture', + ]; + + /** + * Returns the ID for the user's page as a string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getField('id'); + } + + /** + * Returns the Category for the user's page as a string if present. + * + * @return string|null + */ + public function getCategory() + { + return $this->getField('category'); + } + + /** + * Returns the Name of the user's page as a string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getField('name'); + } + + /** + * Returns the best available Page on Facebook. + * + * @return GraphPage|null + */ + public function getBestPage() + { + return $this->getField('best_page'); + } + + /** + * Returns the brand's global (parent) Page. + * + * @return GraphPage|null + */ + public function getGlobalBrandParentPage() + { + return $this->getField('global_brand_parent_page'); + } + + /** + * Returns the location of this place. + * + * @return GraphLocation|null + */ + public function getLocation() + { + return $this->getField('location'); + } + + /** + * Returns CoverPhoto of the Page. + * + * @return GraphCoverPhoto|null + */ + public function getCover() + { + return $this->getField('cover'); + } + + /** + * Returns Picture of the Page. + * + * @return GraphPicture|null + */ + public function getPicture() + { + return $this->getField('picture'); + } + + /** + * Returns the page access token for the admin user. + * + * Only available in the `/me/accounts` context. + * + * @return string|null + */ + public function getAccessToken() + { + return $this->getField('access_token'); + } + + /** + * Returns the roles of the page admin user. + * + * Only available in the `/me/accounts` context. + * + * @return array|null + */ + public function getPerms() + { + return $this->getField('perms'); + } + + /** + * Returns the `fan_count` (Number of people who likes to page) as int if present. + * + * @return int|null + */ + public function getFanCount() + { + return $this->getField('fan_count'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphPicture.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphPicture.php new file mode 100755 index 00000000..10274ec5 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphPicture.php @@ -0,0 +1,72 @@ +getField('is_silhouette'); + } + + /** + * Returns the url of user picture if it exists + * + * @return string|null + */ + public function getUrl() + { + return $this->getField('url'); + } + + /** + * Returns the width of user picture if it exists + * + * @return int|null + */ + public function getWidth() + { + return $this->getField('width'); + } + + /** + * Returns the height of user picture if it exists + * + * @return int|null + */ + public function getHeight() + { + return $this->getField('height'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphSessionInfo.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphSessionInfo.php new file mode 100755 index 00000000..df8dd358 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphSessionInfo.php @@ -0,0 +1,102 @@ +getField('app_id'); + } + + /** + * Returns the application name the token was issued for. + * + * @return string|null + */ + public function getApplication() + { + return $this->getField('application'); + } + + /** + * Returns the date & time that the token expires. + * + * @return \DateTime|null + */ + public function getExpiresAt() + { + return $this->getField('expires_at'); + } + + /** + * Returns whether the token is valid. + * + * @return boolean + */ + public function getIsValid() + { + return $this->getField('is_valid'); + } + + /** + * Returns the date & time the token was issued at. + * + * @return \DateTime|null + */ + public function getIssuedAt() + { + return $this->getField('issued_at'); + } + + /** + * Returns the scope permissions associated with the token. + * + * @return array + */ + public function getScopes() + { + return $this->getField('scopes'); + } + + /** + * Returns the login id of the user associated with the token. + * + * @return string|null + */ + public function getUserId() + { + return $this->getField('user_id'); + } +} diff --git a/inc/vendors/social-login/Facebook/GraphNodes/GraphUser.php b/inc/vendors/social-login/Facebook/GraphNodes/GraphUser.php new file mode 100755 index 00000000..6e1ed8f5 --- /dev/null +++ b/inc/vendors/social-login/Facebook/GraphNodes/GraphUser.php @@ -0,0 +1,172 @@ + '\Facebook\GraphNodes\GraphPage', + 'location' => '\Facebook\GraphNodes\GraphPage', + 'significant_other' => '\Facebook\GraphNodes\GraphUser', + 'picture' => '\Facebook\GraphNodes\GraphPicture', + ]; + + /** + * Returns the ID for the user as a string if present. + * + * @return string|null + */ + public function getId() + { + return $this->getField('id'); + } + + /** + * Returns the name for the user as a string if present. + * + * @return string|null + */ + public function getName() + { + return $this->getField('name'); + } + + /** + * Returns the first name for the user as a string if present. + * + * @return string|null + */ + public function getFirstName() + { + return $this->getField('first_name'); + } + + /** + * Returns the middle name for the user as a string if present. + * + * @return string|null + */ + public function getMiddleName() + { + return $this->getField('middle_name'); + } + + /** + * Returns the last name for the user as a string if present. + * + * @return string|null + */ + public function getLastName() + { + return $this->getField('last_name'); + } + + /** + * Returns the email for the user as a string if present. + * + * @return string|null + */ + public function getEmail() + { + return $this->getField('email'); + } + + /** + * Returns the gender for the user as a string if present. + * + * @return string|null + */ + public function getGender() + { + return $this->getField('gender'); + } + + /** + * Returns the Facebook URL for the user as a string if available. + * + * @return string|null + */ + public function getLink() + { + return $this->getField('link'); + } + + /** + * Returns the users birthday, if available. + * + * @return Birthday|null + */ + public function getBirthday() + { + return $this->getField('birthday'); + } + + /** + * Returns the current location of the user as a GraphPage. + * + * @return GraphPage|null + */ + public function getLocation() + { + return $this->getField('location'); + } + + /** + * Returns the current location of the user as a GraphPage. + * + * @return GraphPage|null + */ + public function getHometown() + { + return $this->getField('hometown'); + } + + /** + * Returns the current location of the user as a GraphUser. + * + * @return GraphUser|null + */ + public function getSignificantOther() + { + return $this->getField('significant_other'); + } + + /** + * Returns the picture of the user as a GraphPicture + * + * @return GraphPicture|null + */ + public function getPicture() + { + return $this->getField('picture'); + } +} diff --git a/inc/vendors/social-login/Facebook/Helpers/FacebookCanvasHelper.php b/inc/vendors/social-login/Facebook/Helpers/FacebookCanvasHelper.php new file mode 100755 index 00000000..7f3466ff --- /dev/null +++ b/inc/vendors/social-login/Facebook/Helpers/FacebookCanvasHelper.php @@ -0,0 +1,52 @@ +signedRequest ? $this->signedRequest->get('app_data') : null; + } + + /** + * Get raw signed request from POST. + * + * @return string|null + */ + public function getRawSignedRequest() + { + return $this->getRawSignedRequestFromPost() ?: null; + } +} diff --git a/inc/vendors/social-login/Facebook/Helpers/FacebookJavaScriptHelper.php b/inc/vendors/social-login/Facebook/Helpers/FacebookJavaScriptHelper.php new file mode 100755 index 00000000..01a76b8b --- /dev/null +++ b/inc/vendors/social-login/Facebook/Helpers/FacebookJavaScriptHelper.php @@ -0,0 +1,42 @@ +getRawSignedRequestFromCookie(); + } +} diff --git a/inc/vendors/social-login/Facebook/Helpers/FacebookPageTabHelper.php b/inc/vendors/social-login/Facebook/Helpers/FacebookPageTabHelper.php new file mode 100755 index 00000000..da2c356c --- /dev/null +++ b/inc/vendors/social-login/Facebook/Helpers/FacebookPageTabHelper.php @@ -0,0 +1,95 @@ +signedRequest) { + return; + } + + $this->pageData = $this->signedRequest->get('page'); + } + + /** + * Returns a value from the page data. + * + * @param string $key + * @param mixed|null $default + * + * @return mixed|null + */ + public function getPageData($key, $default = null) + { + if (isset($this->pageData[$key])) { + return $this->pageData[$key]; + } + + return $default; + } + + /** + * Returns true if the user is an admin. + * + * @return boolean + */ + public function isAdmin() + { + return $this->getPageData('admin') === true; + } + + /** + * Returns the page id if available. + * + * @return string|null + */ + public function getPageId() + { + return $this->getPageData('id'); + } +} diff --git a/inc/vendors/social-login/Facebook/Helpers/FacebookRedirectLoginHelper.php b/inc/vendors/social-login/Facebook/Helpers/FacebookRedirectLoginHelper.php new file mode 100755 index 00000000..6003a20f --- /dev/null +++ b/inc/vendors/social-login/Facebook/Helpers/FacebookRedirectLoginHelper.php @@ -0,0 +1,333 @@ +oAuth2Client = $oAuth2Client; + $this->persistentDataHandler = $persistentDataHandler ?: new FacebookSessionPersistentDataHandler(); + $this->urlDetectionHandler = $urlHandler ?: new FacebookUrlDetectionHandler(); + $this->pseudoRandomStringGenerator = PseudoRandomStringGeneratorFactory::createPseudoRandomStringGenerator($prsg); + } + + /** + * Returns the persistent data handler. + * + * @return PersistentDataInterface + */ + public function getPersistentDataHandler() + { + return $this->persistentDataHandler; + } + + /** + * Returns the URL detection handler. + * + * @return UrlDetectionInterface + */ + public function getUrlDetectionHandler() + { + return $this->urlDetectionHandler; + } + + /** + * Returns the cryptographically secure pseudo-random string generator. + * + * @return PseudoRandomStringGeneratorInterface + */ + public function getPseudoRandomStringGenerator() + { + return $this->pseudoRandomStringGenerator; + } + + /** + * Stores CSRF state and returns a URL to which the user should be sent to in order to continue the login process with Facebook. + * + * @param string $redirectUrl The URL Facebook should redirect users to after login. + * @param array $scope List of permissions to request during login. + * @param array $params An array of parameters to generate URL. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + private function makeUrl($redirectUrl, array $scope, array $params = [], $separator = '&') + { + $state = $this->persistentDataHandler->get('state') ?: $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); + $this->persistentDataHandler->set('state', $state); + + return $this->oAuth2Client->getAuthorizationUrl($redirectUrl, $state, $scope, $params, $separator); + } + + /** + * Returns the URL to send the user in order to login to Facebook. + * + * @param string $redirectUrl The URL Facebook should redirect users to after login. + * @param array $scope List of permissions to request during login. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getLoginUrl($redirectUrl, array $scope = [], $separator = '&') + { + return $this->makeUrl($redirectUrl, $scope, [], $separator); + } + + /** + * Returns the URL to send the user in order to log out of Facebook. + * + * @param AccessToken|string $accessToken The access token that will be logged out. + * @param string $next The url Facebook should redirect the user to after a successful logout. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + * + * @throws FacebookSDKException + */ + public function getLogoutUrl($accessToken, $next, $separator = '&') + { + if (!$accessToken instanceof AccessToken) { + $accessToken = new AccessToken($accessToken); + } + + if ($accessToken->isAppAccessToken()) { + throw new FacebookSDKException('Cannot generate a logout URL with an app access token.', 722); + } + + $params = [ + 'next' => $next, + 'access_token' => $accessToken->getValue(), + ]; + + return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, $separator); + } + + /** + * Returns the URL to send the user in order to login to Facebook with permission(s) to be re-asked. + * + * @param string $redirectUrl The URL Facebook should redirect users to after login. + * @param array $scope List of permissions to request during login. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getReRequestUrl($redirectUrl, array $scope = [], $separator = '&') + { + $params = ['auth_type' => 'rerequest']; + + return $this->makeUrl($redirectUrl, $scope, $params, $separator); + } + + /** + * Returns the URL to send the user in order to login to Facebook with user to be re-authenticated. + * + * @param string $redirectUrl The URL Facebook should redirect users to after login. + * @param array $scope List of permissions to request during login. + * @param string $separator The separator to use in http_build_query(). + * + * @return string + */ + public function getReAuthenticationUrl($redirectUrl, array $scope = [], $separator = '&') + { + $params = ['auth_type' => 'reauthenticate']; + + return $this->makeUrl($redirectUrl, $scope, $params, $separator); + } + + /** + * Takes a valid code from a login redirect, and returns an AccessToken entity. + * + * @param string|null $redirectUrl The redirect URL. + * + * @return AccessToken|null + * + * @throws FacebookSDKException + */ + public function getAccessToken($redirectUrl = null) + { + if (!$code = $this->getCode()) { + return null; + } + + $this->validateCsrf(); + $this->resetCsrf(); + + $redirectUrl = $redirectUrl ?: $this->urlDetectionHandler->getCurrentUrl(); + // At minimum we need to remove the 'code', 'enforce_https' and 'state' params + $redirectUrl = FacebookUrlManipulator::removeParamsFromUrl($redirectUrl, ['code', 'enforce_https', 'state']); + + return $this->oAuth2Client->getAccessTokenFromCode($code, $redirectUrl); + } + + /** + * Validate the request against a cross-site request forgery. + * + * @throws FacebookSDKException + */ + protected function validateCsrf() + { + $state = $this->getState(); + if (!$state) { + throw new FacebookSDKException('Cross-site request forgery validation failed. Required GET param "state" missing.'); + } + $savedState = $this->persistentDataHandler->get('state'); + if (!$savedState) { + throw new FacebookSDKException('Cross-site request forgery validation failed. Required param "state" missing from persistent data.'); + } + + if (\hash_equals($savedState, $state)) { + return; + } + + throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.'); + } + + /** + * Resets the CSRF so that it doesn't get reused. + */ + private function resetCsrf() + { + $this->persistentDataHandler->set('state', null); + } + + /** + * Return the code. + * + * @return string|null + */ + protected function getCode() + { + return $this->getInput('code'); + } + + /** + * Return the state. + * + * @return string|null + */ + protected function getState() + { + return $this->getInput('state'); + } + + /** + * Return the error code. + * + * @return string|null + */ + public function getErrorCode() + { + return $this->getInput('error_code'); + } + + /** + * Returns the error. + * + * @return string|null + */ + public function getError() + { + return $this->getInput('error'); + } + + /** + * Returns the error reason. + * + * @return string|null + */ + public function getErrorReason() + { + return $this->getInput('error_reason'); + } + + /** + * Returns the error description. + * + * @return string|null + */ + public function getErrorDescription() + { + return $this->getInput('error_description'); + } + + /** + * Returns a value from a GET param. + * + * @param string $key + * + * @return string|null + */ + private function getInput($key) + { + return isset($_GET[$key]) ? $_GET[$key] : null; + } +} diff --git a/inc/vendors/social-login/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php b/inc/vendors/social-login/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php new file mode 100755 index 00000000..4044da10 --- /dev/null +++ b/inc/vendors/social-login/Facebook/Helpers/FacebookSignedRequestFromInputHelper.php @@ -0,0 +1,166 @@ +app = $app; + $graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; + $this->oAuth2Client = new OAuth2Client($this->app, $client, $graphVersion); + + $this->instantiateSignedRequest(); + } + + /** + * Instantiates a new SignedRequest entity. + * + * @param string|null + */ + public function instantiateSignedRequest($rawSignedRequest = null) + { + $rawSignedRequest = $rawSignedRequest ?: $this->getRawSignedRequest(); + + if (!$rawSignedRequest) { + return; + } + + $this->signedRequest = new SignedRequest($this->app, $rawSignedRequest); + } + + /** + * Returns an AccessToken entity from the signed request. + * + * @return AccessToken|null + * + * @throws \Facebook\Exceptions\FacebookSDKException + */ + public function getAccessToken() + { + if ($this->signedRequest && $this->signedRequest->hasOAuthData()) { + $code = $this->signedRequest->get('code'); + $accessToken = $this->signedRequest->get('oauth_token'); + + if ($code && !$accessToken) { + return $this->oAuth2Client->getAccessTokenFromCode($code); + } + + $expiresAt = $this->signedRequest->get('expires', 0); + + return new AccessToken($accessToken, $expiresAt); + } + + return null; + } + + /** + * Returns the SignedRequest entity. + * + * @return SignedRequest|null + */ + public function getSignedRequest() + { + return $this->signedRequest; + } + + /** + * Returns the user_id if available. + * + * @return string|null + */ + public function getUserId() + { + return $this->signedRequest ? $this->signedRequest->getUserId() : null; + } + + /** + * Get raw signed request from input. + * + * @return string|null + */ + abstract public function getRawSignedRequest(); + + /** + * Get raw signed request from POST input. + * + * @return string|null + */ + public function getRawSignedRequestFromPost() + { + if (isset($_POST['signed_request'])) { + return $_POST['signed_request']; + } + + return null; + } + + /** + * Get raw signed request from cookie set from the Javascript SDK. + * + * @return string|null + */ + public function getRawSignedRequestFromCookie() + { + if (isset($_COOKIE['fbsr_' . $this->app->getId()])) { + return $_COOKIE['fbsr_' . $this->app->getId()]; + } + + return null; + } +} diff --git a/inc/vendors/social-login/Facebook/Http/GraphRawResponse.php b/inc/vendors/social-login/Facebook/Http/GraphRawResponse.php new file mode 100755 index 00000000..44105c49 --- /dev/null +++ b/inc/vendors/social-login/Facebook/Http/GraphRawResponse.php @@ -0,0 +1,138 @@ +httpResponseCode = (int)$httpStatusCode; + } + + if (is_array($headers)) { + $this->headers = $headers; + } else { + $this->setHeadersFromString($headers); + } + + $this->body = $body; + } + + /** + * Return the response headers. + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Return the body of the response. + * + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * Return the HTTP response code. + * + * @return int + */ + public function getHttpResponseCode() + { + return $this->httpResponseCode; + } + + /** + * Sets the HTTP response code from a raw header. + * + * @param string $rawResponseHeader + */ + public function setHttpResponseCodeFromHeader($rawResponseHeader) + { + // https://tools.ietf.org/html/rfc7230#section-3.1.2 + list($version, $status, $reason) = array_pad(explode(' ', $rawResponseHeader, 3), 3, null); + $this->httpResponseCode = (int) $status; + } + + /** + * Parse the raw headers and set as an array. + * + * @param string $rawHeaders The raw headers from the response. + */ + protected function setHeadersFromString($rawHeaders) + { + // Normalize line breaks + $rawHeaders = str_replace("\r\n", "\n", $rawHeaders); + + // There will be multiple headers if a 301 was followed + // or a proxy was followed, etc + $headerCollection = explode("\n\n", trim($rawHeaders)); + // We just want the last response (at the end) + $rawHeader = array_pop($headerCollection); + + $headerComponents = explode("\n", $rawHeader); + foreach ($headerComponents as $line) { + if (strpos($line, ': ') === false) { + $this->setHttpResponseCodeFromHeader($line); + } else { + list($key, $value) = explode(': ', $line, 2); + $this->headers[$key] = $value; + } + } + } +} diff --git a/inc/vendors/social-login/Facebook/Http/RequestBodyInterface.php b/inc/vendors/social-login/Facebook/Http/RequestBodyInterface.php new file mode 100755 index 00000000..1c03f4fd --- /dev/null +++ b/inc/vendors/social-login/Facebook/Http/RequestBodyInterface.php @@ -0,0 +1,39 @@ +params = $params; + $this->files = $files; + $this->boundary = $boundary ?: uniqid(); + } + + /** + * @inheritdoc + */ + public function getBody() + { + $body = ''; + + // Compile normal params + $params = $this->getNestedParams($this->params); + foreach ($params as $k => $v) { + $body .= $this->getParamString($k, $v); + } + + // Compile files + foreach ($this->files as $k => $v) { + $body .= $this->getFileString($k, $v); + } + + // Peace out + $body .= "--{$this->boundary}--\r\n"; + + return $body; + } + + /** + * Get the boundary + * + * @return string + */ + public function getBoundary() + { + return $this->boundary; + } + + /** + * Get the string needed to transfer a file. + * + * @param string $name + * @param FacebookFile $file + * + * @return string + */ + private function getFileString($name, FacebookFile $file) + { + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"%s\r\n\r\n%s\r\n", + $this->boundary, + $name, + $file->getFileName(), + $this->getFileHeaders($file), + $file->getContents() + ); + } + + /** + * Get the string needed to transfer a POST field. + * + * @param string $name + * @param string $value + * + * @return string + */ + private function getParamString($name, $value) + { + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", + $this->boundary, + $name, + $value + ); + } + + /** + * Returns the params as an array of nested params. + * + * @param array $params + * + * @return array + */ + private function getNestedParams(array $params) + { + $query = http_build_query($params, null, '&'); + $params = explode('&', $query); + $result = []; + + foreach ($params as $param) { + list($key, $value) = explode('=', $param, 2); + $result[urldecode($key)] = urldecode($value); + } + + return $result; + } + + /** + * Get the headers needed before transferring the content of a POST file. + * + * @param FacebookFile $file + * + * @return string + */ + protected function getFileHeaders(FacebookFile $file) + { + return "\r\nContent-Type: {$file->getMimetype()}"; + } +} diff --git a/inc/vendors/social-login/Facebook/Http/RequestBodyUrlEncoded.php b/inc/vendors/social-login/Facebook/Http/RequestBodyUrlEncoded.php new file mode 100755 index 00000000..c1e35f43 --- /dev/null +++ b/inc/vendors/social-login/Facebook/Http/RequestBodyUrlEncoded.php @@ -0,0 +1,55 @@ +params = $params; + } + + /** + * @inheritdoc + */ + public function getBody() + { + return http_build_query($this->params, null, '&'); + } +} diff --git a/inc/vendors/social-login/Facebook/HttpClients/FacebookCurl.php b/inc/vendors/social-login/Facebook/HttpClients/FacebookCurl.php new file mode 100755 index 00000000..28e4ba59 --- /dev/null +++ b/inc/vendors/social-login/Facebook/HttpClients/FacebookCurl.php @@ -0,0 +1,129 @@ +curl = curl_init(); + } + + /** + * Set a curl option + * + * @param $key + * @param $value + */ + public function setopt($key, $value) + { + curl_setopt($this->curl, $key, $value); + } + + /** + * Set an array of options to a curl resource + * + * @param array $options + */ + public function setoptArray(array $options) + { + curl_setopt_array($this->curl, $options); + } + + /** + * Send a curl request + * + * @return mixed + */ + public function exec() + { + return curl_exec($this->curl); + } + + /** + * Return the curl error number + * + * @return int + */ + public function errno() + { + return curl_errno($this->curl); + } + + /** + * Return the curl error message + * + * @return string + */ + public function error() + { + return curl_error($this->curl); + } + + /** + * Get info from a curl reference + * + * @param $type + * + * @return mixed + */ + public function getinfo($type) + { + return curl_getinfo($this->curl, $type); + } + + /** + * Get the currently installed curl version + * + * @return array + */ + public function version() + { + return curl_version(); + } + + /** + * Close the resource connection to curl + */ + public function close() + { + curl_close($this->curl); + } +} diff --git a/inc/vendors/social-login/Facebook/HttpClients/FacebookCurlHttpClient.php b/inc/vendors/social-login/Facebook/HttpClients/FacebookCurlHttpClient.php new file mode 100755 index 00000000..9516cc83 --- /dev/null +++ b/inc/vendors/social-login/Facebook/HttpClients/FacebookCurlHttpClient.php @@ -0,0 +1,163 @@ +facebookCurl = $facebookCurl ?: new FacebookCurl(); + } + + /** + * @inheritdoc + */ + public function send($url, $method, $body, array $headers, $timeOut) + { + $this->openConnection($url, $method, $body, $headers, $timeOut); + $this->sendRequest(); + + if ($curlErrorCode = $this->facebookCurl->errno()) { + throw new FacebookSDKException($this->facebookCurl->error(), $curlErrorCode); + } + + // Separate the raw headers from the raw body + list($rawHeaders, $rawBody) = $this->extractResponseHeadersAndBody(); + + $this->closeConnection(); + + return new GraphRawResponse($rawHeaders, $rawBody); + } + + /** + * Opens a new curl connection. + * + * @param string $url The endpoint to send the request to. + * @param string $method The request method. + * @param string $body The body of the request. + * @param array $headers The request headers. + * @param int $timeOut The timeout in seconds for the request. + */ + public function openConnection($url, $method, $body, array $headers, $timeOut) + { + $options = [ + CURLOPT_CUSTOMREQUEST => $method, + CURLOPT_HTTPHEADER => $this->compileRequestHeaders($headers), + CURLOPT_URL => $url, + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => $timeOut, + CURLOPT_RETURNTRANSFER => true, // Return response as string + CURLOPT_HEADER => true, // Enable header processing + CURLOPT_SSL_VERIFYHOST => 2, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', + ]; + + if ($method !== "GET") { + $options[CURLOPT_POSTFIELDS] = $body; + } + + $this->facebookCurl->init(); + $this->facebookCurl->setoptArray($options); + } + + /** + * Closes an existing curl connection + */ + public function closeConnection() + { + $this->facebookCurl->close(); + } + + /** + * Send the request and get the raw response from curl + */ + public function sendRequest() + { + $this->rawResponse = $this->facebookCurl->exec(); + } + + /** + * Compiles the request headers into a curl-friendly format. + * + * @param array $headers The request headers. + * + * @return array + */ + public function compileRequestHeaders(array $headers) + { + $return = []; + + foreach ($headers as $key => $value) { + $return[] = $key . ': ' . $value; + } + + return $return; + } + + /** + * Extracts the headers and the body into a two-part array + * + * @return array + */ + public function extractResponseHeadersAndBody() + { + $parts = explode("\r\n\r\n", $this->rawResponse); + $rawBody = array_pop($parts); + $rawHeaders = implode("\r\n\r\n", $parts); + + return [trim($rawHeaders), trim($rawBody)]; + } +} diff --git a/inc/vendors/social-login/Facebook/HttpClients/FacebookGuzzleHttpClient.php b/inc/vendors/social-login/Facebook/HttpClients/FacebookGuzzleHttpClient.php new file mode 100755 index 00000000..8feb7cb6 --- /dev/null +++ b/inc/vendors/social-login/Facebook/HttpClients/FacebookGuzzleHttpClient.php @@ -0,0 +1,97 @@ +guzzleClient = $guzzleClient ?: new Client(); + } + + /** + * @inheritdoc + */ + public function send($url, $method, $body, array $headers, $timeOut) + { + $options = [ + 'headers' => $headers, + 'body' => $body, + 'timeout' => $timeOut, + 'connect_timeout' => 10, + 'verify' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', + ]; + $request = $this->guzzleClient->createRequest($method, $url, $options); + + try { + $rawResponse = $this->guzzleClient->send($request); + } catch (RequestException $e) { + $rawResponse = $e->getResponse(); + + if ($e->getPrevious() instanceof RingException || !$rawResponse instanceof ResponseInterface) { + throw new FacebookSDKException($e->getMessage(), $e->getCode()); + } + } + + $rawHeaders = $this->getHeadersAsString($rawResponse); + $rawBody = $rawResponse->getBody(); + $httpStatusCode = $rawResponse->getStatusCode(); + + return new GraphRawResponse($rawHeaders, $rawBody, $httpStatusCode); + } + + /** + * Returns the Guzzle array of headers as a string. + * + * @param ResponseInterface $response The Guzzle response. + * + * @return string + */ + public function getHeadersAsString(ResponseInterface $response) + { + $headers = $response->getHeaders(); + $rawHeaders = []; + foreach ($headers as $name => $values) { + $rawHeaders[] = $name . ": " . implode(", ", $values); + } + + return implode("\r\n", $rawHeaders); + } +} diff --git a/inc/vendors/social-login/Facebook/HttpClients/FacebookHttpClientInterface.php b/inc/vendors/social-login/Facebook/HttpClients/FacebookHttpClientInterface.php new file mode 100755 index 00000000..1fbf953d --- /dev/null +++ b/inc/vendors/social-login/Facebook/HttpClients/FacebookHttpClientInterface.php @@ -0,0 +1,47 @@ +stream = stream_context_create($options); + } + + /** + * The response headers from the stream wrapper + * + * @return array + */ + public function getResponseHeaders() + { + return $this->responseHeaders; + } + + /** + * Send a stream wrapped request + * + * @param string $url + * + * @return mixed + */ + public function fileGetContents($url) + { + // $rawResponse = file get contents($url, false, $this->stream); + $rawResponse = wp_remote_get($url, ['stream' => $this->stream]); + $this->responseHeaders = $http_response_header ?: []; + + return $rawResponse; + } +} diff --git a/inc/vendors/social-login/Facebook/HttpClients/FacebookStreamHttpClient.php b/inc/vendors/social-login/Facebook/HttpClients/FacebookStreamHttpClient.php new file mode 100755 index 00000000..1cdfd539 --- /dev/null +++ b/inc/vendors/social-login/Facebook/HttpClients/FacebookStreamHttpClient.php @@ -0,0 +1,94 @@ +facebookStream = $facebookStream ?: new FacebookStream(); + } + + /** + * @inheritdoc + */ + public function send($url, $method, $body, array $headers, $timeOut) + { + $options = [ + 'http' => [ + 'method' => $method, + 'header' => $this->compileHeader($headers), + 'content' => $body, + 'timeout' => $timeOut, + 'ignore_errors' => true + ], + 'ssl' => [ + 'verify_peer' => true, + 'verify_peer_name' => true, + 'allow_self_signed' => true, // All root certificates are self-signed + 'cafile' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', + ], + ]; + + $this->facebookStream->streamContextCreate($options); + $rawBody = $this->facebookStream->fileGetContents($url); + $rawHeaders = $this->facebookStream->getResponseHeaders(); + + if ($rawBody === false || empty($rawHeaders)) { + throw new FacebookSDKException('Stream returned an empty response', 660); + } + + $rawHeaders = implode("\r\n", $rawHeaders); + + return new GraphRawResponse($rawHeaders, $rawBody); + } + + /** + * Formats the headers for use in the stream wrapper. + * + * @param array $headers The request headers. + * + * @return string + */ + public function compileHeader(array $headers) + { + $header = []; + foreach ($headers as $k => $v) { + $header[] = $k . ': ' . $v; + } + + return implode("\r\n", $header); + } +} diff --git a/inc/vendors/social-login/Facebook/HttpClients/HttpClientsFactory.php b/inc/vendors/social-login/Facebook/HttpClients/HttpClientsFactory.php new file mode 100755 index 00000000..d9f2a8d3 --- /dev/null +++ b/inc/vendors/social-login/Facebook/HttpClients/HttpClientsFactory.php @@ -0,0 +1,99 @@ +sessionData[$key]) ? $this->sessionData[$key] : null; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + $this->sessionData[$key] = $value; + } +} diff --git a/inc/vendors/social-login/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php b/inc/vendors/social-login/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php new file mode 100755 index 00000000..9123e3dc --- /dev/null +++ b/inc/vendors/social-login/Facebook/PersistentData/FacebookSessionPersistentDataHandler.php @@ -0,0 +1,76 @@ +sessionPrefix . $key])) { + return $_SESSION[$this->sessionPrefix . $key]; + } + + return null; + } + + /** + * @inheritdoc + */ + public function set($key, $value) + { + $_SESSION[$this->sessionPrefix . $key] = $value; + } +} diff --git a/inc/vendors/social-login/Facebook/PersistentData/PersistentDataFactory.php b/inc/vendors/social-login/Facebook/PersistentData/PersistentDataFactory.php new file mode 100755 index 00000000..18fb8fd5 --- /dev/null +++ b/inc/vendors/social-login/Facebook/PersistentData/PersistentDataFactory.php @@ -0,0 +1,65 @@ +validateLength($length); + + $binaryString = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); + + if ($binaryString === false) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'mcrypt_create_iv() returned an error.' + ); + } + + return $this->binToHex($binaryString, $length); + } +} diff --git a/inc/vendors/social-login/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php b/inc/vendors/social-login/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php new file mode 100755 index 00000000..4b4276dc --- /dev/null +++ b/inc/vendors/social-login/Facebook/PseudoRandomString/OpenSslPseudoRandomStringGenerator.php @@ -0,0 +1,67 @@ +validateLength($length); + + $wasCryptographicallyStrong = false; + $binaryString = openssl_random_pseudo_bytes($length, $wasCryptographicallyStrong); + + if ($binaryString === false) { + throw new FacebookSDKException(static::ERROR_MESSAGE . 'openssl_random_pseudo_bytes() returned an unknown error.'); + } + + if ($wasCryptographicallyStrong !== true) { + throw new FacebookSDKException(static::ERROR_MESSAGE . 'openssl_random_pseudo_bytes() returned a pseudo-random string but it was not cryptographically secure and cannot be used.'); + } + + return $this->binToHex($binaryString, $length); + } +} diff --git a/inc/vendors/social-login/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php b/inc/vendors/social-login/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php new file mode 100755 index 00000000..412f4813 --- /dev/null +++ b/inc/vendors/social-login/Facebook/PseudoRandomString/PseudoRandomStringGeneratorFactory.php @@ -0,0 +1,101 @@ +validateLength($length); + + return $this->binToHex(random_bytes($length), $length); + } +} diff --git a/inc/vendors/social-login/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php b/inc/vendors/social-login/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php new file mode 100755 index 00000000..5ab434e6 --- /dev/null +++ b/inc/vendors/social-login/Facebook/PseudoRandomString/UrandomPseudoRandomStringGenerator.php @@ -0,0 +1,89 @@ +validateLength($length); + + $stream = fopen('/dev/urandom', 'rb'); + if (!is_resource($stream)) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'Unable to open stream to /dev/urandom.' + ); + } + + if (!defined('HHVM_VERSION')) { + stream_set_read_buffer($stream, 0); + } + + $binaryString = fread($stream, $length); + fclose($stream); + + if (!$binaryString) { + throw new FacebookSDKException( + static::ERROR_MESSAGE . + 'Stream to /dev/urandom returned no data.' + ); + } + + return $this->binToHex($binaryString, $length); + } +} diff --git a/inc/vendors/social-login/Facebook/SignedRequest.php b/inc/vendors/social-login/Facebook/SignedRequest.php new file mode 100755 index 00000000..6a175a0a --- /dev/null +++ b/inc/vendors/social-login/Facebook/SignedRequest.php @@ -0,0 +1,326 @@ +app = $facebookApp; + + if (!$rawSignedRequest) { + return; + } + + $this->rawSignedRequest = $rawSignedRequest; + + $this->parse(); + } + + /** + * Returns the raw signed request data. + * + * @return string|null + */ + public function getRawSignedRequest() + { + return $this->rawSignedRequest; + } + + /** + * Returns the parsed signed request data. + * + * @return array|null + */ + public function getPayload() + { + return $this->payload; + } + + /** + * Returns a property from the signed request data if available. + * + * @param string $key + * @param mixed|null $default + * + * @return mixed|null + */ + public function get($key, $default = null) + { + if (isset($this->payload[$key])) { + return $this->payload[$key]; + } + + return $default; + } + + /** + * Returns user_id from signed request data if available. + * + * @return string|null + */ + public function getUserId() + { + return $this->get('user_id'); + } + + /** + * Checks for OAuth data in the payload. + * + * @return boolean + */ + public function hasOAuthData() + { + return $this->get('oauth_token') || $this->get('code'); + } + + /** + * Creates a signed request from an array of data. + * + * @param array $payload + * + * @return string + */ + public function make(array $payload) + { + $payload['algorithm'] = isset($payload['algorithm']) ? $payload['algorithm'] : 'HMAC-SHA256'; + $payload['issued_at'] = isset($payload['issued_at']) ? $payload['issued_at'] : time(); + $encodedPayload = $this->base64UrlEncode(json_encode($payload)); + + $hashedSig = $this->hashSignature($encodedPayload); + $encodedSig = $this->base64UrlEncode($hashedSig); + + return $encodedSig . '.' . $encodedPayload; + } + + /** + * Validates and decodes a signed request and saves + * the payload to an array. + */ + protected function parse() + { + list($encodedSig, $encodedPayload) = $this->split(); + + // Signature validation + $sig = $this->decodeSignature($encodedSig); + $hashedSig = $this->hashSignature($encodedPayload); + $this->validateSignature($hashedSig, $sig); + + $this->payload = $this->decodePayload($encodedPayload); + + // Payload validation + $this->validateAlgorithm(); + } + + /** + * Splits a raw signed request into signature and payload. + * + * @return array + * + * @throws FacebookSDKException + */ + protected function split() + { + if (strpos($this->rawSignedRequest, '.') === false) { + throw new FacebookSDKException('Malformed signed request.', 606); + } + + return explode('.', $this->rawSignedRequest, 2); + } + + /** + * Decodes the raw signature from a signed request. + * + * @param string $encodedSig + * + * @return string + * + * @throws FacebookSDKException + */ + protected function decodeSignature($encodedSig) + { + $sig = $this->base64UrlDecode($encodedSig); + + if (!$sig) { + throw new FacebookSDKException('Signed request has malformed encoded signature data.', 607); + } + + return $sig; + } + + /** + * Decodes the raw payload from a signed request. + * + * @param string $encodedPayload + * + * @return array + * + * @throws FacebookSDKException + */ + protected function decodePayload($encodedPayload) + { + $payload = $this->base64UrlDecode($encodedPayload); + + if ($payload) { + $payload = json_decode($payload, true); + } + + if (!is_array($payload)) { + throw new FacebookSDKException('Signed request has malformed encoded payload data.', 607); + } + + return $payload; + } + + /** + * Validates the algorithm used in a signed request. + * + * @throws FacebookSDKException + */ + protected function validateAlgorithm() + { + if ($this->get('algorithm') !== 'HMAC-SHA256') { + throw new FacebookSDKException('Signed request is using the wrong algorithm.', 605); + } + } + + /** + * Hashes the signature used in a signed request. + * + * @param string $encodedData + * + * @return string + * + * @throws FacebookSDKException + */ + protected function hashSignature($encodedData) + { + $hashedSig = hash_hmac( + 'sha256', + $encodedData, + $this->app->getSecret(), + $raw_output = true + ); + + if (!$hashedSig) { + throw new FacebookSDKException('Unable to hash signature from encoded payload data.', 602); + } + + return $hashedSig; + } + + /** + * Validates the signature used in a signed request. + * + * @param string $hashedSig + * @param string $sig + * + * @throws FacebookSDKException + */ + protected function validateSignature($hashedSig, $sig) + { + if (\hash_equals($hashedSig, $sig)) { + return; + } + + throw new FacebookSDKException('Signed request has an invalid signature.', 602); + } + + /** + * Base64 decoding which replaces characters: + * + instead of - + * / instead of _ + * + * @link http://en.wikipedia.org/wiki/Base64#URL_applications + * + * @param string $input base64 url encoded input + * + * @return string decoded string + */ + public function base64UrlDecode($input) + { + $urlDecodedBase64 = strtr($input, '-_', '+/'); + $this->validateBase64($urlDecodedBase64); + + return base64_decode($urlDecodedBase64); + } + + /** + * Base64 encoding which replaces characters: + * + instead of - + * / instead of _ + * + * @link http://en.wikipedia.org/wiki/Base64#URL_applications + * + * @param string $input string to encode + * + * @return string base64 url encoded input + */ + public function base64UrlEncode($input) + { + return strtr(base64_encode($input), '+/', '-_'); + } + + /** + * Validates a base64 string. + * + * @param string $input base64 value to validate + * + * @throws FacebookSDKException + */ + protected function validateBase64($input) + { + if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $input)) { + throw new FacebookSDKException('Signed request contains malformed base64 encoding.', 608); + } + } +} diff --git a/inc/vendors/social-login/Facebook/Url/FacebookUrlDetectionHandler.php b/inc/vendors/social-login/Facebook/Url/FacebookUrlDetectionHandler.php new file mode 100755 index 00000000..1d134ddc --- /dev/null +++ b/inc/vendors/social-login/Facebook/Url/FacebookUrlDetectionHandler.php @@ -0,0 +1,182 @@ +getHttpScheme() . '://' . $this->getHostName() . $this->getServerVar('REQUEST_URI'); + } + + /** + * Get the currently active URL scheme. + * + * @return string + */ + protected function getHttpScheme() + { + return $this->isBehindSsl() ? 'https' : 'http'; + } + + /** + * Tries to detect if the server is running behind an SSL. + * + * @return boolean + */ + protected function isBehindSsl() + { + // Check for proxy first + $protocol = $this->getHeader('X_FORWARDED_PROTO'); + if ($protocol) { + return $this->protocolWithActiveSsl($protocol); + } + + $protocol = $this->getServerVar('HTTPS'); + if ($protocol) { + return $this->protocolWithActiveSsl($protocol); + } + + return (string)$this->getServerVar('SERVER_PORT') === '443'; + } + + /** + * Detects an active SSL protocol value. + * + * @param string $protocol + * + * @return boolean + */ + protected function protocolWithActiveSsl($protocol) + { + $protocol = strtolower((string)$protocol); + + return in_array($protocol, ['on', '1', 'https', 'ssl'], true); + } + + /** + * Tries to detect the host name of the server. + * + * Some elements adapted from + * + * @see https://github.com/symfony/HttpFoundation/blob/master/Request.php + * + * @return string + */ + protected function getHostName() + { + // Check for proxy first + $header = $this->getHeader('X_FORWARDED_HOST'); + if ($header && $this->isValidForwardedHost($header)) { + $elements = explode(',', $header); + $host = $elements[count($elements) - 1]; + } elseif (!$host = $this->getHeader('HOST')) { + if (!$host = $this->getServerVar('SERVER_NAME')) { + $host = $this->getServerVar('SERVER_ADDR'); + } + } + + // trim and remove port number from host + // host is lowercase as per RFC 952/2181 + $host = strtolower(preg_replace('/:\d+$/', '', trim($host))); + + // Port number + $scheme = $this->getHttpScheme(); + $port = $this->getCurrentPort(); + $appendPort = ':' . $port; + + // Don't append port number if a normal port. + if (($scheme == 'http' && $port == '80') || ($scheme == 'https' && $port == '443')) { + $appendPort = ''; + } + + return $host . $appendPort; + } + + protected function getCurrentPort() + { + // Check for proxy first + $port = $this->getHeader('X_FORWARDED_PORT'); + if ($port) { + return (string)$port; + } + + $protocol = (string)$this->getHeader('X_FORWARDED_PROTO'); + if ($protocol === 'https') { + return '443'; + } + + return (string)$this->getServerVar('SERVER_PORT'); + } + + /** + * Returns the a value from the $_SERVER super global. + * + * @param string $key + * + * @return string + */ + protected function getServerVar($key) + { + return isset($_SERVER[$key]) ? $_SERVER[$key] : ''; + } + + /** + * Gets a value from the HTTP request headers. + * + * @param string $key + * + * @return string + */ + protected function getHeader($key) + { + return $this->getServerVar('HTTP_' . $key); + } + + /** + * Checks if the value in X_FORWARDED_HOST is a valid hostname + * Could prevent unintended redirections + * + * @param string $header + * + * @return boolean + */ + protected function isValidForwardedHost($header) + { + $elements = explode(',', $header); + $host = $elements[count($elements) - 1]; + + return preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $host) //valid chars check + && 0 < strlen($host) && strlen($host) < 254 //overall length check + && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $host); //length of each label + } +} diff --git a/inc/vendors/social-login/Facebook/Url/FacebookUrlManipulator.php b/inc/vendors/social-login/Facebook/Url/FacebookUrlManipulator.php new file mode 100755 index 00000000..daeab9c5 --- /dev/null +++ b/inc/vendors/social-login/Facebook/Url/FacebookUrlManipulator.php @@ -0,0 +1,167 @@ + 0) { + $query = '?' . http_build_query($params, null, '&'); + } + } + + $scheme = isset($parts['scheme']) ? $parts['scheme'] . '://' : ''; + $host = isset($parts['host']) ? $parts['host'] : ''; + $port = isset($parts['port']) ? ':' . $parts['port'] : ''; + $path = isset($parts['path']) ? $parts['path'] : ''; + $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; + + return $scheme . $host . $port . $path . $query . $fragment; + } + + /** + * Gracefully appends params to the URL. + * + * @param string $url The URL that will receive the params. + * @param array $newParams The params to append to the URL. + * + * @return string + */ + public static function appendParamsToUrl($url, array $newParams = []) + { + if (empty($newParams)) { + return $url; + } + + if (strpos($url, '?') === false) { + return $url . '?' . http_build_query($newParams, null, '&'); + } + + list($path, $query) = explode('?', $url, 2); + $existingParams = []; + parse_str($query, $existingParams); + + // Favor params from the original URL over $newParams + $newParams = array_merge($newParams, $existingParams); + + // Sort for a predicable order + ksort($newParams); + + return $path . '?' . http_build_query($newParams, null, '&'); + } + + /** + * Returns the params from a URL in the form of an array. + * + * @param string $url The URL to parse the params from. + * + * @return array + */ + public static function getParamsAsArray($url) + { + $query = parse_url($url, PHP_URL_QUERY); + if (!$query) { + return []; + } + $params = []; + parse_str($query, $params); + + return $params; + } + + /** + * Adds the params of the first URL to the second URL. + * + * Any params that already exist in the second URL will go untouched. + * + * @param string $urlToStealFrom The URL harvest the params from. + * @param string $urlToAddTo The URL that will receive the new params. + * + * @return string The $urlToAddTo with any new params from $urlToStealFrom. + */ + public static function mergeUrlParams($urlToStealFrom, $urlToAddTo) + { + $newParams = static::getParamsAsArray($urlToStealFrom); + // Nothing new to add, return as-is + if (!$newParams) { + return $urlToAddTo; + } + + return static::appendParamsToUrl($urlToAddTo, $newParams); + } + + /** + * Check for a "/" prefix and prepend it if not exists. + * + * @param string|null $string + * + * @return string|null + */ + public static function forceSlashPrefix($string) + { + if (!$string) { + return $string; + } + + return strpos($string, '/') === 0 ? $string : '/' . $string; + } + + /** + * Trims off the hostname and Graph version from a URL. + * + * @param string $urlToTrim The URL the needs the surgery. + * + * @return string The $urlToTrim with the hostname and Graph version removed. + */ + public static function baseGraphUrlEndpoint($urlToTrim) + { + return '/' . preg_replace('/^https:\/\/.+\.facebook\.com(\/v.+?)?\//', '', $urlToTrim); + } +} diff --git a/inc/vendors/social-login/Facebook/Url/UrlDetectionInterface.php b/inc/vendors/social-login/Facebook/Url/UrlDetectionInterface.php new file mode 100755 index 00000000..dca38a0c --- /dev/null +++ b/inc/vendors/social-login/Facebook/Url/UrlDetectionInterface.php @@ -0,0 +1,39 @@ + + * @author Chirag Shah + */ +class apiClient { + // the version of the discovery mechanism this class is meant to work with + const discoveryVersion = 'v0.3'; + + /** + * @static + * @var apiAuth $auth + */ + static $auth; + + /** @var apiIo $io */ + static $io; + + /** @var apiCache $cache */ + static $cache; + + /** @var array $scopes */ + protected $scopes = array(); + + /** @var bool $useObjects */ + protected $useObjects = false; + + // definitions of services that are discovered. + protected $services = array(); + + // Used to track authenticated state, can't discover services after doing authenticate() + private $authenticated = false; + + private $defaultService = array( + 'authorization_token_url' => 'https://www.google.com/accounts/OAuthAuthorizeToken', + 'request_token_url' => 'https://www.google.com/accounts/OAuthGetRequestToken', + 'access_token_url' => 'https://www.google.com/accounts/OAuthGetAccessToken'); + + public function __construct($config = array()) { + global $apiConfig; + $apiConfig = array_merge($apiConfig, $config); + self::$cache = new $apiConfig['cacheClass'](); + self::$auth = new $apiConfig['authClass'](); + self::$io = new $apiConfig['ioClass'](); + } + + public function discover($service, $version = 'v1') { + $this->addService($service, $version); + $this->$service = $this->discoverService($service, $this->services[$service]['discoveryURI']); + return $this->$service; + } + + /** + * Add a service + */ + public function addService($service, $version) { + global $apiConfig; + if ($this->authenticated) { + // Adding services after being authenticated, since the oauth scope is already set (so you wouldn't have access to that data) + throw new apiException('Cant add services after having authenticated'); + } + $this->services[$service] = $this->defaultService; + if (isset($apiConfig['services'][$service])) { + // Merge the service descriptor with the default values + $this->services[$service] = array_merge($this->services[$service], $apiConfig['services'][$service]); + } + $this->services[$service]['discoveryURI'] = $apiConfig['basePath'] . '/discovery/' . self::discoveryVersion . '/describe/' . urlencode($service) . '/' . urlencode($version); + } + + /** + * Set the type of Auth class the client should use. + * @param string $authClassName + */ + public function setAuthClass($authClassName) { + self::$auth = new $authClassName(); + } + + public function authenticate() { + $service = $this->prepareService(); + $this->authenticated = true; + return self::$auth->authenticate($service); + } + + /** + * Construct the OAuth 2.0 authorization request URI. + * @return string + */ + public function createAuthUrl() { + $service = $this->prepareService(); + return self::$auth->createAuthUrl($service['scope']); + } + + private function prepareService() { + $service = $this->defaultService; + $scopes = array(); + if ($this->scopes) { + $scopes = $this->scopes; + } else { + foreach ($this->services as $key => $val) { + if (isset($val['scope'])) { + if (is_array($val['scope'])) { + $scopes = array_merge($val['scope'], $scopes); + } else { + $scopes[] = $val['scope']; + } + } else { + $scopes[] = 'https://www.googleapis.com/auth/' . $key; + } + unset($val['discoveryURI']); + unset($val['scope']); + $service = array_merge($service, $val); + } + } + $service['scope'] = implode(' ', $scopes); + return $service; + } + + /** + * Set the OAuth 2.0 access token using the string that resulted from calling authenticate() + * or apiClient#getAccessToken(). + * @param string $accessToken JSON encoded string containing in the following format: + * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer", + * "expires_in":3600, "id_token":"TOKEN", "created":1320790426} + */ + public function setAccessToken($accessToken) { + if ($accessToken == null || 'null' == $accessToken) { + $accessToken = null; + } + self::$auth->setAccessToken($accessToken); + } + + /** + * Get the OAuth 2.0 access token. + * @return string $accessToken JSON encoded string in the following format: + * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer", + * "expires_in":3600,"id_token":"TOKEN", "created":1320790426} + */ + public function getAccessToken() { + $token = self::$auth->getAccessToken(); + return (null == $token || 'null' == $token) ? null : $token; + } + + /** + * Set the developer key to use, these are obtained through the API Console. + * @see http://code.google.com/apis/console-help/#generatingdevkeys + * @param string $developerKey + */ + public function setDeveloperKey($developerKey) { + self::$auth->setDeveloperKey($developerKey); + } + + /** + * Set OAuth 2.0 "state" parameter to achieve per-request customization. + * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2 + * @param string $state + */ + public function setState($state) { + self::$auth->setState($state); + } + + /** + * @param string $accessType Possible values for access_type include: + * {@code "offline"} to request offline access from the user. (This is the default value) + * {@code "online"} to request online access from the user. + */ + public function setAccessType($accessType) { + self::$auth->setAccessType($accessType); + } + + /** + * @param string $approvalPrompt Possible values for approval_prompt include: + * {@code "force"} to force the approval UI to appear. (This is the default value) + * {@code "auto"} to request auto-approval when possible. + */ + public function setApprovalPrompt($approvalPrompt) { + self::$auth->setApprovalPrompt($approvalPrompt); + } + + /** + * Set the application name, this is included in the User-Agent HTTP header. + * @param string $applicationName + */ + public function setApplicationName($applicationName) { + global $apiConfig; + $apiConfig['application_name'] = $applicationName; + } + + /** + * Set the OAuth 2.0 Client ID. + * @param string $clientId + */ + public function setClientId($clientId) { + global $apiConfig; + $apiConfig['oauth2_client_id'] = $clientId; + self::$auth->clientId = $clientId; + } + + /** + * Set the OAuth 2.0 Client Secret. + * @param string $clientSecret + */ + public function setClientSecret($clientSecret) { + global $apiConfig; + $apiConfig['oauth2_client_secret'] = $clientSecret; + self::$auth->clientSecret = $clientSecret; + } + + /** + * Set the OAuth 2.0 Redirect URI. + * @param string $redirectUri + */ + public function setRedirectUri($redirectUri) { + global $apiConfig; + $apiConfig['oauth2_redirect_uri'] = $redirectUri; + self::$auth->redirectUri = $redirectUri; + } + + /** + * Fetches a fresh OAuth 2.0 access token with the given refresh token. + * @param string $refreshToken + * @return void + */ + public function refreshToken($refreshToken) { + self::$auth->refreshToken($refreshToken); + } + + /** + * Revoke an OAuth2 access token or refresh token. This method will revoke the current access + * token, if a token isn't provided. + * @throws apiAuthException + * @param string|null $token The token (access token or a refresh token) that should be revoked. + * @return boolean Returns True if the revocation was successful, otherwise False. + */ + public function revokeToken($token = null) { + self::$auth->revokeToken($token); + } + + /** + * Verify an id_token. This method will verify the current id_token, if one + * isn't provided. + * @throws apiAuthException + * @param string|null $token The token (id_token) that should be verified. + * @return apiLoginTicket Returns an apiLoginTicket if the verification was + * successful. + */ + public function verifyIdToken($token = null) { + return self::$auth->verifyIdToken($token); + } + + /** + * This function allows you to overrule the automatically generated scopes, + * so that you can ask for more or less permission in the auth flow + * Set this before you call authenticate() though! + * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus', 'https://www.googleapis.com/auth/moderator') + */ + public function setScopes($scopes) { + $this->scopes = is_string($scopes) ? explode(" ", $scopes) : $scopes; + } + + /** + * Declare if objects should be returned by the api service classes. + * @param boolean $useObjects True if objects should be returned by the service classes. + * False if associative arrays should be returned (default behavior). + */ + public function setUseObjects($useObjects) { + global $apiConfig; + $apiConfig['use_objects'] = $useObjects; + } + + private function discoverService($serviceName, $serviceURI) { + $request = self::$io->makeRequest(new apiHttpRequest($serviceURI)); + if ($request->getResponseHttpCode() != 200) { + throw new apiException("Could not fetch discovery document for $serviceName, code: " + . $request->getResponseHttpCode() . ", response: " . $request->getResponseBody()); + } + $discoveryResponse = $request->getResponseBody(); + $discoveryDocument = json_decode($discoveryResponse, true); + if ($discoveryDocument == NULL) { + throw new apiException("Invalid json returned for $serviceName"); + } + return new apiService($serviceName, $discoveryDocument, apiClient::getIo()); + } + + /** + * @static + * @return apiAuth the implementation of apiAuth. + */ + public static function getAuth() { + return apiClient::$auth; + } + + /** + * @static + * @return apiIo the implementation of apiIo. + */ + public static function getIo() { + return apiClient::$io; + } + + /** + * @return apiCache the implementation of apiCache. + */ + public function getCache() { + return apiClient::$cache; + } +} + +// Exceptions that the Google PHP API Library can throw +class apiException extends Exception {} +class apiAuthException extends apiException {} +class apiCacheException extends apiException {} +class apiIOException extends apiException {} +class apiServiceException extends apiException {} diff --git a/inc/vendors/social-login/Google/auth/apiAuth.php b/inc/vendors/social-login/Google/auth/apiAuth.php new file mode 100755 index 00000000..90163d7a --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiAuth.php @@ -0,0 +1,33 @@ + + */ +abstract class apiAuth { + abstract public function authenticate($service); + abstract public function sign(apiHttpRequest $request); + abstract public function createAuthUrl($scope); + + abstract public function getAccessToken(); + abstract public function setAccessToken($accessToken); + abstract public function setDeveloperKey($developerKey); + abstract public function refreshToken($refreshToken); + abstract public function revokeToken(); +} diff --git a/inc/vendors/social-login/Google/auth/apiAuthNone.php b/inc/vendors/social-login/Google/auth/apiAuthNone.php new file mode 100755 index 00000000..9226bc87 --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiAuthNone.php @@ -0,0 +1,45 @@ + + * @author Chirag Shah + */ +class apiAuthNone extends apiAuth { + public $key = null; + + public function __construct() { + global $apiConfig; + if (!empty($apiConfig['developer_key'])) { + $this->setDeveloperKey($apiConfig['developer_key']); + } + } + + public function setDeveloperKey($key) {$this->key = $key;} + public function authenticate($service) {/*noop*/} + public function setAccessToken($accessToken) {/* noop*/} + public function getAccessToken() {return null;} + public function createAuthUrl($scope) {return null;} + public function refreshToken($refreshToken) {/* noop*/} + public function revokeToken() {/* noop*/} + + public function sign(apiHttpRequest $request) { + if ($this->key) { + $request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&') + . 'key='.urlencode($this->key)); + } + return $request; + } +} diff --git a/inc/vendors/social-login/Google/auth/apiLoginTicket.php b/inc/vendors/social-login/Google/auth/apiLoginTicket.php new file mode 100755 index 00000000..499c24a7 --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiLoginTicket.php @@ -0,0 +1,55 @@ + + */ +class apiLoginTicket { + const USER_ATTR = "id"; + + // Information from id token envelope. + private $envelope; + + // Information from id token payload. + private $payload; + + /** + * Creates a user based on the supplied token. + * envelope: header from a verified authentication token. + * payload: information from a verified authentication token. + */ + public function __construct($envelope, $payload) { + $this->envelope = $envelope; + $this->payload = $payload; + } + + /** + * Returns the numeric identifier for the user. + */ + public function getUserId() { + if (array_key_exists(self::USER_ATTR, $this->payload)) { + return $this->payload[self::USER_ATTR]; + } + throw new apiAuthException("No user_id in token"); + } + + /** + * Returns attributes from the login ticket. This can contain + * various information about the user session. + */ + public function getAttributes() { + return array("envelope" => $this->envelope, "payload" => $this->payload); + } +} diff --git a/inc/vendors/social-login/Google/auth/apiOAuth.php b/inc/vendors/social-login/Google/auth/apiOAuth.php new file mode 100755 index 00000000..f27a2ced --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiOAuth.php @@ -0,0 +1,236 @@ + + */ +class apiOAuth extends apiAuth { + public $cacheKey; + protected $consumerToken; + protected $accessToken; + protected $privateKeyFile; + protected $developerKey; + public $service; + + /** + * Instantiates the class, but does not initiate the login flow, leaving it + * to the discretion of the caller. + */ + public function __construct() { + global $apiConfig; + if (!empty($apiConfig['developer_key'])) { + $this->setDeveloperKey($apiConfig['developer_key']); + } + $this->consumerToken = new apiClientOAuthConsumer($apiConfig['oauth_consumer_key'], $apiConfig['oauth_consumer_secret'], NULL); + $this->signatureMethod = new apiClientOAuthSignatureMethod_HMAC_SHA1(); + $this->cacheKey = 'OAuth:' . $apiConfig['oauth_consumer_key']; // Scope data to the local user as well, or else multiple local users will share the same OAuth credentials. + } + + /** + * The 3 legged oauth class needs a way to store the access key and token + * it uses the apiCache class to do so. + * Constructing this class will initiate the 3 legged oauth work flow, including redirecting + * to the OAuth provider's site if required(!) + * @param string $consumerKey + * @param string $consumerSecret + * @return apiOAuth3Legged the logged-in provider instance + */ + public function authenticate($service) { + global $apiConfig; + $this->service = $service; + $this->service['authorization_token_url'] .= '?scope=' . apiClientOAuthUtil::urlencodeRFC3986($service['scope']) . '&domain=' . apiClientOAuthUtil::urlencodeRFC3986($apiConfig['site_name']) . '&oauth_token='; + if (isset($_GET['oauth_verifier']) && isset($_GET['oauth_token']) && isset($_GET['uid'])) { + $uid = $_GET['uid']; + $secret = apiClient::$cache->get($this->cacheKey.":nonce:" . $uid); + apiClient::$cache->delete($this->cacheKey.":nonce:" . $uid); + $token = $this->upgradeRequestToken($_GET['oauth_token'], $secret, $_GET['oauth_verifier']); + return json_encode($token); + } else { + // Initialize the OAuth dance, first request a request token, then kick the client to the authorize URL + // First we store the current URL in our cache, so that when the oauth dance is completed we can return there + $callbackUrl = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $uid = uniqid(); + $token = $this->obtainRequestToken($callbackUrl, $uid); + apiClient::$cache->set($this->cacheKey.":nonce:" . $uid, $token->secret); + $this->redirectToAuthorization($token); + } + } + + /** + * Sets the internal oauth access token (which is returned by the authenticate function), a user should only + * go through the authenticate() flow once (which involces a bunch of browser redirections and authentication screens, not fun) + * and every time the user comes back the access token from the authentication() flow should be re-used (it essentially never expires) + * @param object $accessToken + */ + public function setAccessToken($accessToken) { + $accessToken = json_decode($accessToken, true); + if ($accessToken == null) { + throw new apiAuthException("Could not json decode the access token"); + } + if (! isset($accessToken['key']) || ! isset($accessToken['secret'])) { + throw new apiAuthException("Invalid OAuth token, missing key and/or secret"); + } + $this->accessToken = new apiClientOAuthConsumer($accessToken['key'], $accessToken['secret']); + } + + /** + * Returns the current access token + */ + public function getAccessToken() { + return $this->accessToken; + } + + + /** + * Set the developer key to use, these are obtained through the API Console + */ + public function setDeveloperKey($developerKey) { + $this->developerKey = $developerKey; + } + + /** + * Upgrades an existing request token to an access token. + * @param apiCache $cache cache class to use (file,apc,memcache,mysql) + * @param oauthVerifier + */ + public function upgradeRequestToken($requestToken, $requestTokenSecret, $oauthVerifier) { + $ret = $this->requestAccessToken($requestToken, $requestTokenSecret, $oauthVerifier); + $matches = array(); + @parse_str($ret, $matches); + if (!isset($matches['oauth_token']) || !isset($matches['oauth_token_secret'])) { + throw new apiAuthException("Error authorizing access key (result was: {$ret})"); + } + // The token was upgraded to an access token, we can now continue to use it. + $this->accessToken = new apiClientOAuthConsumer(apiClientOAuthUtil::urldecodeRFC3986($matches['oauth_token']), apiClientOAuthUtil::urldecodeRFC3986($matches['oauth_token_secret'])); + return $this->accessToken; + } + + /** + * Sends the actual request to exchange an existing request token for an access token. + * @param string $requestToken the existing request token + * @param string $requestTokenSecret the request token secret + * @return array('http_code' => HTTP response code (200, 404, 401, etc), 'data' => the html document) + */ + protected function requestAccessToken($requestToken, $requestTokenSecret, $oauthVerifier) { + $accessToken = new apiClientOAuthConsumer($requestToken, $requestTokenSecret); + $accessRequest = apiClientOAuthRequest::from_consumer_and_token($this->consumerToken, $accessToken, "GET", $this->service['access_token_url'], array('oauth_verifier' => $oauthVerifier)); + $accessRequest->sign_request($this->signatureMethod, $this->consumerToken, $accessToken); + $request = apiClient::$io->makeRequest(new apiHttpRequest($accessRequest)); + if ($request->getResponseHttpCode() != 200) { + throw new apiAuthException("Could not fetch access token, http code: " . $request->getResponseHttpCode() . ', response body: '. $request->getResponseBody()); + } + return $request->getResponseBody(); + } + + /** + * Obtains a request token from the specified provider. + */ + public function obtainRequestToken($callbackUrl, $uid) { + $callbackParams = (strpos($_SERVER['REQUEST_URI'], '?') !== false ? '&' : '?') . 'uid=' . urlencode($uid); + $ret = $this->requestRequestToken($callbackUrl . $callbackParams); + $matches = array(); + preg_match('/oauth_token=(.*)&oauth_token_secret=(.*)&oauth_callback_confirmed=(.*)/', $ret, $matches); + if (!is_array($matches) || count($matches) != 4) { + throw new apiAuthException("Error retrieving request key ({$ret})"); + } + return new apiClientOAuthToken(apiClientOAuthUtil::urldecodeRFC3986($matches[1]), apiClientOAuthUtil::urldecodeRFC3986($matches[2])); + } + + /** + * Sends the actual request to obtain a request token. + * @return array('http_code' => HTTP response code (200, 404, 401, etc), 'data' => the html document) + */ + protected function requestRequestToken($callbackUrl) { + $requestTokenRequest = apiClientOAuthRequest::from_consumer_and_token($this->consumerToken, NULL, "GET", $this->service['request_token_url'], array()); + $requestTokenRequest->set_parameter('scope', $this->service['scope']); + $requestTokenRequest->set_parameter('oauth_callback', $callbackUrl); + $requestTokenRequest->sign_request($this->signatureMethod, $this->consumerToken, NULL); + $request = apiClient::$io->makeRequest(new apiHttpRequest($requestTokenRequest)); + if ($request->getResponseHttpCode() != 200) { + throw new apiAuthException("Couldn't fetch request token, http code: " . $request->getResponseHttpCode() . ', response body: '. $request->getResponseBody()); + } + return $request->getResponseBody(); + } + + /** + * Redirect the uset to the (provider's) authorize page, if approved it should kick the user back to the call back URL + * which hopefully means we'll end up in the constructor of this class again, but with oauth_continue=1 set + * @param OAuthToken $token the request token + * @param string $callbackUrl the URL to return to post-authorization (passed to login site) + */ + public function redirectToAuthorization($token) { + $authorizeRedirect = $this->service['authorization_token_url']. $token->key; + header("Location: $authorizeRedirect"); + } + + /** + * Sign the request using OAuth. This uses the consumer token and key + * @param string $method the method (get/put/delete/post) + * @param string $url the url to sign (http://site/social/rest/people/1/@me) + * @param array $params the params that should be appended to the url (count=20 fields=foo, etc) + * @param string $postBody for POST/PUT requests, the postBody is included in the signature + * @return string the signed url + */ + public function sign(apiHttpRequest $request) { + // add the developer key to the request before signing it + if ($this->developerKey) { + $request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&') . 'key='.urlencode($this->developerKey)); + } + // and sign the request + $oauthRequest = apiClientOAuthRequest::from_request($request->getMethod(), $request->getBaseUrl(), $request->getQueryParams()); + $params = $this->mergeParameters($request->getQueryParams()); + foreach ($params as $key => $val) { + if (is_array($val)) { + $val = implode(',', $val); + } + $oauthRequest->set_parameter($key, $val); + } + $oauthRequest->sign_request($this->signatureMethod, $this->consumerToken, $this->accessToken); + $authHeaders = $oauthRequest->to_header(); + $headers = $request->getHeaders(); + $headers[] = $authHeaders; + $request->setHeaders($headers); + // and add the access token key to it (since it doesn't include the secret, it's still secure to store this in cache) + $request->accessKey = $this->accessToken->key; + return $request; + } + + /** + * Merges the supplied parameters with reasonable defaults for 2 legged oauth. User-supplied parameters + * will have precedent over the defaults. + * @param array $params the user-supplied params that will be appended to the url + * @return array the combined parameters + */ + protected function mergeParameters($params) { + $defaults = array( + 'oauth_nonce' => md5(microtime() . mt_rand()), + 'oauth_version' => apiClientOAuthRequest::$version, 'oauth_timestamp' => time(), + 'oauth_consumer_key' => $this->consumerToken->key + ); + if ($this->accessToken != null) { + $params['oauth_token'] = $this->accessToken->key; + } + return array_merge($defaults, $params); + } + + public function createAuthUrl($scope) {return null;} + public function refreshToken($refreshToken) {/* noop*/} + public function revokeToken() {/* noop*/} +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/auth/apiOAuth2.php b/inc/vendors/social-login/Google/auth/apiOAuth2.php new file mode 100755 index 00000000..256d984e --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiOAuth2.php @@ -0,0 +1,385 @@ + + * @author Chirag Shah + */ +class apiOAuth2 extends apiAuth { + public $clientId; + public $clientSecret; + public $developerKey; + public $accessToken; + public $redirectUri; + public $state; + public $accessType = 'offline'; + public $approvalPrompt = 'force'; + + const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke'; + const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token'; + const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth'; + const OAUTH2_FEDERATED_SIGNON_CERTS_URL = 'https://www.googleapis.com/oauth2/v1/certs'; + const CLOCK_SKEW_SECS = 300; // five minutes in seconds + const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds + const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds + + /** + * Instantiates the class, but does not initiate the login flow, leaving it + * to the discretion of the caller (which is done by calling authenticate()). + */ + public function __construct() { + global $apiConfig; + + if (! empty($apiConfig['developer_key'])) { + $this->developerKey = $apiConfig['developer_key']; + } + + if (! empty($apiConfig['oauth2_client_id'])) { + $this->clientId = $apiConfig['oauth2_client_id']; + } + + if (! empty($apiConfig['oauth2_client_secret'])) { + $this->clientSecret = $apiConfig['oauth2_client_secret']; + } + + if (! empty($apiConfig['oauth2_redirect_uri'])) { + $this->redirectUri = $apiConfig['oauth2_redirect_uri']; + } + + if (! empty($apiConfig['oauth2_access_type'])) { + $this->accessType = $apiConfig['oauth2_access_type']; + } + + if (! empty($apiConfig['oauth2_approval_prompt'])) { + $this->approvalPrompt = $apiConfig['oauth2_approval_prompt']; + } + } + + /** + * @param $service + * @return string + * @throws apiAuthException + */ + public function authenticate($service) { + if (isset($_GET['code'])) { + // We got here from the redirect from a successful authorization grant, fetch the access token + $request = apiClient::$io->makeRequest(new apiHttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array( + 'code' => $_GET['code'], + 'grant_type' => 'authorization_code', + 'redirect_uri' => $this->redirectUri, + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret + ))); + + if ($request->getResponseHttpCode() == 200) { + $this->setAccessToken($request->getResponseBody()); + $this->accessToken['created'] = time(); + return $this->getAccessToken(); + } else { + $response = $request->getResponseBody(); + $decodedResponse = json_decode($response, true); + if ($decodedResponse != $response && $decodedResponse != null && $decodedResponse['error']) { + $response = $decodedResponse['error']; + } + throw new apiAuthException("Error fetching OAuth2 access token, message: '$response'", $request->getResponseHttpCode()); + } + } + + $authUrl = $this->createAuthUrl($service['scope']); + header('Location: ' . $authUrl); + } + + /** + * Create a URL to obtain user authorization. + * The authorization endpoint allows the user to first + * authenticate, and then grant/deny the access request. + * @param string $scope The scope is expressed as a list of space-delimited strings. + * @return string + */ + public function createAuthUrl($scope) { + $params = array( + 'response_type=code', + 'redirect_uri=' . urlencode($this->redirectUri), + 'client_id=' . urlencode($this->clientId), + 'scope=' . urlencode($scope), + 'access_type=' . urlencode($this->accessType), + 'approval_prompt=' . urlencode($this->approvalPrompt) + ); + + if (isset($this->state)) { + $params[] = 'state=' . urlencode($this->state); + } + $params = implode('&', $params); + return self::OAUTH2_AUTH_URL . "?$params"; + } + + /** + * @param $accessToken + * @throws apiAuthException Thrown when $accessToken is invalid. + */ + public function setAccessToken($accessToken) { + $accessToken = json_decode($accessToken, true); + if ($accessToken == null) { + throw new apiAuthException('Could not json decode the access token'); + } + if (! isset($accessToken['access_token'])) { + throw new apiAuthException("Invalid token format"); + } + $this->accessToken = $accessToken; + } + + public function getAccessToken() { + return json_encode($this->accessToken); + } + + public function setDeveloperKey($developerKey) { + $this->developerKey = $developerKey; + } + + public function setState($state) { + $this->state = $state; + } + + public function setAccessType($accessType) { + $this->accessType = $accessType; + } + + public function setApprovalPrompt($approvalPrompt) { + $this->approvalPrompt = $approvalPrompt; + } + + /** + * Include an accessToken in a given apiHttpRequest. + * @param apiHttpRequest $request + * @return apiHttpRequest + * @throws apiAuthException + */ + public function sign(apiHttpRequest $request) { + // add the developer key to the request before signing it + if ($this->developerKey) { + $requestUrl = $request->getUrl(); + $requestUrl .= (strpos($request->getUrl(), '?') === false) ? '?' : '&'; + $requestUrl .= 'key=' . urlencode($this->developerKey); + $request->setUrl($requestUrl); + } + + // Cannot sign the request without an OAuth access token. + if (null == $this->accessToken) { + return $request; + } + + // If the token is set to expire in the next 30 seconds (or has already + // expired), refresh it and set the new token. + $expired = ($this->accessToken['created'] + ($this->accessToken['expires_in'] - 30)) < time(); + if ($expired) { + if (! array_key_exists('refresh_token', $this->accessToken)) { + throw new apiAuthException("The OAuth 2.0 access token has expired, " + . "and a refresh token is not available. Refresh tokens are not " + . "returned for responses that were auto-approved."); + } + $this->refreshToken($this->accessToken['refresh_token']); + } + + // Add the OAuth2 header to the request + $request->setRequestHeaders( + array('Authorization' => 'Bearer ' . $this->accessToken['access_token']) + ); + + return $request; + } + + /** + * Fetches a fresh access token with the given refresh token. + * @param string $refreshToken + * @return void + */ + public function refreshToken($refreshToken) { + $params = array( + 'client_id' => $this->clientId, + 'client_secret' => $this->clientSecret, + 'refresh_token' => $refreshToken, + 'grant_type' => 'refresh_token' + ); + $request = apiClient::$io->makeRequest( + new apiHttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), $params)); + $code = $request->getResponseHttpCode(); + $body = $request->getResponseBody(); + if ($code == 200) { + $token = json_decode($body, true); + if ($token == null) { + throw new apiAuthException("Could not json decode the access token"); + } + + if (! isset($token['access_token']) || ! isset($token['expires_in'])) { + throw new apiAuthException("Invalid token format"); + } + + $this->accessToken['access_token'] = $token['access_token']; + $this->accessToken['expires_in'] = $token['expires_in']; + $this->accessToken['created'] = time(); + } else { + throw new apiAuthException("Error refreshing the OAuth2 token, message: '$body'", $code); + } + } + + /** + * Revoke an OAuth2 access token or refresh token. This method will revoke the current access + * token, if a token isn't provided. + * @throws apiAuthException + * @param string|null $token The token (access token or a refresh token) that should be revoked. + * @return boolean Returns True if the revocation was successful, otherwise False. + */ + public function revokeToken($token = null) { + if (!$token) { + $token = $this->accessToken['access_token']; + } + $request = new apiHttpRequest(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token"); + $response = apiClient::$io->makeRequest($request); + $code = $response->getResponseHttpCode(); + if ($code == 200) { + $this->accessToken = null; + return true; + } + + return false; + } + + // Gets federated sign-on certificates to use for verifying identity tokens. + // Returns certs as array structure, where keys are key ids, and values + // are PEM encoded certificates. + private function getFederatedSignOnCerts() { + // This relies on makeRequest caching certificate responses. + $request = apiClient::$io->makeRequest(new apiHttpRequest( + self::OAUTH2_FEDERATED_SIGNON_CERTS_URL)); + if ($request->getResponseHttpCode() == 200) { + $certs = json_decode($request->getResponseBody(), true); + if ($certs) { + return $certs; + } + } + throw new apiAuthException( + "Failed to retrieve verification certificates: '" . + $request->getResponseBody() . "'.", + $request->getResponseHttpCode()); + } + + /** + * Verifies an id token and returns the authenticated apiLoginTicket. + * Throws an exception if the id token is not valid. + * The audience parameter can be used to control which id tokens are + * accepted. By default, the id token must have been issued to this OAuth2 client. + * @param $id_token + * @param $audience + * @return apiLoginTicket + */ + public function verifyIdToken($id_token = null, $audience = null) { + if (!$id_token) { + $id_token = $this->accessToken['id_token']; + } + + $certs = $this->getFederatedSignonCerts(); + if (!$audience) { + $audience = $this->clientId; + } + return $this->verifySignedJwtWithCerts($id_token, $certs, $audience); + } + + // Verifies the id token, returns the verified token contents. + // Visible for testing. + function verifySignedJwtWithCerts($jwt, $certs, $required_audience) { + $segments = explode(".", $jwt); + if (count($segments) != 3) { + throw new apiAuthException("Wrong number of segments in token: $jwt"); + } + $signed = $segments[0] . "." . $segments[1]; + $signature = apiUtils::urlSafeB64Decode($segments[2]); + + // Parse envelope. + $envelope = json_decode(apiUtils::urlSafeB64Decode($segments[0]), true); + if (!$envelope) { + throw new apiAuthException("Can't parse token envelope: " . $segments[0]); + } + + // Parse token + $json_body = apiUtils::urlSafeB64Decode($segments[1]); + $payload = json_decode($json_body, true); + if (!$payload) { + throw new apiAuthException("Can't parse token payload: " . $segments[1]); + } + + // Check signature + $verified = false; + foreach ($certs as $keyName => $pem) { + $public_key = new apiPemVerifier($pem); + if ($public_key->verify($signed, $signature)) { + $verified = true; + break; + } + } + + if (!$verified) { + throw new apiAuthException("Invalid token signature: $jwt"); + } + + // Check issued-at timestamp + $iat = 0; + if (array_key_exists("iat", $payload)) { + $iat = $payload["iat"]; + } + if (!$iat) { + throw new apiAuthException("No issue time in token: $json_body"); + } + $earliest = $iat - self::CLOCK_SKEW_SECS; + + // Check expiration timestamp + $now = time(); + $exp = 0; + if (array_key_exists("exp", $payload)) { + $exp = $payload["exp"]; + } + if (!$exp) { + throw new apiAuthException("No expiration time in token: $json_body"); + } + if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) { + throw new apiAuthException( + "Expiration time too far in future: $json_body"); + } + + $latest = $exp + self::CLOCK_SKEW_SECS; + if ($now < $earliest) { + throw new apiAuthException( + "Token used too early, $now < $earliest: $json_body"); + } + if ($now > $latest) { + throw new apiAuthException( + "Token used too late, $now > $latest: $json_body"); + } + + // TODO(beaton): check issuer field? + + // Check audience + $aud = $payload["aud"]; + if ($aud != $required_audience) { + throw new apiAuthException("Wrong recipient, $aud != $required_audience: $json_body"); + } + + // All good. + return new apiLoginTicket($envelope, $payload); + } +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/auth/apiP12Signer.php b/inc/vendors/social-login/Google/auth/apiP12Signer.php new file mode 100755 index 00000000..ff3df576 --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiP12Signer.php @@ -0,0 +1,62 @@ + + */ +class apiP12Signer extends apiSigner { + // OpenSSL private key resource + private $privateKey; + + // Creates a new signer from a .p12 file. + function __construct($p12file, $password) { + if (!function_exists('openssl_x509_read')) { + throw new Exception( + 'The Google PHP API library needs the openssl PHP extension'); + } + // This throws on error + // $p12 = file get contents($p12file); + $p12 = wp_remote_get($p12file); + $certs = array(); + if (!openssl_pkcs12_read($p12, $certs, $password)) { + throw new apiAuthException("Unable to parse $p12file. " . + "Is this a .p12 file? Is the password correct? OpenSSL error: " . + openssl_error_string()); + } + // TODO(beaton): is this part of the contract for the openssl_pkcs12_read + // method? What happens if there are multiple private keys? Do we care? + if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) { + throw new apiAuthException("No private key found in p12 file $p12file"); + } + $this->privateKey = openssl_pkey_get_private($certs["pkey"]); + if (!$this->privateKey) { + throw new apiAuthException("Unable to load private key in $p12file"); + } + } + + function __destruct() { + if ($this->privateKey) { + openssl_pkey_free($this->privateKey); + } + } + + function sign($data) { + if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) { + throw new apiAuthException("Unable to sign data"); + } + return $signature; + } +} diff --git a/inc/vendors/social-login/Google/auth/apiPemVerifier.php b/inc/vendors/social-login/Google/auth/apiPemVerifier.php new file mode 100755 index 00000000..368162b3 --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiPemVerifier.php @@ -0,0 +1,55 @@ + + */ +class apiPemVerifier extends apiVerifier { + private $publicKey; + + /** + * Constructs a verifier from the supplied PEM-encoded certificate. + * $pem: a PEM encoded certificate (not a file). + */ + function __construct($pem) { + if (!function_exists('openssl_x509_read')) { + throw new Exception( + 'The Google PHP API library needs the openssl PHP extension'); + } + $this->publicKey = openssl_x509_read($pem); + if (!$this->publicKey) { + throw new apiAuthException("Unable to parse PEM: $pem"); + } + } + + function __destruct() { + if ($this->publicKey) { + openssl_x509_free($this->publicKey); + } + } + + /** + * Verifies the signature on data. + * Returns true if the signature is valid, false otherwise. + */ + function verify($data, $signature) { + $status = openssl_verify($data, $signature, $this->publicKey, "sha256"); + if ($status === -1) { + throw new apiAuthException("Signature verification error: " . + openssl_error_string()); + } + return $status === 1; + } +} diff --git a/inc/vendors/social-login/Google/auth/apiSigner.php b/inc/vendors/social-login/Google/auth/apiSigner.php new file mode 100755 index 00000000..104035c7 --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiSigner.php @@ -0,0 +1,26 @@ + + */ +abstract class apiSigner { + /** + * Signs data, returns the signature as binary data. + */ + abstract public function sign($data); +} diff --git a/inc/vendors/social-login/Google/auth/apiVerifier.php b/inc/vendors/social-login/Google/auth/apiVerifier.php new file mode 100755 index 00000000..bdfac84d --- /dev/null +++ b/inc/vendors/social-login/Google/auth/apiVerifier.php @@ -0,0 +1,27 @@ + + */ +abstract class apiVerifier { + /** + * Checks a signature, returns true if the signature is correct, + * false otherwise. + */ + abstract public function verify($data, $signature); +} diff --git a/inc/vendors/social-login/Google/cache/apiApcCache.php b/inc/vendors/social-login/Google/cache/apiApcCache.php new file mode 100755 index 00000000..e6708df3 --- /dev/null +++ b/inc/vendors/social-login/Google/cache/apiApcCache.php @@ -0,0 +1,93 @@ + + */ +class apiApcCache extends apiCache { + + public function __construct() { + if (! function_exists('apc_add')) { + throw new apiCacheException("Apc functions not available"); + } + } + + private function isLocked($key) { + if ((@apc_fetch($key . '.lock')) === false) { + return false; + } + return true; + } + + private function createLock($key) { + // the interesting thing is that this could fail if the lock was created in the meantime.. + // but we'll ignore that out of convenience + @apc_add($key . '.lock', '', 5); + } + + private function removeLock($key) { + // suppress all warnings, if some other process removed it that's ok too + @apc_delete($key . '.lock'); + } + + private function waitForLock($key) { + // 20 x 250 = 5 seconds + $tries = 20; + $cnt = 0; + do { + // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks.. + usleep(250); + $cnt ++; + } while ($cnt <= $tries && $this->isLocked($key)); + if ($this->isLocked($key)) { + // 5 seconds passed, assume the owning process died off and remove it + $this->removeLock($key); + } + } + + /** + * @inheritDoc + */ + public function get($key, $expiration = false) { + + if (($ret = @apc_fetch($key)) === false) { + return false; + } + if (!$expiration || (time() - $ret['time'] > $expiration)) { + $this->delete($key); + return false; + } + return unserialize($ret['data']); + } + + /** + * @inheritDoc + */ + public function set($key, $value) { + if (@apc_store($key, array('time' => time(), 'data' => serialize($value))) == false) { + throw new apiCacheException("Couldn't store data"); + } + } + + /** + * @inheritDoc + */ + public function delete($key) { + @apc_delete($key); + } +} diff --git a/inc/vendors/social-login/Google/cache/apiCache.php b/inc/vendors/social-login/Google/cache/apiCache.php new file mode 100755 index 00000000..63f8a4f5 --- /dev/null +++ b/inc/vendors/social-login/Google/cache/apiCache.php @@ -0,0 +1,48 @@ + + */ +abstract class apiCache { + + /** + * Retrieves the data for the given key, or false if they + * key is unknown or expired + * @param String $key The key who's data to retrieve + * @param boolean|int $expiration Expiration time in seconds + */ + abstract function get($key, $expiration = false); + + /** + * Store the key => $value set. The $value is serialized + * by this function so can be of any type + * @param String $key Key of the data + * @param $value the data + */ + abstract function set($key, $value); + + /** + * Removes the key/data pair for the given $key + * @param String $key + */ + abstract function delete($key); +} + + diff --git a/inc/vendors/social-login/Google/cache/apiFileCache.php b/inc/vendors/social-login/Google/cache/apiFileCache.php new file mode 100755 index 00000000..dd86277b --- /dev/null +++ b/inc/vendors/social-login/Google/cache/apiFileCache.php @@ -0,0 +1,135 @@ + + */ +class apiFileCache extends apiCache { + private $path; + + public function __construct() { + global $apiConfig; + $this->path = $apiConfig['ioFileCache_directory']; + } + + private function isLocked($storageFile) { + // our lock file convention is simple: /the/file/path.lock + return file_exists($storageFile . '.lock'); + } + + private function createLock($storageFile) { + $storageDir = dirname($storageFile); + if (! is_dir($storageDir)) { + if (! @mkdir($storageDir, 0755, true)) { + // make sure the failure isn't because of a concurrency issue + if (! is_dir($storageDir)) { + throw new apiCacheException("Could not create storage directory: $storageDir"); + } + } + } + @touch($storageFile . '.lock'); + } + + private function removeLock($storageFile) { + // suppress all warnings, if some other process removed it that's ok too + @unlink($storageFile . '.lock'); + } + + private function waitForLock($storageFile) { + // 20 x 250 = 5 seconds + $tries = 20; + $cnt = 0; + do { + // make sure PHP picks up on file changes. This is an expensive action but really can't be avoided + clearstatcache(); + // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks.. + usleep(250); + $cnt ++; + } while ($cnt <= $tries && $this->isLocked($storageFile)); + if ($this->isLocked($storageFile)) { + // 5 seconds passed, assume the owning process died off and remove it + $this->removeLock($storageFile); + } + } + + private function getCacheDir($hash) { + // use the first 2 characters of the hash as a directory prefix + // this should prevent slowdowns due to huge directory listings + // and thus give some basic amount of scalability + return $this->path . '/' . substr($hash, 0, 2); + } + + private function getCacheFile($hash) { + return $this->getCacheDir($hash) . '/' . $hash; + } + + public function get($key, $expiration = false) { + $storageFile = $this->getCacheFile(md5($key)); + // See if this storage file is locked, if so we wait upto 5 seconds for the lock owning process to + // complete it's work. If the lock is not released within that time frame, it's cleaned up. + // This should give us a fair amount of 'Cache Stampeding' protection + if ($this->isLocked($storageFile)) { + $this->waitForLock($storageFile); + } + if (file_exists($storageFile) && is_readable($storageFile)) { + $now = time(); + if (! $expiration || (($mtime = @filemtime($storageFile)) !== false && ($now - $mtime) < $expiration)) { + // if (($data = @ file get contents($storageFile)) !== false) { + // $data = unserialize($data); + // return $data; + // } + if (($data = wp_remote_get($storageFile)) !== false) { + $data = unserialize($data); + return $data; + } + } + } + return false; + } + + public function set($key, $value) { + $storageDir = $this->getCacheDir(md5($key)); + $storageFile = $this->getCacheFile(md5($key)); + if ($this->isLocked($storageFile)) { + // some other process is writing to this file too, wait until it's done to prevent hickups + $this->waitForLock($storageFile); + } + if (! is_dir($storageDir)) { + if (! @mkdir($storageDir, 0755, true)) { + throw new apiCacheException("Could not create storage directory: $storageDir"); + } + } + // we serialize the whole request object, since we don't only want the + // responseContent but also the postBody used, headers, size, etc + $data = serialize($value); + $this->createLock($storageFile); + if (! @file_put_contents($storageFile, $data)) { + $this->removeLock($storageFile); + throw new apiCacheException("Could not store data in the file"); + } + $this->removeLock($storageFile); + } + + public function delete($key) { + $file = $this->getCacheFile(md5($key)); + if (! @unlink($file)) { + throw new apiCacheException("Cache file could not be deleted"); + } + } +} diff --git a/inc/vendors/social-login/Google/cache/apiMemcacheCache.php b/inc/vendors/social-login/Google/cache/apiMemcacheCache.php new file mode 100755 index 00000000..a96c9ae5 --- /dev/null +++ b/inc/vendors/social-login/Google/cache/apiMemcacheCache.php @@ -0,0 +1,122 @@ + + */ +class apiMemcacheCache extends apiCache { + private $connection = false; + + public function __construct() { + global $apiConfig; + if (! function_exists('memcache_connect')) { + throw new apiCacheException("Memcache functions not available"); + } + $this->host = $apiConfig['ioMemCacheCache_host']; + $this->port = $apiConfig['ioMemCacheCache_port']; + if (empty($this->host) || empty($this->port)) { + throw new apiCacheException("You need to supply a valid memcache host and port"); + } + } + + private function isLocked($key) { + $this->check(); + if ((@memcache_get($this->connection, $key . '.lock')) === false) { + return false; + } + return true; + } + + private function createLock($key) { + $this->check(); + // the interesting thing is that this could fail if the lock was created in the meantime.. + // but we'll ignore that out of convenience + @memcache_add($this->connection, $key . '.lock', '', 0, 5); + } + + private function removeLock($key) { + $this->check(); + // suppress all warnings, if some other process removed it that's ok too + @memcache_delete($this->connection, $key . '.lock'); + } + + private function waitForLock($key) { + $this->check(); + // 20 x 250 = 5 seconds + $tries = 20; + $cnt = 0; + do { + // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks.. + usleep(250); + $cnt ++; + } while ($cnt <= $tries && $this->isLocked($key)); + if ($this->isLocked($key)) { + // 5 seconds passed, assume the owning process died off and remove it + $this->removeLock($key); + } + } + + // I prefer lazy initialization since the cache isn't used every request + // so this potentially saves a lot of overhead + private function connect() { + if (! $this->connection = @memcache_pconnect($this->host, $this->port)) { + throw new apiCacheException("Couldn't connect to memcache server"); + } + } + + private function check() { + if (! $this->connection) { + $this->connect(); + } + } + + /** + * @inheritDoc + */ + public function get($key, $expiration = false) { + $this->check(); + if (($ret = @memcache_get($this->connection, $key)) === false) { + return false; + } + if (! $expiration || (time() - $ret['time'] > $expiration)) { + $this->delete($key); + return false; + } + return $ret['data']; + } + + /** + * @inheritDoc + */ + public function set($key, $value) { + $this->check(); + // we store it with the cache_time default expiration so objects will at least get cleaned eventually. + if (@memcache_set($this->connection, $key, array('time' => time(), + 'data' => $value), false) == false) { + throw new apiCacheException("Couldn't store data in cache"); + } + } + + /** + * @inheritDoc + */ + public function delete($key) { + $this->check(); + @memcache_delete($this->connection, $key); + } +} diff --git a/inc/vendors/social-login/Google/config.php b/inc/vendors/social-login/Google/config.php new file mode 100755 index 00000000..684ab173 --- /dev/null +++ b/inc/vendors/social-login/Google/config.php @@ -0,0 +1,89 @@ + false, + + // The application_name is included in the User-Agent HTTP header. + 'application_name' => '', + + // OAuth2 Settings, you can get these keys at https://code.google.com/apis/console + 'oauth2_client_id' => '', + 'oauth2_client_secret' => '', + 'oauth2_redirect_uri' => '', + + // The developer key, you get this at https://code.google.com/apis/console + 'developer_key' => '', + + // OAuth1 Settings. + // If you're using the apiOAuth auth class, it will use these values for the oauth consumer key and secret. + // See http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html for info on how to obtain those + 'oauth_consumer_key' => 'anonymous', + 'oauth_consumer_secret' => 'anonymous', + + // Site name to show in the Google's OAuth 1 authentication screen. + 'site_name' => 'www.example.org', + + // Which Authentication, Storage and HTTP IO classes to use. + 'authClass' => 'apiOAuth2', + 'ioClass' => 'apiCurlIO', + 'cacheClass' => 'apiFileCache', + + // If you want to run the test suite (by running # phpunit AllTests.php in the tests/ directory), fill in the settings below + 'oauth_test_token' => '', // the oauth access token to use (which you can get by runing authenticate() as the test user and copying the token value), ie '{"key":"foo","secret":"bar","callback_url":null}' + 'oauth_test_user' => '', // and the user ID to use, this can either be a vanity name 'testuser' or a numberic ID '123456' + + // Don't change these unless you're working against a special development or testing environment. + 'basePath' => 'https://www.googleapis.com', + + // IO Class dependent configuration, you only have to configure the values for the class that was configured as the ioClass above + 'ioFileCache_directory' => + (function_exists('sys_get_temp_dir') ? + sys_get_temp_dir() . '/apiClient' : + '/tmp/apiClient'), + 'ioMemCacheStorage_host' => '127.0.0.1', + 'ioMemcacheStorage_port' => '11211', + + // Definition of service specific values like scopes, oauth token URLs, etc + 'services' => array( + 'analytics' => array('scope' => 'https://www.googleapis.com/auth/analytics.readonly'), + 'calendar' => array( + 'scope' => array( + "https://www.googleapis.com/auth/calendar", + "https://www.googleapis.com/auth/calendar.readonly", + ) + ), + 'books' => array('scope' => 'https://www.googleapis.com/auth/books'), + 'latitude' => array( + 'scope' => array( + 'https://www.googleapis.com/auth/latitude.all.best', + 'https://www.googleapis.com/auth/latitude.all.city', + ) + ), + 'moderator' => array('scope' => 'https://www.googleapis.com/auth/moderator'), + 'oauth2' => array( + 'scope' => array( + 'https://www.googleapis.com/auth/userinfo.profile', + 'https://www.googleapis.com/auth/userinfo.email', + ) + ), + 'plus' => array('scope' => 'https://www.googleapis.com/auth/plus.me'), + 'siteVerification' => array('scope' => 'https://www.googleapis.com/auth/siteverification'), + 'tasks' => array('scope' => 'https://www.googleapis.com/auth/tasks'), + 'urlshortener' => array('scope' => 'https://www.googleapis.com/auth/urlshortener') + ) +); \ No newline at end of file diff --git a/inc/vendors/social-login/Google/contrib/apiAdsenseService.php b/inc/vendors/social-login/Google/contrib/apiAdsenseService.php new file mode 100755 index 00000000..3fdefaea --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiAdsenseService.php @@ -0,0 +1,1135 @@ + + * $adsenseService = new apiAdsenseService(...); + * $urlchannels = $adsenseService->urlchannels; + *
            + */ + class UrlchannelsServiceResource extends apiServiceResource { + + + /** + * List all URL channels in the specified ad client for this AdSense account. (urlchannels.list) + * @param string $adClientId Ad client for which to list URL channels. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through URL channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of URL channels to include in the response, used for paging. + * @return UrlChannels + */ + public function listUrlchannels($adClientId, $optParams = array()) { + $params = array('adClientId' => $adClientId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new UrlChannels($data); + } else { + return $data; + } + } + } + + /** + * The "adunits" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $adunits = $adsenseService->adunits; + * + */ + class AdunitsServiceResource extends apiServiceResource { + + + /** + * List all ad units in the specified ad client for this AdSense account. (adunits.list) + * @param string $adClientId Ad client for which to list ad units. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool includeInactive Whether to include inactive ad units. Default: true. + * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging. + * @return AdUnits + */ + public function listAdunits($adClientId, $optParams = array()) { + $params = array('adClientId' => $adClientId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new AdUnits($data); + } else { + return $data; + } + } + /** + * Gets the specified ad unit in the specified ad client. (adunits.get) + * @param string $adClientId Ad client for which to get the ad unit. + * @param string $adUnitId Ad unit to retrieve. + * @return AdUnit + */ + public function get($adClientId, $adUnitId, $optParams = array()) { + $params = array('adClientId' => $adClientId, 'adUnitId' => $adUnitId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new AdUnit($data); + } else { + return $data; + } + } + } + + + /** + * The "customchannels" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $customchannels = $adsenseService->customchannels; + * + */ + class AdunitsCustomchannelsServiceResource extends apiServiceResource { + + + /** + * List all custom channels which the specified ad unit belongs to. (customchannels.list) + * @param string $adClientId Ad client which contains the ad unit. + * @param string $adUnitId Ad unit for which to list custom channels. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging. + * @return CustomChannels + */ + public function listAdunitsCustomchannels($adClientId, $adUnitId, $optParams = array()) { + $params = array('adClientId' => $adClientId, 'adUnitId' => $adUnitId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CustomChannels($data); + } else { + return $data; + } + } + } + + /** + * The "adclients" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $adclients = $adsenseService->adclients; + * + */ + class AdclientsServiceResource extends apiServiceResource { + + + /** + * List all ad clients in this AdSense account. (adclients.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through ad clients. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of ad clients to include in the response, used for paging. + * @return AdClients + */ + public function listAdclients($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new AdClients($data); + } else { + return $data; + } + } + } + + /** + * The "reports" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $reports = $adsenseService->reports; + * + */ + class ReportsServiceResource extends apiServiceResource { + + + /** + * Generate an AdSense report based on the report request sent in the query parameters. Returns the + * result as JSON; to retrieve output in CSV format specify "alt=csv" as a query parameter. + * (reports.generate) + * @param string $startDate Start of the date range to report on in "YYYY-MM-DD" format, inclusive. + * @param string $endDate End of the date range to report on in "YYYY-MM-DD" format, inclusive. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string sort The name of a dimension or metric to sort the resulting report on, optionally prefixed with "+" to sort ascending or "-" to sort descending. If no prefix is specified, the column is sorted ascending. + * @opt_param string locale Optional locale to use for translating report output to a local language. Defaults to "en_US" if not specified. + * @opt_param string metric Numeric columns to include in the report. + * @opt_param int maxResults The maximum number of rows of report data to return. + * @opt_param string filter Filters to be run on the report. + * @opt_param string currency Optional currency to use when reporting on monetary metrics. Defaults to the account's currency if not set. + * @opt_param int startIndex Index of the first row of report data to return. + * @opt_param string dimension Dimensions to base the report on. + * @opt_param string accountId Accounts upon which to report. + * @return AdsenseReportsGenerateResponse + */ + public function generate($startDate, $endDate, $optParams = array()) { + $params = array('startDate' => $startDate, 'endDate' => $endDate); + $params = array_merge($params, $optParams); + $data = $this->__call('generate', array($params)); + if ($this->useObjects()) { + return new AdsenseReportsGenerateResponse($data); + } else { + return $data; + } + } + } + + /** + * The "accounts" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $accounts = $adsenseService->accounts; + * + */ + class AccountsServiceResource extends apiServiceResource { + + + /** + * List all accounts available to this AdSense account. (accounts.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through accounts. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of accounts to include in the response, used for paging. + * @return Accounts + */ + public function listAccounts($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Accounts($data); + } else { + return $data; + } + } + /** + * Get information about the selected AdSense account. (accounts.get) + * @param string $accountId Account to get information about. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool tree Whether the tree of sub accounts should be returned. + * @return Account + */ + public function get($accountId, $optParams = array()) { + $params = array('accountId' => $accountId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Account($data); + } else { + return $data; + } + } + } + + + /** + * The "urlchannels" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $urlchannels = $adsenseService->urlchannels; + * + */ + class AccountsUrlchannelsServiceResource extends apiServiceResource { + + + /** + * List all URL channels in the specified ad client for the specified account. (urlchannels.list) + * @param string $accountId Account to which the ad client belongs. + * @param string $adClientId Ad client for which to list URL channels. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through URL channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of URL channels to include in the response, used for paging. + * @return UrlChannels + */ + public function listAccountsUrlchannels($accountId, $adClientId, $optParams = array()) { + $params = array('accountId' => $accountId, 'adClientId' => $adClientId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new UrlChannels($data); + } else { + return $data; + } + } + } + /** + * The "adunits" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $adunits = $adsenseService->adunits; + * + */ + class AccountsAdunitsServiceResource extends apiServiceResource { + + + /** + * List all ad units in the specified ad client for the specified account. (adunits.list) + * @param string $accountId Account to which the ad client belongs. + * @param string $adClientId Ad client for which to list ad units. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool includeInactive Whether to include inactive ad units. Default: true. + * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging. + * @return AdUnits + */ + public function listAccountsAdunits($accountId, $adClientId, $optParams = array()) { + $params = array('accountId' => $accountId, 'adClientId' => $adClientId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new AdUnits($data); + } else { + return $data; + } + } + /** + * Gets the specified ad unit in the specified ad client for the specified account. (adunits.get) + * @param string $accountId Account to which the ad client belongs. + * @param string $adClientId Ad client for which to get the ad unit. + * @param string $adUnitId Ad unit to retrieve. + * @return AdUnit + */ + public function get($accountId, $adClientId, $adUnitId, $optParams = array()) { + $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'adUnitId' => $adUnitId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new AdUnit($data); + } else { + return $data; + } + } + } + + + /** + * The "customchannels" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $customchannels = $adsenseService->customchannels; + * + */ + class AccountsAdunitsCustomchannelsServiceResource extends apiServiceResource { + + + /** + * List all custom channels which the specified ad unit belongs to. (customchannels.list) + * @param string $accountId Account to which the ad client belongs. + * @param string $adClientId Ad client which contains the ad unit. + * @param string $adUnitId Ad unit for which to list custom channels. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging. + * @return CustomChannels + */ + public function listAccountsAdunitsCustomchannels($accountId, $adClientId, $adUnitId, $optParams = array()) { + $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'adUnitId' => $adUnitId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CustomChannels($data); + } else { + return $data; + } + } + } + /** + * The "adclients" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $adclients = $adsenseService->adclients; + * + */ + class AccountsAdclientsServiceResource extends apiServiceResource { + + + /** + * List all ad clients in the specified account. (adclients.list) + * @param string $accountId Account for which to list ad clients. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through ad clients. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of ad clients to include in the response, used for paging. + * @return AdClients + */ + public function listAccountsAdclients($accountId, $optParams = array()) { + $params = array('accountId' => $accountId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new AdClients($data); + } else { + return $data; + } + } + } + /** + * The "reports" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $reports = $adsenseService->reports; + * + */ + class AccountsReportsServiceResource extends apiServiceResource { + + + /** + * Generate an AdSense report based on the report request sent in the query parameters. Returns the + * result as JSON; to retrieve output in CSV format specify "alt=csv" as a query parameter. + * (reports.generate) + * @param string $startDate Start of the date range to report on in "YYYY-MM-DD" format, inclusive. + * @param string $endDate End of the date range to report on in "YYYY-MM-DD" format, inclusive. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string accountId Account upon which to report. + * @opt_param string sort The name of a dimension or metric to sort the resulting report on, optionally prefixed with "+" to sort ascending or "-" to sort descending. If no prefix is specified, the column is sorted ascending. + * @opt_param string locale Optional locale to use for translating report output to a local language. Defaults to "en_US" if not specified. + * @opt_param string metric Numeric columns to include in the report. + * @opt_param int maxResults The maximum number of rows of report data to return. + * @opt_param string filter Filters to be run on the report. + * @opt_param string currency Optional currency to use when reporting on monetary metrics. Defaults to the account's currency if not set. + * @opt_param int startIndex Index of the first row of report data to return. + * @opt_param string dimension Dimensions to base the report on. + * @return AdsenseReportsGenerateResponse + */ + public function generate($startDate, $endDate, $optParams = array()) { + $params = array('startDate' => $startDate, 'endDate' => $endDate); + $params = array_merge($params, $optParams); + $data = $this->__call('generate', array($params)); + if ($this->useObjects()) { + return new AdsenseReportsGenerateResponse($data); + } else { + return $data; + } + } + } + /** + * The "customchannels" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $customchannels = $adsenseService->customchannels; + * + */ + class AccountsCustomchannelsServiceResource extends apiServiceResource { + + + /** + * List all custom channels in the specified ad client for the specified account. + * (customchannels.list) + * @param string $accountId Account to which the ad client belongs. + * @param string $adClientId Ad client for which to list custom channels. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging. + * @return CustomChannels + */ + public function listAccountsCustomchannels($accountId, $adClientId, $optParams = array()) { + $params = array('accountId' => $accountId, 'adClientId' => $adClientId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CustomChannels($data); + } else { + return $data; + } + } + /** + * Get the specified custom channel from the specified ad client for the specified account. + * (customchannels.get) + * @param string $accountId Account to which the ad client belongs. + * @param string $adClientId Ad client which contains the custom channel. + * @param string $customChannelId Custom channel to retrieve. + * @return CustomChannel + */ + public function get($accountId, $adClientId, $customChannelId, $optParams = array()) { + $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'customChannelId' => $customChannelId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new CustomChannel($data); + } else { + return $data; + } + } + } + + + /** + * The "adunits" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $adunits = $adsenseService->adunits; + * + */ + class AccountsCustomchannelsAdunitsServiceResource extends apiServiceResource { + + + /** + * List all ad units in the specified custom channel. (adunits.list) + * @param string $accountId Account to which the ad client belongs. + * @param string $adClientId Ad client which contains the custom channel. + * @param string $customChannelId Custom channel for which to list ad units. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool includeInactive Whether to include inactive ad units. Default: true. + * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging. + * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @return AdUnits + */ + public function listAccountsCustomchannelsAdunits($accountId, $adClientId, $customChannelId, $optParams = array()) { + $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'customChannelId' => $customChannelId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new AdUnits($data); + } else { + return $data; + } + } + } + + /** + * The "customchannels" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $customchannels = $adsenseService->customchannels; + * + */ + class CustomchannelsServiceResource extends apiServiceResource { + + + /** + * List all custom channels in the specified ad client for this AdSense account. + * (customchannels.list) + * @param string $adClientId Ad client for which to list custom channels. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging. + * @return CustomChannels + */ + public function listCustomchannels($adClientId, $optParams = array()) { + $params = array('adClientId' => $adClientId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CustomChannels($data); + } else { + return $data; + } + } + /** + * Get the specified custom channel from the specified ad client. (customchannels.get) + * @param string $adClientId Ad client which contains the custom channel. + * @param string $customChannelId Custom channel to retrieve. + * @return CustomChannel + */ + public function get($adClientId, $customChannelId, $optParams = array()) { + $params = array('adClientId' => $adClientId, 'customChannelId' => $customChannelId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new CustomChannel($data); + } else { + return $data; + } + } + } + + + /** + * The "adunits" collection of methods. + * Typical usage is: + * + * $adsenseService = new apiAdsenseService(...); + * $adunits = $adsenseService->adunits; + * + */ + class CustomchannelsAdunitsServiceResource extends apiServiceResource { + + + /** + * List all ad units in the specified custom channel. (adunits.list) + * @param string $adClientId Ad client which contains the custom channel. + * @param string $customChannelId Custom channel for which to list ad units. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool includeInactive Whether to include inactive ad units. Default: true. + * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging. + * @return AdUnits + */ + public function listCustomchannelsAdunits($adClientId, $customChannelId, $optParams = array()) { + $params = array('adClientId' => $adClientId, 'customChannelId' => $customChannelId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new AdUnits($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Adsense (v1.1). + *

            + * Gives AdSense publishers access to their inventory and the ability to generate reports + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiAdsenseService extends apiService { + public $urlchannels; + public $adunits; + public $adunits_customchannels; + public $adunits_customchannels_customchannels; + public $adclients; + public $reports; + public $accounts; + public $accounts_urlchannels; + public $accounts_urlchannels_urlchannels; + public $accounts_urlchannels_adunits; + public $accounts_urlchannels_adclients; + public $accounts_urlchannels_reports; + public $accounts_urlchannels_customchannels; + public $accounts_adunits; + public $accounts_adunits_urlchannels; + public $accounts_adunits_adunits; + public $accounts_adunits_adclients; + public $accounts_adunits_reports; + public $accounts_adunits_customchannels; + public $accounts_adclients; + public $accounts_adclients_urlchannels; + public $accounts_adclients_adunits; + public $accounts_adclients_adclients; + public $accounts_adclients_reports; + public $accounts_adclients_customchannels; + public $accounts_reports; + public $accounts_reports_urlchannels; + public $accounts_reports_adunits; + public $accounts_reports_adclients; + public $accounts_reports_reports; + public $accounts_reports_customchannels; + public $accounts_customchannels; + public $accounts_customchannels_urlchannels; + public $accounts_customchannels_adunits; + public $accounts_customchannels_adclients; + public $accounts_customchannels_reports; + public $accounts_customchannels_customchannels; + public $customchannels; + public $customchannels_adunits; + public $customchannels_adunits_adunits; + /** + * Constructs the internal representation of the Adsense service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/adsense/v1.1/'; + $this->version = 'v1.1'; + $this->serviceName = 'adsense'; + + $apiClient->addService($this->serviceName, $this->version); + $this->urlchannels = new UrlchannelsServiceResource($this, $this->serviceName, 'urlchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}}, "id": "adsense.urlchannels.list", "httpMethod": "GET", "path": "adclients/{adClientId}/urlchannels", "response": {"$ref": "UrlChannels"}}}}', true)); + $this->adunits = new AdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}}, "id": "adsense.adunits.list", "httpMethod": "GET", "path": "adclients/{adClientId}/adunits", "response": {"$ref": "AdUnits"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"adClientId": {"required": true, "type": "string", "location": "path"}, "adUnitId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.adunits.get", "httpMethod": "GET", "path": "adclients/{adClientId}/adunits/{adUnitId}", "response": {"$ref": "AdUnit"}}}}', true)); + $this->adunits_customchannels = new AdunitsCustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "adUnitId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}}, "id": "adsense.adunits.customchannels.list", "httpMethod": "GET", "path": "adclients/{adClientId}/adunits/{adUnitId}/customchannels", "response": {"$ref": "CustomChannels"}}}}', true)); + $this->adclients = new AdclientsServiceResource($this, $this->serviceName, 'adclients', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}}, "response": {"$ref": "AdClients"}, "httpMethod": "GET", "path": "adclients", "id": "adsense.adclients.list"}}}', true)); + $this->reports = new ReportsServiceResource($this, $this->serviceName, 'reports', json_decode('{"methods": {"generate": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"sort": {"repeated": true, "type": "string", "location": "query"}, "startDate": {"required": true, "type": "string", "location": "query"}, "endDate": {"required": true, "type": "string", "location": "query"}, "locale": {"type": "string", "location": "query"}, "metric": {"repeated": true, "type": "string", "location": "query"}, "maxResults": {"format": "int32", "maximum": "50000", "minimum": "0", "location": "query", "type": "integer"}, "filter": {"repeated": true, "type": "string", "location": "query"}, "currency": {"type": "string", "location": "query"}, "startIndex": {"format": "int32", "maximum": "5000", "minimum": "0", "location": "query", "type": "integer"}, "dimension": {"repeated": true, "type": "string", "location": "query"}, "accountId": {"repeated": true, "type": "string", "location": "query"}}, "id": "adsense.reports.generate", "httpMethod": "GET", "path": "reports", "response": {"$ref": "AdsenseReportsGenerateResponse"}}}}', true)); + $this->accounts = new AccountsServiceResource($this, $this->serviceName, 'accounts', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}}, "response": {"$ref": "Accounts"}, "httpMethod": "GET", "path": "accounts", "id": "adsense.accounts.list"}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"tree": {"type": "boolean", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.get", "httpMethod": "GET", "path": "accounts/{accountId}", "response": {"$ref": "Account"}}}}', true)); + $this->accounts_urlchannels = new AccountsUrlchannelsServiceResource($this, $this->serviceName, 'urlchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.urlchannels.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/urlchannels", "response": {"$ref": "UrlChannels"}}}}', true)); + $this->accounts_adunits = new AccountsAdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adunits.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/adunits", "response": {"$ref": "AdUnits"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"adClientId": {"required": true, "type": "string", "location": "path"}, "adUnitId": {"required": true, "type": "string", "location": "path"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adunits.get", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/adunits/{adUnitId}", "response": {"$ref": "AdUnit"}}}}', true)); + $this->accounts_adunits_customchannels = new AccountsAdunitsCustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "adUnitId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adunits.customchannels.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/adunits/{adUnitId}/customchannels", "response": {"$ref": "CustomChannels"}}}}', true)); + $this->accounts_adclients = new AccountsAdclientsServiceResource($this, $this->serviceName, 'adclients', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adclients.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients", "response": {"$ref": "AdClients"}}}}', true)); + $this->accounts_reports = new AccountsReportsServiceResource($this, $this->serviceName, 'reports', json_decode('{"methods": {"generate": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"sort": {"repeated": true, "type": "string", "location": "query"}, "startDate": {"required": true, "type": "string", "location": "query"}, "endDate": {"required": true, "type": "string", "location": "query"}, "locale": {"type": "string", "location": "query"}, "metric": {"repeated": true, "type": "string", "location": "query"}, "maxResults": {"format": "int32", "maximum": "50000", "minimum": "0", "location": "query", "type": "integer"}, "filter": {"repeated": true, "type": "string", "location": "query"}, "currency": {"type": "string", "location": "query"}, "startIndex": {"format": "int32", "maximum": "5000", "minimum": "0", "location": "query", "type": "integer"}, "dimension": {"repeated": true, "type": "string", "location": "query"}, "accountId": {"type": "string", "location": "path"}}, "id": "adsense.accounts.reports.generate", "httpMethod": "GET", "path": "accounts/{accountId}/reports", "response": {"$ref": "AdsenseReportsGenerateResponse"}}}}', true)); + $this->accounts_customchannels = new AccountsCustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.customchannels.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/customchannels", "response": {"$ref": "CustomChannels"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.customchannels.get", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/customchannels/{customChannelId}", "response": {"$ref": "CustomChannel"}}}}', true)); + $this->accounts_customchannels_adunits = new AccountsCustomchannelsAdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}, "pageToken": {"type": "string", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.customchannels.adunits.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/customchannels/{customChannelId}/adunits", "response": {"$ref": "AdUnits"}}}}', true)); + $this->customchannels = new CustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}}, "id": "adsense.customchannels.list", "httpMethod": "GET", "path": "adclients/{adClientId}/customchannels", "response": {"$ref": "CustomChannels"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.customchannels.get", "httpMethod": "GET", "path": "adclients/{adClientId}/customchannels/{customChannelId}", "response": {"$ref": "CustomChannel"}}}}', true)); + $this->customchannels_adunits = new CustomchannelsAdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "int32", "maximum": "10000", "minimum": "0", "location": "query", "type": "integer"}}, "id": "adsense.customchannels.adunits.list", "httpMethod": "GET", "path": "adclients/{adClientId}/customchannels/{customChannelId}/adunits", "response": {"$ref": "AdUnits"}}}}', true)); + } +} + +class Account extends apiModel { + public $kind; + public $id; + protected $__subAccountsType = 'Account'; + protected $__subAccountsDataType = 'array'; + public $subAccounts; + public $name; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSubAccounts(/* array(Account) */ $subAccounts) { + $this->assertIsArray($subAccounts, 'Account', __METHOD__); + $this->subAccounts = $subAccounts; + } + public function getSubAccounts() { + return $this->subAccounts; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class Accounts extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Account'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Account) */ $items) { + $this->assertIsArray($items, 'Account', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class AdClient extends apiModel { + public $productCode; + public $kind; + public $id; + public $supportsReporting; + public function setProductCode($productCode) { + $this->productCode = $productCode; + } + public function getProductCode() { + return $this->productCode; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSupportsReporting($supportsReporting) { + $this->supportsReporting = $supportsReporting; + } + public function getSupportsReporting() { + return $this->supportsReporting; + } +} + +class AdClients extends apiModel { + public $nextPageToken; + protected $__itemsType = 'AdClient'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(AdClient) */ $items) { + $this->assertIsArray($items, 'AdClient', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class AdUnit extends apiModel { + public $status; + public $kind; + public $code; + public $id; + public $name; + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setCode($code) { + $this->code = $code; + } + public function getCode() { + return $this->code; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class AdUnits extends apiModel { + public $nextPageToken; + protected $__itemsType = 'AdUnit'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(AdUnit) */ $items) { + $this->assertIsArray($items, 'AdUnit', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class AdsenseReportsGenerateResponse extends apiModel { + public $kind; + public $rows; + public $warnings; + public $totals; + protected $__headersType = 'AdsenseReportsGenerateResponseHeaders'; + protected $__headersDataType = 'array'; + public $headers; + public $totalMatchedRows; + public $averages; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setRows(/* array(string) */ $rows) { + $this->assertIsArray($rows, 'string', __METHOD__); + $this->rows = $rows; + } + public function getRows() { + return $this->rows; + } + public function setWarnings(/* array(string) */ $warnings) { + $this->assertIsArray($warnings, 'string', __METHOD__); + $this->warnings = $warnings; + } + public function getWarnings() { + return $this->warnings; + } + public function setTotals(/* array(string) */ $totals) { + $this->assertIsArray($totals, 'string', __METHOD__); + $this->totals = $totals; + } + public function getTotals() { + return $this->totals; + } + public function setHeaders(/* array(AdsenseReportsGenerateResponseHeaders) */ $headers) { + $this->assertIsArray($headers, 'AdsenseReportsGenerateResponseHeaders', __METHOD__); + $this->headers = $headers; + } + public function getHeaders() { + return $this->headers; + } + public function setTotalMatchedRows($totalMatchedRows) { + $this->totalMatchedRows = $totalMatchedRows; + } + public function getTotalMatchedRows() { + return $this->totalMatchedRows; + } + public function setAverages(/* array(string) */ $averages) { + $this->assertIsArray($averages, 'string', __METHOD__); + $this->averages = $averages; + } + public function getAverages() { + return $this->averages; + } +} + +class AdsenseReportsGenerateResponseHeaders extends apiModel { + public $currency; + public $type; + public $name; + public function setCurrency($currency) { + $this->currency = $currency; + } + public function getCurrency() { + return $this->currency; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class CustomChannel extends apiModel { + public $kind; + public $code; + protected $__targetingInfoType = 'CustomChannelTargetingInfo'; + protected $__targetingInfoDataType = ''; + public $targetingInfo; + public $id; + public $name; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setCode($code) { + $this->code = $code; + } + public function getCode() { + return $this->code; + } + public function setTargetingInfo(CustomChannelTargetingInfo $targetingInfo) { + $this->targetingInfo = $targetingInfo; + } + public function getTargetingInfo() { + return $this->targetingInfo; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class CustomChannelTargetingInfo extends apiModel { + public $location; + public $adsAppearOn; + public $siteLanguage; + public $description; + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setAdsAppearOn($adsAppearOn) { + $this->adsAppearOn = $adsAppearOn; + } + public function getAdsAppearOn() { + return $this->adsAppearOn; + } + public function setSiteLanguage($siteLanguage) { + $this->siteLanguage = $siteLanguage; + } + public function getSiteLanguage() { + return $this->siteLanguage; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } +} + +class CustomChannels extends apiModel { + public $nextPageToken; + protected $__itemsType = 'CustomChannel'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(CustomChannel) */ $items) { + $this->assertIsArray($items, 'CustomChannel', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class UrlChannel extends apiModel { + public $kind; + public $id; + public $urlPattern; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setUrlPattern($urlPattern) { + $this->urlPattern = $urlPattern; + } + public function getUrlPattern() { + return $this->urlPattern; + } +} + +class UrlChannels extends apiModel { + public $nextPageToken; + protected $__itemsType = 'UrlChannel'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(UrlChannel) */ $items) { + $this->assertIsArray($items, 'UrlChannel', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiAnalyticsService.php b/inc/vendors/social-login/Google/contrib/apiAnalyticsService.php new file mode 100755 index 00000000..61b14f06 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiAnalyticsService.php @@ -0,0 +1,1553 @@ + + * $analyticsService = new apiAnalyticsService(...); + * $management = $analyticsService->management; + * + */ + class ManagementServiceResource extends apiServiceResource { + + + } + + + /** + * The "webproperties" collection of methods. + * Typical usage is: + * + * $analyticsService = new apiAnalyticsService(...); + * $webproperties = $analyticsService->webproperties; + * + */ + class ManagementWebpropertiesServiceResource extends apiServiceResource { + + + /** + * Lists web properties to which the user has access. (webproperties.list) + * @param string $accountId Account ID for the web properties to retrieve. Can either be a specific account ID or '~all', which refers to all the accounts to which user has access. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param int max-results The maximum number of entries to include in this response. + * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter. + * @return Webproperties + */ + public function listManagementWebproperties($accountId, $optParams = array()) { + $params = array('accountId' => $accountId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Webproperties($data); + } else { + return $data; + } + } + } + /** + * The "segments" collection of methods. + * Typical usage is: + * + * $analyticsService = new apiAnalyticsService(...); + * $segments = $analyticsService->segments; + * + */ + class ManagementSegmentsServiceResource extends apiServiceResource { + + + /** + * Lists advanced segments to which the user has access. (segments.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param int max-results The maximum number of entries to include in this response. + * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter. + * @return Segments + */ + public function listManagementSegments($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Segments($data); + } else { + return $data; + } + } + } + /** + * The "accounts" collection of methods. + * Typical usage is: + * + * $analyticsService = new apiAnalyticsService(...); + * $accounts = $analyticsService->accounts; + * + */ + class ManagementAccountsServiceResource extends apiServiceResource { + + + /** + * Lists all accounts to which the user has access. (accounts.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param int max-results The maximum number of entries to include in this response. + * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter. + * @return Accounts + */ + public function listManagementAccounts($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Accounts($data); + } else { + return $data; + } + } + } + /** + * The "goals" collection of methods. + * Typical usage is: + * + * $analyticsService = new apiAnalyticsService(...); + * $goals = $analyticsService->goals; + * + */ + class ManagementGoalsServiceResource extends apiServiceResource { + + + /** + * Lists goals to which the user has access. (goals.list) + * @param string $accountId Account ID for the web properties to retrieve. Can either be a specific account ID or '~all', which refers to all the accounts to which the user has access. + * @param string $webPropertyId Web property ID for the web properties to retrieve. Can either be a specific web property ID or '~all', which refers to all the web properties to which the user has access. + * @param string $profileId Profile ID for the web properties to retrieve. Can either be a specific profile ID or '~all', which refers to all the profiles to which the user has access. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param int max-results The maximum number of entries to include in this response. + * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter. + * @return Goals + */ + public function listManagementGoals($accountId, $webPropertyId, $profileId, $optParams = array()) { + $params = array('accountId' => $accountId, 'webPropertyId' => $webPropertyId, 'profileId' => $profileId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Goals($data); + } else { + return $data; + } + } + } + /** + * The "profiles" collection of methods. + * Typical usage is: + * + * $analyticsService = new apiAnalyticsService(...); + * $profiles = $analyticsService->profiles; + * + */ + class ManagementProfilesServiceResource extends apiServiceResource { + + + /** + * Lists profiles to which the user has access. (profiles.list) + * @param string $accountId Account ID for the web properties to retrieve. Can either be a specific account ID or '~all', which refers to all the accounts to which the user has access. + * @param string $webPropertyId Web property ID for the web properties to retrieve. Can either be a specific web property ID or '~all', which refers to all the web properties to which the user has access. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param int max-results The maximum number of entries to include in this response. + * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter. + * @return Profiles + */ + public function listManagementProfiles($accountId, $webPropertyId, $optParams = array()) { + $params = array('accountId' => $accountId, 'webPropertyId' => $webPropertyId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Profiles($data); + } else { + return $data; + } + } + } + + /** + * The "data" collection of methods. + * Typical usage is: + * + * $analyticsService = new apiAnalyticsService(...); + * $data = $analyticsService->data; + * + */ + class DataServiceResource extends apiServiceResource { + + + } + + + /** + * The "ga" collection of methods. + * Typical usage is: + * + * $analyticsService = new apiAnalyticsService(...); + * $ga = $analyticsService->ga; + * + */ + class DataGaServiceResource extends apiServiceResource { + + + /** + * Returns Analytics data for a profile. (ga.get) + * @param string $ids Unique table ID for retrieving Analytics data. Table ID is of the form ga:XXXX, where XXXX is the Analytics profile ID. + * @param string $start_date Start date for fetching Analytics data. All requests should specify a start date formatted as YYYY-MM-DD. + * @param string $end_date End date for fetching Analytics data. All requests should specify an end date formatted as YYYY-MM-DD. + * @param string $metrics A comma-separated list of Analytics metrics. E.g., 'ga:visits,ga:pageviews'. At least one metric must be specified. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param int max-results The maximum number of entries to include in this feed. + * @opt_param string sort A comma-separated list of dimensions or metrics that determine the sort order for Analytics data. + * @opt_param string dimensions A comma-separated list of Analytics dimensions. E.g., 'ga:browser,ga:city'. + * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter. + * @opt_param string segment An Analytics advanced segment to be applied to data. + * @opt_param string filters A comma-separated list of dimension or metric filters to be applied to Analytics data. + * @return GaData + */ + public function get($ids, $start_date, $end_date, $metrics, $optParams = array()) { + $params = array('ids' => $ids, 'start-date' => $start_date, 'end-date' => $end_date, 'metrics' => $metrics); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new GaData($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Analytics (v3). + *

            + * View and manage your Google Analytics data + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiAnalyticsService extends apiService { + public $management_webproperties; + public $management_segments; + public $management_accounts; + public $management_goals; + public $management_profiles; + public $data_ga; + /** + * Constructs the internal representation of the Analytics service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/analytics/v3/'; + $this->version = 'v3'; + $this->serviceName = 'analytics'; + + $apiClient->addService($this->serviceName, $this->version); + $this->management_webproperties = new ManagementWebpropertiesServiceResource($this, $this->serviceName, 'webproperties', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"format": "int32", "type": "integer", "location": "query"}, "start-index": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "analytics.management.webproperties.list", "httpMethod": "GET", "path": "management/accounts/{accountId}/webproperties", "response": {"$ref": "Webproperties"}}}}', true)); + $this->management_segments = new ManagementSegmentsServiceResource($this, $this->serviceName, 'segments', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"format": "int32", "type": "integer", "location": "query"}, "start-index": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}}, "response": {"$ref": "Segments"}, "httpMethod": "GET", "path": "management/segments", "id": "analytics.management.segments.list"}}}', true)); + $this->management_accounts = new ManagementAccountsServiceResource($this, $this->serviceName, 'accounts', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"format": "int32", "type": "integer", "location": "query"}, "start-index": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}}, "response": {"$ref": "Accounts"}, "httpMethod": "GET", "path": "management/accounts", "id": "analytics.management.accounts.list"}}}', true)); + $this->management_goals = new ManagementGoalsServiceResource($this, $this->serviceName, 'goals', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"format": "int32", "type": "integer", "location": "query"}, "profileId": {"required": true, "type": "string", "location": "path"}, "start-index": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}, "webPropertyId": {"required": true, "type": "string", "location": "path"}}, "id": "analytics.management.goals.list", "httpMethod": "GET", "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals", "response": {"$ref": "Goals"}}}}', true)); + $this->management_profiles = new ManagementProfilesServiceResource($this, $this->serviceName, 'profiles', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"format": "int32", "type": "integer", "location": "query"}, "start-index": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}, "webPropertyId": {"required": true, "type": "string", "location": "path"}}, "id": "analytics.management.profiles.list", "httpMethod": "GET", "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles", "response": {"$ref": "Profiles"}}}}', true)); + $this->data_ga = new DataGaServiceResource($this, $this->serviceName, 'ga', json_decode('{"methods": {"get": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"format": "int32", "type": "integer", "location": "query"}, "sort": {"type": "string", "location": "query"}, "dimensions": {"type": "string", "location": "query"}, "start-date": {"required": true, "type": "string", "location": "query"}, "start-index": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}, "end-date": {"required": true, "type": "string", "location": "query"}, "ids": {"required": true, "type": "string", "location": "query"}, "metrics": {"required": true, "type": "string", "location": "query"}, "filters": {"type": "string", "location": "query"}, "segment": {"type": "string", "location": "query"}}, "id": "analytics.data.ga.get", "httpMethod": "GET", "path": "data/ga", "response": {"$ref": "GaData"}}}}', true)); + } +} + +class Account extends apiModel { + public $kind; + public $name; + public $created; + public $updated; + protected $__childLinkType = 'AccountChildLink'; + protected $__childLinkDataType = ''; + public $childLink; + public $id; + public $selfLink; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setChildLink(AccountChildLink $childLink) { + $this->childLink = $childLink; + } + public function getChildLink() { + return $this->childLink; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class AccountChildLink extends apiModel { + public $href; + public $type; + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class Accounts extends apiModel { + public $username; + public $kind; + protected $__itemsType = 'Account'; + protected $__itemsDataType = 'array'; + public $items; + public $itemsPerPage; + public $previousLink; + public $startIndex; + public $nextLink; + public $totalResults; + public function setUsername($username) { + $this->username = $username; + } + public function getUsername() { + return $this->username; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(Account) */ $items) { + $this->assertIsArray($items, 'Account', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setPreviousLink($previousLink) { + $this->previousLink = $previousLink; + } + public function getPreviousLink() { + return $this->previousLink; + } + public function setStartIndex($startIndex) { + $this->startIndex = $startIndex; + } + public function getStartIndex() { + return $this->startIndex; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setTotalResults($totalResults) { + $this->totalResults = $totalResults; + } + public function getTotalResults() { + return $this->totalResults; + } +} + +class GaData extends apiModel { + public $kind; + public $rows; + public $containsSampledData; + public $totalResults; + public $itemsPerPage; + public $totalsForAllResults; + public $nextLink; + public $id; + protected $__queryType = 'GaDataQuery'; + protected $__queryDataType = ''; + public $query; + public $previousLink; + protected $__profileInfoType = 'GaDataProfileInfo'; + protected $__profileInfoDataType = ''; + public $profileInfo; + protected $__columnHeadersType = 'GaDataColumnHeaders'; + protected $__columnHeadersDataType = 'array'; + public $columnHeaders; + public $selfLink; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setRows(/* array(string) */ $rows) { + $this->assertIsArray($rows, 'string', __METHOD__); + $this->rows = $rows; + } + public function getRows() { + return $this->rows; + } + public function setContainsSampledData($containsSampledData) { + $this->containsSampledData = $containsSampledData; + } + public function getContainsSampledData() { + return $this->containsSampledData; + } + public function setTotalResults($totalResults) { + $this->totalResults = $totalResults; + } + public function getTotalResults() { + return $this->totalResults; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setTotalsForAllResults($totalsForAllResults) { + $this->totalsForAllResults = $totalsForAllResults; + } + public function getTotalsForAllResults() { + return $this->totalsForAllResults; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setQuery(GaDataQuery $query) { + $this->query = $query; + } + public function getQuery() { + return $this->query; + } + public function setPreviousLink($previousLink) { + $this->previousLink = $previousLink; + } + public function getPreviousLink() { + return $this->previousLink; + } + public function setProfileInfo(GaDataProfileInfo $profileInfo) { + $this->profileInfo = $profileInfo; + } + public function getProfileInfo() { + return $this->profileInfo; + } + public function setColumnHeaders(/* array(GaDataColumnHeaders) */ $columnHeaders) { + $this->assertIsArray($columnHeaders, 'GaDataColumnHeaders', __METHOD__); + $this->columnHeaders = $columnHeaders; + } + public function getColumnHeaders() { + return $this->columnHeaders; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class GaDataColumnHeaders extends apiModel { + public $dataType; + public $columnType; + public $name; + public function setDataType($dataType) { + $this->dataType = $dataType; + } + public function getDataType() { + return $this->dataType; + } + public function setColumnType($columnType) { + $this->columnType = $columnType; + } + public function getColumnType() { + return $this->columnType; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class GaDataProfileInfo extends apiModel { + public $webPropertyId; + public $internalWebPropertyId; + public $tableId; + public $profileId; + public $profileName; + public $accountId; + public function setWebPropertyId($webPropertyId) { + $this->webPropertyId = $webPropertyId; + } + public function getWebPropertyId() { + return $this->webPropertyId; + } + public function setInternalWebPropertyId($internalWebPropertyId) { + $this->internalWebPropertyId = $internalWebPropertyId; + } + public function getInternalWebPropertyId() { + return $this->internalWebPropertyId; + } + public function setTableId($tableId) { + $this->tableId = $tableId; + } + public function getTableId() { + return $this->tableId; + } + public function setProfileId($profileId) { + $this->profileId = $profileId; + } + public function getProfileId() { + return $this->profileId; + } + public function setProfileName($profileName) { + $this->profileName = $profileName; + } + public function getProfileName() { + return $this->profileName; + } + public function setAccountId($accountId) { + $this->accountId = $accountId; + } + public function getAccountId() { + return $this->accountId; + } +} + +class GaDataQuery extends apiModel { + public $max_results; + public $sort; + public $dimensions; + public $start_date; + public $start_index; + public $segment; + public $ids; + public $metrics; + public $filters; + public $end_date; + public function setMax_results($max_results) { + $this->max_results = $max_results; + } + public function getMax_results() { + return $this->max_results; + } + public function setSort(/* array(string) */ $sort) { + $this->assertIsArray($sort, 'string', __METHOD__); + $this->sort = $sort; + } + public function getSort() { + return $this->sort; + } + public function setDimensions($dimensions) { + $this->dimensions = $dimensions; + } + public function getDimensions() { + return $this->dimensions; + } + public function setStart_date($start_date) { + $this->start_date = $start_date; + } + public function getStart_date() { + return $this->start_date; + } + public function setStart_index($start_index) { + $this->start_index = $start_index; + } + public function getStart_index() { + return $this->start_index; + } + public function setSegment($segment) { + $this->segment = $segment; + } + public function getSegment() { + return $this->segment; + } + public function setIds($ids) { + $this->ids = $ids; + } + public function getIds() { + return $this->ids; + } + public function setMetrics(/* array(string) */ $metrics) { + $this->assertIsArray($metrics, 'string', __METHOD__); + $this->metrics = $metrics; + } + public function getMetrics() { + return $this->metrics; + } + public function setFilters($filters) { + $this->filters = $filters; + } + public function getFilters() { + return $this->filters; + } + public function setEnd_date($end_date) { + $this->end_date = $end_date; + } + public function getEnd_date() { + return $this->end_date; + } +} + +class Goal extends apiModel { + public $kind; + protected $__visitTimeOnSiteDetailsType = 'GoalVisitTimeOnSiteDetails'; + protected $__visitTimeOnSiteDetailsDataType = ''; + public $visitTimeOnSiteDetails; + public $name; + public $created; + protected $__urlDestinationDetailsType = 'GoalUrlDestinationDetails'; + protected $__urlDestinationDetailsDataType = ''; + public $urlDestinationDetails; + public $updated; + public $value; + protected $__visitNumPagesDetailsType = 'GoalVisitNumPagesDetails'; + protected $__visitNumPagesDetailsDataType = ''; + public $visitNumPagesDetails; + public $internalWebPropertyId; + protected $__eventDetailsType = 'GoalEventDetails'; + protected $__eventDetailsDataType = ''; + public $eventDetails; + public $webPropertyId; + public $active; + public $profileId; + protected $__parentLinkType = 'GoalParentLink'; + protected $__parentLinkDataType = ''; + public $parentLink; + public $type; + public $id; + public $selfLink; + public $accountId; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setVisitTimeOnSiteDetails(GoalVisitTimeOnSiteDetails $visitTimeOnSiteDetails) { + $this->visitTimeOnSiteDetails = $visitTimeOnSiteDetails; + } + public function getVisitTimeOnSiteDetails() { + return $this->visitTimeOnSiteDetails; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setUrlDestinationDetails(GoalUrlDestinationDetails $urlDestinationDetails) { + $this->urlDestinationDetails = $urlDestinationDetails; + } + public function getUrlDestinationDetails() { + return $this->urlDestinationDetails; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } + public function setVisitNumPagesDetails(GoalVisitNumPagesDetails $visitNumPagesDetails) { + $this->visitNumPagesDetails = $visitNumPagesDetails; + } + public function getVisitNumPagesDetails() { + return $this->visitNumPagesDetails; + } + public function setInternalWebPropertyId($internalWebPropertyId) { + $this->internalWebPropertyId = $internalWebPropertyId; + } + public function getInternalWebPropertyId() { + return $this->internalWebPropertyId; + } + public function setEventDetails(GoalEventDetails $eventDetails) { + $this->eventDetails = $eventDetails; + } + public function getEventDetails() { + return $this->eventDetails; + } + public function setWebPropertyId($webPropertyId) { + $this->webPropertyId = $webPropertyId; + } + public function getWebPropertyId() { + return $this->webPropertyId; + } + public function setActive($active) { + $this->active = $active; + } + public function getActive() { + return $this->active; + } + public function setProfileId($profileId) { + $this->profileId = $profileId; + } + public function getProfileId() { + return $this->profileId; + } + public function setParentLink(GoalParentLink $parentLink) { + $this->parentLink = $parentLink; + } + public function getParentLink() { + return $this->parentLink; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setAccountId($accountId) { + $this->accountId = $accountId; + } + public function getAccountId() { + return $this->accountId; + } +} + +class GoalEventDetails extends apiModel { + protected $__eventConditionsType = 'GoalEventDetailsEventConditions'; + protected $__eventConditionsDataType = 'array'; + public $eventConditions; + public $useEventValue; + public function setEventConditions(/* array(GoalEventDetailsEventConditions) */ $eventConditions) { + $this->assertIsArray($eventConditions, 'GoalEventDetailsEventConditions', __METHOD__); + $this->eventConditions = $eventConditions; + } + public function getEventConditions() { + return $this->eventConditions; + } + public function setUseEventValue($useEventValue) { + $this->useEventValue = $useEventValue; + } + public function getUseEventValue() { + return $this->useEventValue; + } +} + +class GoalEventDetailsEventConditions extends apiModel { + public $type; + public $matchType; + public $expression; + public $comparisonType; + public $comparisonValue; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setMatchType($matchType) { + $this->matchType = $matchType; + } + public function getMatchType() { + return $this->matchType; + } + public function setExpression($expression) { + $this->expression = $expression; + } + public function getExpression() { + return $this->expression; + } + public function setComparisonType($comparisonType) { + $this->comparisonType = $comparisonType; + } + public function getComparisonType() { + return $this->comparisonType; + } + public function setComparisonValue($comparisonValue) { + $this->comparisonValue = $comparisonValue; + } + public function getComparisonValue() { + return $this->comparisonValue; + } +} + +class GoalParentLink extends apiModel { + public $href; + public $type; + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class GoalUrlDestinationDetails extends apiModel { + public $url; + public $caseSensitive; + public $matchType; + protected $__stepsType = 'GoalUrlDestinationDetailsSteps'; + protected $__stepsDataType = 'array'; + public $steps; + public $firstStepRequired; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setCaseSensitive($caseSensitive) { + $this->caseSensitive = $caseSensitive; + } + public function getCaseSensitive() { + return $this->caseSensitive; + } + public function setMatchType($matchType) { + $this->matchType = $matchType; + } + public function getMatchType() { + return $this->matchType; + } + public function setSteps(/* array(GoalUrlDestinationDetailsSteps) */ $steps) { + $this->assertIsArray($steps, 'GoalUrlDestinationDetailsSteps', __METHOD__); + $this->steps = $steps; + } + public function getSteps() { + return $this->steps; + } + public function setFirstStepRequired($firstStepRequired) { + $this->firstStepRequired = $firstStepRequired; + } + public function getFirstStepRequired() { + return $this->firstStepRequired; + } +} + +class GoalUrlDestinationDetailsSteps extends apiModel { + public $url; + public $name; + public $number; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setNumber($number) { + $this->number = $number; + } + public function getNumber() { + return $this->number; + } +} + +class GoalVisitNumPagesDetails extends apiModel { + public $comparisonType; + public $comparisonValue; + public function setComparisonType($comparisonType) { + $this->comparisonType = $comparisonType; + } + public function getComparisonType() { + return $this->comparisonType; + } + public function setComparisonValue($comparisonValue) { + $this->comparisonValue = $comparisonValue; + } + public function getComparisonValue() { + return $this->comparisonValue; + } +} + +class GoalVisitTimeOnSiteDetails extends apiModel { + public $comparisonType; + public $comparisonValue; + public function setComparisonType($comparisonType) { + $this->comparisonType = $comparisonType; + } + public function getComparisonType() { + return $this->comparisonType; + } + public function setComparisonValue($comparisonValue) { + $this->comparisonValue = $comparisonValue; + } + public function getComparisonValue() { + return $this->comparisonValue; + } +} + +class Goals extends apiModel { + public $username; + public $kind; + protected $__itemsType = 'Goal'; + protected $__itemsDataType = 'array'; + public $items; + public $itemsPerPage; + public $previousLink; + public $startIndex; + public $nextLink; + public $totalResults; + public function setUsername($username) { + $this->username = $username; + } + public function getUsername() { + return $this->username; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(Goal) */ $items) { + $this->assertIsArray($items, 'Goal', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setPreviousLink($previousLink) { + $this->previousLink = $previousLink; + } + public function getPreviousLink() { + return $this->previousLink; + } + public function setStartIndex($startIndex) { + $this->startIndex = $startIndex; + } + public function getStartIndex() { + return $this->startIndex; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setTotalResults($totalResults) { + $this->totalResults = $totalResults; + } + public function getTotalResults() { + return $this->totalResults; + } +} + +class Profile extends apiModel { + public $defaultPage; + public $kind; + public $excludeQueryParameters; + public $name; + public $created; + public $webPropertyId; + public $updated; + public $siteSearchQueryParameters; + public $currency; + public $internalWebPropertyId; + protected $__childLinkType = 'ProfileChildLink'; + protected $__childLinkDataType = ''; + public $childLink; + public $timezone; + public $siteSearchCategoryParameters; + protected $__parentLinkType = 'ProfileParentLink'; + protected $__parentLinkDataType = ''; + public $parentLink; + public $id; + public $selfLink; + public $accountId; + public function setDefaultPage($defaultPage) { + $this->defaultPage = $defaultPage; + } + public function getDefaultPage() { + return $this->defaultPage; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setExcludeQueryParameters($excludeQueryParameters) { + $this->excludeQueryParameters = $excludeQueryParameters; + } + public function getExcludeQueryParameters() { + return $this->excludeQueryParameters; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setWebPropertyId($webPropertyId) { + $this->webPropertyId = $webPropertyId; + } + public function getWebPropertyId() { + return $this->webPropertyId; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setSiteSearchQueryParameters($siteSearchQueryParameters) { + $this->siteSearchQueryParameters = $siteSearchQueryParameters; + } + public function getSiteSearchQueryParameters() { + return $this->siteSearchQueryParameters; + } + public function setCurrency($currency) { + $this->currency = $currency; + } + public function getCurrency() { + return $this->currency; + } + public function setInternalWebPropertyId($internalWebPropertyId) { + $this->internalWebPropertyId = $internalWebPropertyId; + } + public function getInternalWebPropertyId() { + return $this->internalWebPropertyId; + } + public function setChildLink(ProfileChildLink $childLink) { + $this->childLink = $childLink; + } + public function getChildLink() { + return $this->childLink; + } + public function setTimezone($timezone) { + $this->timezone = $timezone; + } + public function getTimezone() { + return $this->timezone; + } + public function setSiteSearchCategoryParameters($siteSearchCategoryParameters) { + $this->siteSearchCategoryParameters = $siteSearchCategoryParameters; + } + public function getSiteSearchCategoryParameters() { + return $this->siteSearchCategoryParameters; + } + public function setParentLink(ProfileParentLink $parentLink) { + $this->parentLink = $parentLink; + } + public function getParentLink() { + return $this->parentLink; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setAccountId($accountId) { + $this->accountId = $accountId; + } + public function getAccountId() { + return $this->accountId; + } +} + +class ProfileChildLink extends apiModel { + public $href; + public $type; + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class ProfileParentLink extends apiModel { + public $href; + public $type; + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class Profiles extends apiModel { + public $username; + public $kind; + protected $__itemsType = 'Profile'; + protected $__itemsDataType = 'array'; + public $items; + public $itemsPerPage; + public $previousLink; + public $startIndex; + public $nextLink; + public $totalResults; + public function setUsername($username) { + $this->username = $username; + } + public function getUsername() { + return $this->username; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(Profile) */ $items) { + $this->assertIsArray($items, 'Profile', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setPreviousLink($previousLink) { + $this->previousLink = $previousLink; + } + public function getPreviousLink() { + return $this->previousLink; + } + public function setStartIndex($startIndex) { + $this->startIndex = $startIndex; + } + public function getStartIndex() { + return $this->startIndex; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setTotalResults($totalResults) { + $this->totalResults = $totalResults; + } + public function getTotalResults() { + return $this->totalResults; + } +} + +class Segment extends apiModel { + public $definition; + public $kind; + public $segmentId; + public $created; + public $updated; + public $id; + public $selfLink; + public $name; + public function setDefinition($definition) { + $this->definition = $definition; + } + public function getDefinition() { + return $this->definition; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setSegmentId($segmentId) { + $this->segmentId = $segmentId; + } + public function getSegmentId() { + return $this->segmentId; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class Segments extends apiModel { + public $username; + public $kind; + protected $__itemsType = 'Segment'; + protected $__itemsDataType = 'array'; + public $items; + public $itemsPerPage; + public $previousLink; + public $startIndex; + public $nextLink; + public $totalResults; + public function setUsername($username) { + $this->username = $username; + } + public function getUsername() { + return $this->username; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(Segment) */ $items) { + $this->assertIsArray($items, 'Segment', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setPreviousLink($previousLink) { + $this->previousLink = $previousLink; + } + public function getPreviousLink() { + return $this->previousLink; + } + public function setStartIndex($startIndex) { + $this->startIndex = $startIndex; + } + public function getStartIndex() { + return $this->startIndex; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setTotalResults($totalResults) { + $this->totalResults = $totalResults; + } + public function getTotalResults() { + return $this->totalResults; + } +} + +class Webproperties extends apiModel { + public $username; + public $kind; + protected $__itemsType = 'Webproperty'; + protected $__itemsDataType = 'array'; + public $items; + public $itemsPerPage; + public $previousLink; + public $startIndex; + public $nextLink; + public $totalResults; + public function setUsername($username) { + $this->username = $username; + } + public function getUsername() { + return $this->username; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(Webproperty) */ $items) { + $this->assertIsArray($items, 'Webproperty', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setPreviousLink($previousLink) { + $this->previousLink = $previousLink; + } + public function getPreviousLink() { + return $this->previousLink; + } + public function setStartIndex($startIndex) { + $this->startIndex = $startIndex; + } + public function getStartIndex() { + return $this->startIndex; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setTotalResults($totalResults) { + $this->totalResults = $totalResults; + } + public function getTotalResults() { + return $this->totalResults; + } +} + +class Webproperty extends apiModel { + public $kind; + public $name; + public $created; + public $updated; + public $websiteUrl; + public $internalWebPropertyId; + protected $__childLinkType = 'WebpropertyChildLink'; + protected $__childLinkDataType = ''; + public $childLink; + protected $__parentLinkType = 'WebpropertyParentLink'; + protected $__parentLinkDataType = ''; + public $parentLink; + public $id; + public $selfLink; + public $accountId; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setWebsiteUrl($websiteUrl) { + $this->websiteUrl = $websiteUrl; + } + public function getWebsiteUrl() { + return $this->websiteUrl; + } + public function setInternalWebPropertyId($internalWebPropertyId) { + $this->internalWebPropertyId = $internalWebPropertyId; + } + public function getInternalWebPropertyId() { + return $this->internalWebPropertyId; + } + public function setChildLink(WebpropertyChildLink $childLink) { + $this->childLink = $childLink; + } + public function getChildLink() { + return $this->childLink; + } + public function setParentLink(WebpropertyParentLink $parentLink) { + $this->parentLink = $parentLink; + } + public function getParentLink() { + return $this->parentLink; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setAccountId($accountId) { + $this->accountId = $accountId; + } + public function getAccountId() { + return $this->accountId; + } +} + +class WebpropertyChildLink extends apiModel { + public $href; + public $type; + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class WebpropertyParentLink extends apiModel { + public $href; + public $type; + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiBigqueryService.php b/inc/vendors/social-login/Google/contrib/apiBigqueryService.php new file mode 100755 index 00000000..e6ec6916 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiBigqueryService.php @@ -0,0 +1,1702 @@ + + * $bigqueryService = new apiBigqueryService(...); + * $tables = $bigqueryService->tables; + *
            + */ + class TablesServiceResource extends apiServiceResource { + + + /** + * Creates a new, empty table in the dataset. (tables.insert) + * @param Table $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string projectId Project ID of the new table + * @opt_param string datasetId Dataset ID of the new table + * @return Table + */ + public function insert(Table $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Table($data); + } else { + return $data; + } + } + /** + * Gets the specified table resource by table ID. This method does not return the data in the table, + * it only returns the table resource, which describes the structure of this table. (tables.get) + * @param string $projectId Project ID of the requested table + * @param string $datasetId Dataset ID of the requested table + * @param string $tableId Table ID of the requested table + * @return Table + */ + public function get($projectId, $datasetId, $tableId, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId, 'tableId' => $tableId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Table($data); + } else { + return $data; + } + } + /** + * Lists all tables in the specified dataset. (tables.list) + * @param string $projectId Project ID of the tables to list + * @param string $datasetId Dataset ID of the tables to list + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken Page token, returned by a previous call, to request the next page of results + * @opt_param string maxResults Maximum number of results to return + * @return TableList + */ + public function listTables($projectId, $datasetId, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new TableList($data); + } else { + return $data; + } + } + /** + * Updates information in an existing table, specified by tableId. (tables.update) + * @param Table $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string projectId Project ID of the table to update + * @opt_param string datasetId Dataset ID of the table to update + * @opt_param string tableId Table ID of the table to update + * @return Table + */ + public function update(Table $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Table($data); + } else { + return $data; + } + } + /** + * Updates information in an existing table, specified by tableId. This method supports patch + * semantics. (tables.patch) + * @param string $projectId Project ID of the table to update + * @param string $datasetId Dataset ID of the table to update + * @param string $tableId Table ID of the table to update + * @param Table $postBody + * @return Table + */ + public function patch($projectId, $datasetId, $tableId, Table $postBody, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId, 'tableId' => $tableId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Table($data); + } else { + return $data; + } + } + /** + * Deletes the table specified by tableId from the dataset. If the table contains data, all the data + * will be deleted. (tables.delete) + * @param string $projectId Project ID of the table to delete + * @param string $datasetId Dataset ID of the table to delete + * @param string $tableId Table ID of the table to delete + */ + public function delete($projectId, $datasetId, $tableId, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId, 'tableId' => $tableId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "datasets" collection of methods. + * Typical usage is: + * + * $bigqueryService = new apiBigqueryService(...); + * $datasets = $bigqueryService->datasets; + * + */ + class DatasetsServiceResource extends apiServiceResource { + + + /** + * Creates a new empty dataset. (datasets.insert) + * @param Dataset $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string projectId Project ID of the new dataset + * @return Dataset + */ + public function insert(Dataset $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Dataset($data); + } else { + return $data; + } + } + /** + * Returns the dataset specified by datasetID. (datasets.get) + * @param string $projectId Project ID of the requested dataset + * @param string $datasetId Dataset ID of the requested dataset + * @return Dataset + */ + public function get($projectId, $datasetId, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Dataset($data); + } else { + return $data; + } + } + /** + * Lists all the datasets in the specified project to which the caller has read access; however, a + * project owner can list (but not necessarily get) all datasets in his project. (datasets.list) + * @param string $projectId Project ID of the datasets to be listed + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken Page token, returned by a previous call, to request the next page of results + * @opt_param string maxResults The maximum number of results to return + * @return DatasetList + */ + public function listDatasets($projectId, $optParams = array()) { + $params = array('projectId' => $projectId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new DatasetList($data); + } else { + return $data; + } + } + /** + * Updates information in an existing dataset, specified by datasetId. Properties not included in + * the submitted resource will not be changed. If you include the access property without any values + * assigned, the request will fail as you must specify at least one owner for a dataset. + * (datasets.update) + * @param Dataset $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string projectId Project ID of the dataset being updated + * @opt_param string datasetId Dataset ID of the dataset being updated + * @return Dataset + */ + public function update(Dataset $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Dataset($data); + } else { + return $data; + } + } + /** + * Updates information in an existing dataset, specified by datasetId. Properties not included in + * the submitted resource will not be changed. If you include the access property without any values + * assigned, the request will fail as you must specify at least one owner for a dataset. This method + * supports patch semantics. (datasets.patch) + * @param string $projectId Project ID of the dataset being updated + * @param string $datasetId Dataset ID of the dataset being updated + * @param Dataset $postBody + * @return Dataset + */ + public function patch($projectId, $datasetId, Dataset $postBody, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Dataset($data); + } else { + return $data; + } + } + /** + * Deletes the dataset specified by datasetId value. Before you can delete a dataset, you must + * delete all its tables, either manually or by specifying deleteContents. Immediately after + * deletion, you can create another dataset with the same name. (datasets.delete) + * @param string $projectId Project ID of the dataset being deleted + * @param string $datasetId Dataset ID of dataset being deleted + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool deleteContents If True, delete all the tables in the dataset. If False and the dataset contains tables, the request will fail. Default is False + */ + public function delete($projectId, $datasetId, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "jobs" collection of methods. + * Typical usage is: + * + * $bigqueryService = new apiBigqueryService(...); + * $jobs = $bigqueryService->jobs; + * + */ + class JobsServiceResource extends apiServiceResource { + + + /** + * Starts a new asynchronous job. (jobs.insert) + * @param Job $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string projectId Project ID of the project that will be billed for the job + * @return Job + */ + public function insert(Job $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Job($data); + } else { + return $data; + } + } + /** + * Retrieves the specified job by ID. (jobs.get) + * @param string $projectId Project ID of the requested job + * @param string $jobId Job ID of the requested job + * @return Job + */ + public function get($projectId, $jobId, $optParams = array()) { + $params = array('projectId' => $projectId, 'jobId' => $jobId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Job($data); + } else { + return $data; + } + } + /** + * Lists all the Jobs in the specified project that were started by the user. (jobs.list) + * @param string $projectId Project ID of the jobs to list + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string projection Restrict information returned to a set of selected fields + * @opt_param string stateFilter Filter for job state + * @opt_param bool allUsers Whether to display jobs owned by all users in the project. Default false + * @opt_param string maxResults Maximum number of results to return + * @opt_param string pageToken Page token, returned by a previous call, to request the next page of results + * @return JobList + */ + public function listJobs($projectId, $optParams = array()) { + $params = array('projectId' => $projectId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new JobList($data); + } else { + return $data; + } + } + /** + * Runs a BigQuery SQL query synchronously and returns query results if the query completes within a + * specified timeout. (jobs.query) + * @param string $projectId Project ID of the project billed for the query + * @param QueryRequest $postBody + * @return QueryResponse + */ + public function query($projectId, QueryRequest $postBody, $optParams = array()) { + $params = array('projectId' => $projectId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('query', array($params)); + if ($this->useObjects()) { + return new QueryResponse($data); + } else { + return $data; + } + } + /** + * Retrieves the results of a query job. (jobs.getQueryResults) + * @param string $projectId Project ID of the query job + * @param string $jobId Job ID of the query job + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string timeoutMs How long to wait for the query to complete, in milliseconds, before returning. Default is to return immediately. If the timeout passes before the job completes, the request will fail with a TIMEOUT error + * @opt_param string startIndex Zero-based index of the starting row + * @opt_param string maxResults Maximum number of results to read + * @return GetQueryResultsResponse + */ + public function getQueryResults($projectId, $jobId, $optParams = array()) { + $params = array('projectId' => $projectId, 'jobId' => $jobId); + $params = array_merge($params, $optParams); + $data = $this->__call('getQueryResults', array($params)); + if ($this->useObjects()) { + return new GetQueryResultsResponse($data); + } else { + return $data; + } + } + /** + * Deletes a completed job specified by job ID. (jobs.delete) + * @param string $projectId Project ID of the job to delete + * @param string $jobId Job ID of the job to delete + */ + public function delete($projectId, $jobId, $optParams = array()) { + $params = array('projectId' => $projectId, 'jobId' => $jobId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "tabledata" collection of methods. + * Typical usage is: + * + * $bigqueryService = new apiBigqueryService(...); + * $tabledata = $bigqueryService->tabledata; + * + */ + class TabledataServiceResource extends apiServiceResource { + + + /** + * Retrieves table data from a specified set of rows. (tabledata.list) + * @param string $projectId Project ID of the table to read + * @param string $datasetId Dataset ID of the table to read + * @param string $tableId Table ID of the table to read + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string startIndex Zero-based index of the starting row to read + * @opt_param string maxResults Maximum number of results to return + * @return TableDataList + */ + public function listTabledata($projectId, $datasetId, $tableId, $optParams = array()) { + $params = array('projectId' => $projectId, 'datasetId' => $datasetId, 'tableId' => $tableId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new TableDataList($data); + } else { + return $data; + } + } + } + + /** + * The "projects" collection of methods. + * Typical usage is: + * + * $bigqueryService = new apiBigqueryService(...); + * $projects = $bigqueryService->projects; + * + */ + class ProjectsServiceResource extends apiServiceResource { + + + /** + * Lists the projects to which you have at least read access. (projects.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken Page token, returned by a previous call, to request the next page of results + * @opt_param string maxResults Maximum number of results to return + * @return ProjectList + */ + public function listProjects($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new ProjectList($data); + } else { + return $data; + } + } + } + +/** + * Service definition for Bigquery (v2). + *

            + * A data platform for customers to create, manage, share and query data. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiBigqueryService extends apiService { + public $tables; + public $datasets; + public $jobs; + public $tabledata; + public $projects; + /** + * Constructs the internal representation of the Bigquery service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/bigquery/v2/'; + $this->version = 'v2'; + $this->serviceName = 'bigquery'; + + $apiClient->addService($this->serviceName, $this->version); + $this->tables = new TablesServiceResource($this, $this->serviceName, 'tables', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"type": "string", "location": "path"}, "datasetId": {"type": "string", "location": "path"}}, "request": {"$ref": "Table"}, "id": "bigquery.tables.insert", "httpMethod": "POST", "path": "projects/{projectId}/datasets/{datasetId}/tables", "response": {"$ref": "Table"}}, "get": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "tableId": {"required": true, "type": "string", "location": "path"}, "datasetId": {"required": true, "type": "string", "location": "path"}}, "id": "bigquery.tables.get", "httpMethod": "GET", "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}", "response": {"$ref": "Table"}}, "list": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "datasetId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}, "projectId": {"required": true, "type": "string", "location": "path"}}, "id": "bigquery.tables.list", "httpMethod": "GET", "path": "projects/{projectId}/datasets/{datasetId}/tables", "response": {"$ref": "TableList"}}, "update": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"type": "string", "location": "path"}, "tableId": {"type": "string", "location": "path"}, "datasetId": {"type": "string", "location": "path"}}, "request": {"$ref": "Table"}, "id": "bigquery.tables.update", "httpMethod": "PUT", "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}", "response": {"$ref": "Table"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "tableId": {"required": true, "type": "string", "location": "path"}, "datasetId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Table"}, "id": "bigquery.tables.patch", "httpMethod": "PATCH", "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}", "response": {"$ref": "Table"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "tableId": {"required": true, "type": "string", "location": "path"}, "datasetId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}", "id": "bigquery.tables.delete"}}}', true)); + $this->datasets = new DatasetsServiceResource($this, $this->serviceName, 'datasets', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"type": "string", "location": "path"}}, "request": {"$ref": "Dataset"}, "id": "bigquery.datasets.insert", "httpMethod": "POST", "path": "projects/{projectId}/datasets", "response": {"$ref": "Dataset"}}, "get": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "datasetId": {"required": true, "type": "string", "location": "path"}}, "id": "bigquery.datasets.get", "httpMethod": "GET", "path": "projects/{projectId}/datasets/{datasetId}", "response": {"$ref": "Dataset"}}, "list": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}, "projectId": {"required": true, "type": "string", "location": "path"}}, "id": "bigquery.datasets.list", "httpMethod": "GET", "path": "projects/{projectId}/datasets", "response": {"$ref": "DatasetList"}}, "update": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"type": "string", "location": "path"}, "datasetId": {"type": "string", "location": "path"}}, "request": {"$ref": "Dataset"}, "id": "bigquery.datasets.update", "httpMethod": "PUT", "path": "projects/{projectId}/datasets/{datasetId}", "response": {"$ref": "Dataset"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "datasetId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Dataset"}, "id": "bigquery.datasets.patch", "httpMethod": "PATCH", "path": "projects/{projectId}/datasets/{datasetId}", "response": {"$ref": "Dataset"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"deleteContents": {"type": "boolean", "location": "query"}, "datasetId": {"required": true, "type": "string", "location": "path"}, "projectId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "projects/{projectId}/datasets/{datasetId}", "id": "bigquery.datasets.delete"}}}', true)); + $this->jobs = new JobsServiceResource($this, $this->serviceName, 'jobs', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"type": "string", "location": "path"}}, "mediaUpload": {"accept": ["application/octet-stream"], "protocols": {"simple": {"path": "/upload/bigquery/v2/projects/{projectId}/jobs", "multipart": true}, "resumable": {"path": "/resumable/upload/bigquery/v2/projects/{projectId}/jobs", "multipart": true}}}, "request": {"$ref": "Job"}, "id": "bigquery.jobs.insert", "httpMethod": "POST", "path": "projects/{projectId}/jobs", "response": {"$ref": "Job"}}, "get": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "jobId": {"required": true, "type": "string", "location": "path"}}, "id": "bigquery.jobs.get", "httpMethod": "GET", "path": "projects/{projectId}/jobs/{jobId}", "response": {"$ref": "Job"}}, "list": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projection": {"enum": ["full", "minimal"], "type": "string", "location": "query"}, "stateFilter": {"enum": ["done", "pending", "running"], "repeated": true, "location": "query", "type": "string"}, "projectId": {"required": true, "type": "string", "location": "path"}, "allUsers": {"type": "boolean", "location": "query"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}, "pageToken": {"type": "string", "location": "query"}}, "id": "bigquery.jobs.list", "httpMethod": "GET", "path": "projects/{projectId}/jobs", "response": {"$ref": "JobList"}}, "query": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "QueryRequest"}, "id": "bigquery.jobs.query", "httpMethod": "POST", "path": "projects/{projectId}/queries", "response": {"$ref": "QueryResponse"}}, "getQueryResults": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"timeoutMs": {"format": "uint32", "type": "integer", "location": "query"}, "projectId": {"required": true, "type": "string", "location": "path"}, "startIndex": {"format": "uint64", "type": "string", "location": "query"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}, "jobId": {"required": true, "type": "string", "location": "path"}}, "id": "bigquery.jobs.getQueryResults", "httpMethod": "GET", "path": "projects/{projectId}/queries/{jobId}", "response": {"$ref": "GetQueryResultsResponse"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "jobId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "projects/{projectId}/jobs/{jobId}", "id": "bigquery.jobs.delete"}}}', true)); + $this->tabledata = new TabledataServiceResource($this, $this->serviceName, 'tabledata', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"projectId": {"required": true, "type": "string", "location": "path"}, "startIndex": {"format": "uint64", "type": "string", "location": "query"}, "tableId": {"required": true, "type": "string", "location": "path"}, "datasetId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}}, "id": "bigquery.tabledata.list", "httpMethod": "GET", "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}/data", "response": {"$ref": "TableDataList"}}}}', true)); + $this->projects = new ProjectsServiceResource($this, $this->serviceName, 'projects', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/bigquery"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}}, "response": {"$ref": "ProjectList"}, "httpMethod": "GET", "path": "projects", "id": "bigquery.projects.list"}}}', true)); + + } +} + +class Dataset extends apiModel { + public $kind; + public $description; + protected $__datasetReferenceType = 'DatasetReference'; + protected $__datasetReferenceDataType = ''; + public $datasetReference; + public $creationTime; + protected $__accessType = 'DatasetAccess'; + protected $__accessDataType = 'array'; + public $access; + public $etag; + public $friendlyName; + public $lastModifiedTime; + public $id; + public $selfLink; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setDatasetReference(DatasetReference $datasetReference) { + $this->datasetReference = $datasetReference; + } + public function getDatasetReference() { + return $this->datasetReference; + } + public function setCreationTime($creationTime) { + $this->creationTime = $creationTime; + } + public function getCreationTime() { + return $this->creationTime; + } + public function setAccess(/* array(DatasetAccess) */ $access) { + $this->assertIsArray($access, 'DatasetAccess', __METHOD__); + $this->access = $access; + } + public function getAccess() { + return $this->access; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setFriendlyName($friendlyName) { + $this->friendlyName = $friendlyName; + } + public function getFriendlyName() { + return $this->friendlyName; + } + public function setLastModifiedTime($lastModifiedTime) { + $this->lastModifiedTime = $lastModifiedTime; + } + public function getLastModifiedTime() { + return $this->lastModifiedTime; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class DatasetAccess extends apiModel { + public $specialGroup; + public $domain; + public $role; + public $groupByEmail; + public $userByEmail; + public function setSpecialGroup($specialGroup) { + $this->specialGroup = $specialGroup; + } + public function getSpecialGroup() { + return $this->specialGroup; + } + public function setDomain($domain) { + $this->domain = $domain; + } + public function getDomain() { + return $this->domain; + } + public function setRole($role) { + $this->role = $role; + } + public function getRole() { + return $this->role; + } + public function setGroupByEmail($groupByEmail) { + $this->groupByEmail = $groupByEmail; + } + public function getGroupByEmail() { + return $this->groupByEmail; + } + public function setUserByEmail($userByEmail) { + $this->userByEmail = $userByEmail; + } + public function getUserByEmail() { + return $this->userByEmail; + } +} + +class DatasetList extends apiModel { + public $nextPageToken; + public $kind; + protected $__datasetsType = 'DatasetListDatasets'; + protected $__datasetsDataType = 'array'; + public $datasets; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDatasets(/* array(DatasetListDatasets) */ $datasets) { + $this->assertIsArray($datasets, 'DatasetListDatasets', __METHOD__); + $this->datasets = $datasets; + } + public function getDatasets() { + return $this->datasets; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class DatasetListDatasets extends apiModel { + public $friendlyName; + public $kind; + public $id; + protected $__datasetReferenceType = 'DatasetReference'; + protected $__datasetReferenceDataType = ''; + public $datasetReference; + public function setFriendlyName($friendlyName) { + $this->friendlyName = $friendlyName; + } + public function getFriendlyName() { + return $this->friendlyName; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setDatasetReference(DatasetReference $datasetReference) { + $this->datasetReference = $datasetReference; + } + public function getDatasetReference() { + return $this->datasetReference; + } +} + +class DatasetReference extends apiModel { + public $projectId; + public $datasetId; + public function setProjectId($projectId) { + $this->projectId = $projectId; + } + public function getProjectId() { + return $this->projectId; + } + public function setDatasetId($datasetId) { + $this->datasetId = $datasetId; + } + public function getDatasetId() { + return $this->datasetId; + } +} + +class ErrorProto extends apiModel { + public $debugInfo; + public $message; + public $reason; + public $location; + public function setDebugInfo($debugInfo) { + $this->debugInfo = $debugInfo; + } + public function getDebugInfo() { + return $this->debugInfo; + } + public function setMessage($message) { + $this->message = $message; + } + public function getMessage() { + return $this->message; + } + public function setReason($reason) { + $this->reason = $reason; + } + public function getReason() { + return $this->reason; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } +} + +class GetQueryResultsResponse extends apiModel { + public $kind; + protected $__rowsType = 'TableRow'; + protected $__rowsDataType = 'array'; + public $rows; + protected $__jobReferenceType = 'JobReference'; + protected $__jobReferenceDataType = ''; + public $jobReference; + public $jobComplete; + public $totalRows; + public $etag; + protected $__schemaType = 'TableSchema'; + protected $__schemaDataType = ''; + public $schema; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setRows(/* array(TableRow) */ $rows) { + $this->assertIsArray($rows, 'TableRow', __METHOD__); + $this->rows = $rows; + } + public function getRows() { + return $this->rows; + } + public function setJobReference(JobReference $jobReference) { + $this->jobReference = $jobReference; + } + public function getJobReference() { + return $this->jobReference; + } + public function setJobComplete($jobComplete) { + $this->jobComplete = $jobComplete; + } + public function getJobComplete() { + return $this->jobComplete; + } + public function setTotalRows($totalRows) { + $this->totalRows = $totalRows; + } + public function getTotalRows() { + return $this->totalRows; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setSchema(TableSchema $schema) { + $this->schema = $schema; + } + public function getSchema() { + return $this->schema; + } +} + +class Job extends apiModel { + protected $__statusType = 'JobStatus'; + protected $__statusDataType = ''; + public $status; + public $kind; + protected $__statisticsType = 'JobStatistics'; + protected $__statisticsDataType = ''; + public $statistics; + protected $__jobReferenceType = 'JobReference'; + protected $__jobReferenceDataType = ''; + public $jobReference; + public $etag; + protected $__configurationType = 'JobConfiguration'; + protected $__configurationDataType = ''; + public $configuration; + public $id; + public $selfLink; + public function setStatus(JobStatus $status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setStatistics(JobStatistics $statistics) { + $this->statistics = $statistics; + } + public function getStatistics() { + return $this->statistics; + } + public function setJobReference(JobReference $jobReference) { + $this->jobReference = $jobReference; + } + public function getJobReference() { + return $this->jobReference; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setConfiguration(JobConfiguration $configuration) { + $this->configuration = $configuration; + } + public function getConfiguration() { + return $this->configuration; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class JobConfiguration extends apiModel { + protected $__loadType = 'JobConfigurationLoad'; + protected $__loadDataType = ''; + public $load; + protected $__linkType = 'JobConfigurationLink'; + protected $__linkDataType = ''; + public $link; + protected $__queryType = 'JobConfigurationQuery'; + protected $__queryDataType = ''; + public $query; + protected $__copyType = 'JobConfigurationTableCopy'; + protected $__copyDataType = ''; + public $copy; + protected $__extractType = 'JobConfigurationExtract'; + protected $__extractDataType = ''; + public $extract; + public $properties; + public function setLoad(JobConfigurationLoad $load) { + $this->load = $load; + } + public function getLoad() { + return $this->load; + } + public function setLink(JobConfigurationLink $link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setQuery(JobConfigurationQuery $query) { + $this->query = $query; + } + public function getQuery() { + return $this->query; + } + public function setCopy(JobConfigurationTableCopy $copy) { + $this->copy = $copy; + } + public function getCopy() { + return $this->copy; + } + public function setExtract(JobConfigurationExtract $extract) { + $this->extract = $extract; + } + public function getExtract() { + return $this->extract; + } + public function setProperties($properties) { + $this->properties = $properties; + } + public function getProperties() { + return $this->properties; + } +} + +class JobConfigurationExtract extends apiModel { + public $destinationUri; + protected $__sourceTableType = 'TableReference'; + protected $__sourceTableDataType = ''; + public $sourceTable; + public function setDestinationUri($destinationUri) { + $this->destinationUri = $destinationUri; + } + public function getDestinationUri() { + return $this->destinationUri; + } + public function setSourceTable(TableReference $sourceTable) { + $this->sourceTable = $sourceTable; + } + public function getSourceTable() { + return $this->sourceTable; + } +} + +class JobConfigurationLink extends apiModel { + public $createDisposition; + protected $__destinationTableType = 'TableReference'; + protected $__destinationTableDataType = ''; + public $destinationTable; + public $sourceUri; + public function setCreateDisposition($createDisposition) { + $this->createDisposition = $createDisposition; + } + public function getCreateDisposition() { + return $this->createDisposition; + } + public function setDestinationTable(TableReference $destinationTable) { + $this->destinationTable = $destinationTable; + } + public function getDestinationTable() { + return $this->destinationTable; + } + public function setSourceUri($sourceUri) { + $this->sourceUri = $sourceUri; + } + public function getSourceUri() { + return $this->sourceUri; + } +} + +class JobConfigurationLoad extends apiModel { + public $encoding; + public $fieldDelimiter; + protected $__destinationTableType = 'TableReference'; + protected $__destinationTableDataType = ''; + public $destinationTable; + public $maxBadRecords; + public $writeDisposition; + public $sourceUris; + public $skipLeadingRows; + public $createDisposition; + protected $__schemaType = 'TableSchema'; + protected $__schemaDataType = ''; + public $schema; + public function setEncoding($encoding) { + $this->encoding = $encoding; + } + public function getEncoding() { + return $this->encoding; + } + public function setFieldDelimiter($fieldDelimiter) { + $this->fieldDelimiter = $fieldDelimiter; + } + public function getFieldDelimiter() { + return $this->fieldDelimiter; + } + public function setDestinationTable(TableReference $destinationTable) { + $this->destinationTable = $destinationTable; + } + public function getDestinationTable() { + return $this->destinationTable; + } + public function setMaxBadRecords($maxBadRecords) { + $this->maxBadRecords = $maxBadRecords; + } + public function getMaxBadRecords() { + return $this->maxBadRecords; + } + public function setWriteDisposition($writeDisposition) { + $this->writeDisposition = $writeDisposition; + } + public function getWriteDisposition() { + return $this->writeDisposition; + } + public function setSourceUris(/* array(string) */ $sourceUris) { + $this->assertIsArray($sourceUris, 'string', __METHOD__); + $this->sourceUris = $sourceUris; + } + public function getSourceUris() { + return $this->sourceUris; + } + public function setSkipLeadingRows($skipLeadingRows) { + $this->skipLeadingRows = $skipLeadingRows; + } + public function getSkipLeadingRows() { + return $this->skipLeadingRows; + } + public function setCreateDisposition($createDisposition) { + $this->createDisposition = $createDisposition; + } + public function getCreateDisposition() { + return $this->createDisposition; + } + public function setSchema(TableSchema $schema) { + $this->schema = $schema; + } + public function getSchema() { + return $this->schema; + } +} + +class JobConfigurationQuery extends apiModel { + public $createDisposition; + public $query; + public $writeDisposition; + protected $__destinationTableType = 'TableReference'; + protected $__destinationTableDataType = ''; + public $destinationTable; + protected $__defaultDatasetType = 'DatasetReference'; + protected $__defaultDatasetDataType = ''; + public $defaultDataset; + public function setCreateDisposition($createDisposition) { + $this->createDisposition = $createDisposition; + } + public function getCreateDisposition() { + return $this->createDisposition; + } + public function setQuery($query) { + $this->query = $query; + } + public function getQuery() { + return $this->query; + } + public function setWriteDisposition($writeDisposition) { + $this->writeDisposition = $writeDisposition; + } + public function getWriteDisposition() { + return $this->writeDisposition; + } + public function setDestinationTable(TableReference $destinationTable) { + $this->destinationTable = $destinationTable; + } + public function getDestinationTable() { + return $this->destinationTable; + } + public function setDefaultDataset(DatasetReference $defaultDataset) { + $this->defaultDataset = $defaultDataset; + } + public function getDefaultDataset() { + return $this->defaultDataset; + } +} + +class JobConfigurationTableCopy extends apiModel { + public $createDisposition; + public $writeDisposition; + protected $__destinationTableType = 'TableReference'; + protected $__destinationTableDataType = ''; + public $destinationTable; + protected $__sourceTableType = 'TableReference'; + protected $__sourceTableDataType = ''; + public $sourceTable; + public function setCreateDisposition($createDisposition) { + $this->createDisposition = $createDisposition; + } + public function getCreateDisposition() { + return $this->createDisposition; + } + public function setWriteDisposition($writeDisposition) { + $this->writeDisposition = $writeDisposition; + } + public function getWriteDisposition() { + return $this->writeDisposition; + } + public function setDestinationTable(TableReference $destinationTable) { + $this->destinationTable = $destinationTable; + } + public function getDestinationTable() { + return $this->destinationTable; + } + public function setSourceTable(TableReference $sourceTable) { + $this->sourceTable = $sourceTable; + } + public function getSourceTable() { + return $this->sourceTable; + } +} + +class JobList extends apiModel { + public $nextPageToken; + public $totalItems; + public $kind; + public $etag; + protected $__jobsType = 'JobListJobs'; + protected $__jobsDataType = 'array'; + public $jobs; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setJobs(/* array(JobListJobs) */ $jobs) { + $this->assertIsArray($jobs, 'JobListJobs', __METHOD__); + $this->jobs = $jobs; + } + public function getJobs() { + return $this->jobs; + } +} + +class JobListJobs extends apiModel { + protected $__statusType = 'JobStatus'; + protected $__statusDataType = ''; + public $status; + protected $__statisticsType = 'JobStatistics'; + protected $__statisticsDataType = ''; + public $statistics; + protected $__jobReferenceType = 'JobReference'; + protected $__jobReferenceDataType = ''; + public $jobReference; + public $state; + protected $__configurationType = 'JobConfiguration'; + protected $__configurationDataType = ''; + public $configuration; + public $id; + protected $__errorResultType = 'ErrorProto'; + protected $__errorResultDataType = ''; + public $errorResult; + public function setStatus(JobStatus $status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setStatistics(JobStatistics $statistics) { + $this->statistics = $statistics; + } + public function getStatistics() { + return $this->statistics; + } + public function setJobReference(JobReference $jobReference) { + $this->jobReference = $jobReference; + } + public function getJobReference() { + return $this->jobReference; + } + public function setState($state) { + $this->state = $state; + } + public function getState() { + return $this->state; + } + public function setConfiguration(JobConfiguration $configuration) { + $this->configuration = $configuration; + } + public function getConfiguration() { + return $this->configuration; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setErrorResult(ErrorProto $errorResult) { + $this->errorResult = $errorResult; + } + public function getErrorResult() { + return $this->errorResult; + } +} + +class JobReference extends apiModel { + public $projectId; + public $jobId; + public function setProjectId($projectId) { + $this->projectId = $projectId; + } + public function getProjectId() { + return $this->projectId; + } + public function setJobId($jobId) { + $this->jobId = $jobId; + } + public function getJobId() { + return $this->jobId; + } +} + +class JobStatistics extends apiModel { + public $endTime; + public $totalBytesProcessed; + public $startTime; + public function setEndTime($endTime) { + $this->endTime = $endTime; + } + public function getEndTime() { + return $this->endTime; + } + public function setTotalBytesProcessed($totalBytesProcessed) { + $this->totalBytesProcessed = $totalBytesProcessed; + } + public function getTotalBytesProcessed() { + return $this->totalBytesProcessed; + } + public function setStartTime($startTime) { + $this->startTime = $startTime; + } + public function getStartTime() { + return $this->startTime; + } +} + +class JobStatus extends apiModel { + public $state; + protected $__errorsType = 'ErrorProto'; + protected $__errorsDataType = 'array'; + public $errors; + protected $__errorResultType = 'ErrorProto'; + protected $__errorResultDataType = ''; + public $errorResult; + public function setState($state) { + $this->state = $state; + } + public function getState() { + return $this->state; + } + public function setErrors(/* array(ErrorProto) */ $errors) { + $this->assertIsArray($errors, 'ErrorProto', __METHOD__); + $this->errors = $errors; + } + public function getErrors() { + return $this->errors; + } + public function setErrorResult(ErrorProto $errorResult) { + $this->errorResult = $errorResult; + } + public function getErrorResult() { + return $this->errorResult; + } +} + +class ProjectList extends apiModel { + public $nextPageToken; + public $totalItems; + public $kind; + public $etag; + protected $__projectsType = 'ProjectListProjects'; + protected $__projectsDataType = 'array'; + public $projects; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setProjects(/* array(ProjectListProjects) */ $projects) { + $this->assertIsArray($projects, 'ProjectListProjects', __METHOD__); + $this->projects = $projects; + } + public function getProjects() { + return $this->projects; + } +} + +class ProjectListProjects extends apiModel { + public $friendlyName; + public $kind; + public $id; + protected $__projectReferenceType = 'ProjectReference'; + protected $__projectReferenceDataType = ''; + public $projectReference; + public function setFriendlyName($friendlyName) { + $this->friendlyName = $friendlyName; + } + public function getFriendlyName() { + return $this->friendlyName; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setProjectReference(ProjectReference $projectReference) { + $this->projectReference = $projectReference; + } + public function getProjectReference() { + return $this->projectReference; + } +} + +class ProjectReference extends apiModel { + public $projectId; + public function setProjectId($projectId) { + $this->projectId = $projectId; + } + public function getProjectId() { + return $this->projectId; + } +} + +class QueryRequest extends apiModel { + public $timeoutMs; + public $query; + public $kind; + public $maxResults; + protected $__defaultDatasetType = 'DatasetReference'; + protected $__defaultDatasetDataType = ''; + public $defaultDataset; + public function setTimeoutMs($timeoutMs) { + $this->timeoutMs = $timeoutMs; + } + public function getTimeoutMs() { + return $this->timeoutMs; + } + public function setQuery($query) { + $this->query = $query; + } + public function getQuery() { + return $this->query; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setMaxResults($maxResults) { + $this->maxResults = $maxResults; + } + public function getMaxResults() { + return $this->maxResults; + } + public function setDefaultDataset(DatasetReference $defaultDataset) { + $this->defaultDataset = $defaultDataset; + } + public function getDefaultDataset() { + return $this->defaultDataset; + } +} + +class QueryResponse extends apiModel { + public $kind; + protected $__rowsType = 'TableRow'; + protected $__rowsDataType = 'array'; + public $rows; + protected $__jobReferenceType = 'JobReference'; + protected $__jobReferenceDataType = ''; + public $jobReference; + public $jobComplete; + public $totalRows; + protected $__schemaType = 'TableSchema'; + protected $__schemaDataType = ''; + public $schema; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setRows(/* array(TableRow) */ $rows) { + $this->assertIsArray($rows, 'TableRow', __METHOD__); + $this->rows = $rows; + } + public function getRows() { + return $this->rows; + } + public function setJobReference(JobReference $jobReference) { + $this->jobReference = $jobReference; + } + public function getJobReference() { + return $this->jobReference; + } + public function setJobComplete($jobComplete) { + $this->jobComplete = $jobComplete; + } + public function getJobComplete() { + return $this->jobComplete; + } + public function setTotalRows($totalRows) { + $this->totalRows = $totalRows; + } + public function getTotalRows() { + return $this->totalRows; + } + public function setSchema(TableSchema $schema) { + $this->schema = $schema; + } + public function getSchema() { + return $this->schema; + } +} + +class Table extends apiModel { + public $kind; + public $description; + public $creationTime; + protected $__tableReferenceType = 'TableReference'; + protected $__tableReferenceDataType = ''; + public $tableReference; + public $etag; + public $friendlyName; + public $lastModifiedTime; + public $id; + public $selfLink; + protected $__schemaType = 'TableSchema'; + protected $__schemaDataType = ''; + public $schema; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setCreationTime($creationTime) { + $this->creationTime = $creationTime; + } + public function getCreationTime() { + return $this->creationTime; + } + public function setTableReference(TableReference $tableReference) { + $this->tableReference = $tableReference; + } + public function getTableReference() { + return $this->tableReference; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setFriendlyName($friendlyName) { + $this->friendlyName = $friendlyName; + } + public function getFriendlyName() { + return $this->friendlyName; + } + public function setLastModifiedTime($lastModifiedTime) { + $this->lastModifiedTime = $lastModifiedTime; + } + public function getLastModifiedTime() { + return $this->lastModifiedTime; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setSchema(TableSchema $schema) { + $this->schema = $schema; + } + public function getSchema() { + return $this->schema; + } +} + +class TableDataList extends apiModel { + protected $__rowsType = 'TableRow'; + protected $__rowsDataType = 'array'; + public $rows; + public $kind; + public $etag; + public $totalRows; + public function setRows(/* array(TableRow) */ $rows) { + $this->assertIsArray($rows, 'TableRow', __METHOD__); + $this->rows = $rows; + } + public function getRows() { + return $this->rows; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setTotalRows($totalRows) { + $this->totalRows = $totalRows; + } + public function getTotalRows() { + return $this->totalRows; + } +} + +class TableFieldSchema extends apiModel { + protected $__fieldsType = 'TableFieldSchema'; + protected $__fieldsDataType = 'array'; + public $fields; + public $type; + public $mode; + public $name; + public function setFields(/* array(TableFieldSchema) */ $fields) { + $this->assertIsArray($fields, 'TableFieldSchema', __METHOD__); + $this->fields = $fields; + } + public function getFields() { + return $this->fields; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setMode($mode) { + $this->mode = $mode; + } + public function getMode() { + return $this->mode; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class TableList extends apiModel { + public $nextPageToken; + protected $__tablesType = 'TableListTables'; + protected $__tablesDataType = 'array'; + public $tables; + public $kind; + public $etag; + public $totalItems; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setTables(/* array(TableListTables) */ $tables) { + $this->assertIsArray($tables, 'TableListTables', __METHOD__); + $this->tables = $tables; + } + public function getTables() { + return $this->tables; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } +} + +class TableListTables extends apiModel { + public $friendlyName; + public $kind; + public $id; + protected $__tableReferenceType = 'TableReference'; + protected $__tableReferenceDataType = ''; + public $tableReference; + public function setFriendlyName($friendlyName) { + $this->friendlyName = $friendlyName; + } + public function getFriendlyName() { + return $this->friendlyName; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setTableReference(TableReference $tableReference) { + $this->tableReference = $tableReference; + } + public function getTableReference() { + return $this->tableReference; + } +} + +class TableReference extends apiModel { + public $projectId; + public $tableId; + public $datasetId; + public function setProjectId($projectId) { + $this->projectId = $projectId; + } + public function getProjectId() { + return $this->projectId; + } + public function setTableId($tableId) { + $this->tableId = $tableId; + } + public function getTableId() { + return $this->tableId; + } + public function setDatasetId($datasetId) { + $this->datasetId = $datasetId; + } + public function getDatasetId() { + return $this->datasetId; + } +} + +class TableRow extends apiModel { + protected $__fType = 'TableRowF'; + protected $__fDataType = 'array'; + public $f; + public function setF(/* array(TableRowF) */ $f) { + $this->assertIsArray($f, 'TableRowF', __METHOD__); + $this->f = $f; + } + public function getF() { + return $this->f; + } +} + +class TableRowF extends apiModel { + public $v; + public function setV($v) { + $this->v = $v; + } + public function getV() { + return $this->v; + } +} + +class TableSchema extends apiModel { + protected $__fieldsType = 'TableFieldSchema'; + protected $__fieldsDataType = 'array'; + public $fields; + public function setFields(/* array(TableFieldSchema) */ $fields) { + $this->assertIsArray($fields, 'TableFieldSchema', __METHOD__); + $this->fields = $fields; + } + public function getFields() { + return $this->fields; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiBloggerService.php b/inc/vendors/social-login/Google/contrib/apiBloggerService.php new file mode 100755 index 00000000..cd6ae0c1 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiBloggerService.php @@ -0,0 +1,1074 @@ + + * $bloggerService = new apiBloggerService(...); + * $blogs = $bloggerService->blogs; + * + */ + class BlogsServiceResource extends apiServiceResource { + + + /** + * Gets one blog by id. (blogs.get) + * @param string $blogId The ID of the blog to get. + * @return Blog + */ + public function get($blogId, $optParams = array()) { + $params = array('blogId' => $blogId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Blog($data); + } else { + return $data; + } + } + } + + /** + * The "posts" collection of methods. + * Typical usage is: + * + * $bloggerService = new apiBloggerService(...); + * $posts = $bloggerService->posts; + * + */ + class PostsServiceResource extends apiServiceResource { + + + /** + * Retrieves a list of posts, possibly filtered. (posts.list) + * @param string $blogId ID of the blog to fetch posts from. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken Continuation token if the request is paged. + * @opt_param bool fetchBodies Whether the body content of posts is included. + * @opt_param string maxResults Maximum number of posts to fetch. + * @opt_param string startDate Earliest post date to fetch. + * @return PostList + */ + public function listPosts($blogId, $optParams = array()) { + $params = array('blogId' => $blogId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new PostList($data); + } else { + return $data; + } + } + /** + * Get a post by id. (posts.get) + * @param string $blogId ID of the blog to fetch the post from. + * @param string $postId The ID of the post + * @return Post + */ + public function get($blogId, $postId, $optParams = array()) { + $params = array('blogId' => $blogId, 'postId' => $postId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Post($data); + } else { + return $data; + } + } + } + + /** + * The "pages" collection of methods. + * Typical usage is: + * + * $bloggerService = new apiBloggerService(...); + * $pages = $bloggerService->pages; + * + */ + class PagesServiceResource extends apiServiceResource { + + + /** + * Retrieves pages for a blog, possibly filtered. (pages.list) + * @param string $blogId ID of the blog to fetch pages from. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool fetchBodies Whether to retrieve the Page bodies. + * @return PageList + */ + public function listPages($blogId, $optParams = array()) { + $params = array('blogId' => $blogId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new PageList($data); + } else { + return $data; + } + } + /** + * Gets one blog page by id. (pages.get) + * @param string $blogId ID of the blog containing the page. + * @param string $pageId The ID of the page to get. + * @return Page + */ + public function get($blogId, $pageId, $optParams = array()) { + $params = array('blogId' => $blogId, 'pageId' => $pageId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Page($data); + } else { + return $data; + } + } + } + + /** + * The "comments" collection of methods. + * Typical usage is: + * + * $bloggerService = new apiBloggerService(...); + * $comments = $bloggerService->comments; + * + */ + class CommentsServiceResource extends apiServiceResource { + + + /** + * Retrieves the comments for a blog, possibly filtered. (comments.list) + * @param string $blogId ID of the blog to fetch comments from. + * @param string $postId ID of the post to fetch posts from. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string startDate Earliest date of comment to fetch. + * @opt_param string maxResults Maximum number of comments to include in the result. + * @opt_param string pageToken Continuation token if request is paged. + * @opt_param bool fetchBodies Whether the body content of the comments is included. + * @return CommentList + */ + public function listComments($blogId, $postId, $optParams = array()) { + $params = array('blogId' => $blogId, 'postId' => $postId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommentList($data); + } else { + return $data; + } + } + /** + * Gets one comment by id. (comments.get) + * @param string $blogId ID of the blog to containing the comment. + * @param string $postId ID of the post to fetch posts from. + * @param string $commentId The ID of the comment to get. + * @return Comment + */ + public function get($blogId, $postId, $commentId, $optParams = array()) { + $params = array('blogId' => $blogId, 'postId' => $postId, 'commentId' => $commentId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Comment($data); + } else { + return $data; + } + } + } + + /** + * The "users" collection of methods. + * Typical usage is: + * + * $bloggerService = new apiBloggerService(...); + * $users = $bloggerService->users; + * + */ + class UsersServiceResource extends apiServiceResource { + + + /** + * Gets one user by id. (users.get) + * @param string $userId The ID of the user to get. + * @return User + */ + public function get($userId, $optParams = array()) { + $params = array('userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new User($data); + } else { + return $data; + } + } + } + + + /** + * The "blogs" collection of methods. + * Typical usage is: + * + * $bloggerService = new apiBloggerService(...); + * $blogs = $bloggerService->blogs; + * + */ + class UsersBlogsServiceResource extends apiServiceResource { + + + /** + * Retrieves a list of blogs, possibly filtered. (blogs.list) + * @param string $userId ID of the user whose blogs are to be fetched. + * @return BlogList + */ + public function listUsersBlogs($userId, $optParams = array()) { + $params = array('userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new BlogList($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Blogger (v2). + *

            + * API for access to the data within Blogger. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiBloggerService extends apiService { + public $blogs; + public $posts; + public $pages; + public $comments; + public $users; + public $users_blogs; + /** + * Constructs the internal representation of the Blogger service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/blogger/v2/'; + $this->version = 'v2'; + $this->serviceName = 'blogger'; + + $apiClient->addService($this->serviceName, $this->version); + $this->blogs = new BlogsServiceResource($this, $this->serviceName, 'blogs', json_decode('{"methods": {"get": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"blogId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.blogs.get", "httpMethod": "GET", "path": "blogs/{blogId}", "response": {"$ref": "Blog"}}}}', true)); + $this->posts = new PostsServiceResource($this, $this->serviceName, 'posts', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "fetchBodies": {"type": "boolean", "location": "query"}, "blogId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}, "startDate": {"type": "string", "location": "query"}}, "id": "blogger.posts.list", "httpMethod": "GET", "path": "blogs/{blogId}/posts", "response": {"$ref": "PostList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"postId": {"required": true, "type": "string", "location": "path"}, "blogId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.posts.get", "httpMethod": "GET", "path": "blogs/{blogId}/posts/{postId}", "response": {"$ref": "Post"}}}}', true)); + $this->pages = new PagesServiceResource($this, $this->serviceName, 'pages', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"fetchBodies": {"type": "boolean", "location": "query"}, "blogId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.pages.list", "httpMethod": "GET", "path": "blogs/{blogId}/pages", "response": {"$ref": "PageList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"pageId": {"required": true, "type": "string", "location": "path"}, "blogId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.pages.get", "httpMethod": "GET", "path": "blogs/{blogId}/pages/{pageId}", "response": {"$ref": "Page"}}}}', true)); + $this->comments = new CommentsServiceResource($this, $this->serviceName, 'comments', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"startDate": {"type": "string", "location": "query"}, "postId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "fetchBodies": {"type": "boolean", "location": "query"}, "blogId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.comments.list", "httpMethod": "GET", "path": "blogs/{blogId}/posts/{postId}/comments", "response": {"$ref": "CommentList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"commentId": {"required": true, "type": "string", "location": "path"}, "postId": {"required": true, "type": "string", "location": "path"}, "blogId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.comments.get", "httpMethod": "GET", "path": "blogs/{blogId}/posts/{postId}/comments/{commentId}", "response": {"$ref": "Comment"}}}}', true)); + $this->users = new UsersServiceResource($this, $this->serviceName, 'users', json_decode('{"methods": {"get": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"userId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.users.get", "httpMethod": "GET", "path": "users/{userId}", "response": {"$ref": "User"}}}}', true)); + $this->users_blogs = new UsersBlogsServiceResource($this, $this->serviceName, 'blogs', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/blogger"], "parameters": {"userId": {"required": true, "type": "string", "location": "path"}}, "id": "blogger.users.blogs.list", "httpMethod": "GET", "path": "users/{userId}/blogs", "response": {"$ref": "BlogList"}}}}', true)); + } +} + +class Blog extends apiModel { + public $kind; + public $description; + protected $__localeType = 'BlogLocale'; + protected $__localeDataType = ''; + public $locale; + protected $__postsType = 'BlogPosts'; + protected $__postsDataType = ''; + public $posts; + public $updated; + public $id; + public $url; + public $published; + protected $__pagesType = 'BlogPages'; + protected $__pagesDataType = ''; + public $pages; + public $selfLink; + public $name; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setLocale(BlogLocale $locale) { + $this->locale = $locale; + } + public function getLocale() { + return $this->locale; + } + public function setPosts(BlogPosts $posts) { + $this->posts = $posts; + } + public function getPosts() { + return $this->posts; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } + public function setPages(BlogPages $pages) { + $this->pages = $pages; + } + public function getPages() { + return $this->pages; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class BlogList extends apiModel { + protected $__itemsType = 'Blog'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Blog) */ $items) { + $this->assertIsArray($items, 'Blog', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class BlogLocale extends apiModel { + public $country; + public $variant; + public $language; + public function setCountry($country) { + $this->country = $country; + } + public function getCountry() { + return $this->country; + } + public function setVariant($variant) { + $this->variant = $variant; + } + public function getVariant() { + return $this->variant; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } +} + +class BlogPages extends apiModel { + public $totalItems; + public $selfLink; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class BlogPosts extends apiModel { + public $totalItems; + public $selfLink; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class Comment extends apiModel { + public $content; + public $kind; + protected $__authorType = 'CommentAuthor'; + protected $__authorDataType = ''; + public $author; + public $updated; + protected $__blogType = 'CommentBlog'; + protected $__blogDataType = ''; + public $blog; + public $published; + protected $__postType = 'CommentPost'; + protected $__postDataType = ''; + public $post; + public $id; + public $selfLink; + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAuthor(CommentAuthor $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setBlog(CommentBlog $blog) { + $this->blog = $blog; + } + public function getBlog() { + return $this->blog; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } + public function setPost(CommentPost $post) { + $this->post = $post; + } + public function getPost() { + return $this->post; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class CommentAuthor extends apiModel { + public $url; + protected $__imageType = 'CommentAuthorImage'; + protected $__imageDataType = ''; + public $image; + public $displayName; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(CommentAuthorImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CommentAuthorImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class CommentBlog extends apiModel { + public $id; + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CommentList extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Comment'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $prevPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Comment) */ $items) { + $this->assertIsArray($items, 'Comment', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setPrevPageToken($prevPageToken) { + $this->prevPageToken = $prevPageToken; + } + public function getPrevPageToken() { + return $this->prevPageToken; + } +} + +class CommentPost extends apiModel { + public $id; + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class Page extends apiModel { + public $content; + public $kind; + protected $__authorType = 'PageAuthor'; + protected $__authorDataType = ''; + public $author; + public $url; + public $title; + public $updated; + protected $__blogType = 'PageBlog'; + protected $__blogDataType = ''; + public $blog; + public $published; + public $id; + public $selfLink; + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAuthor(PageAuthor $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setBlog(PageBlog $blog) { + $this->blog = $blog; + } + public function getBlog() { + return $this->blog; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class PageAuthor extends apiModel { + public $url; + protected $__imageType = 'PageAuthorImage'; + protected $__imageDataType = ''; + public $image; + public $displayName; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(PageAuthorImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class PageAuthorImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class PageBlog extends apiModel { + public $id; + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class PageList extends apiModel { + protected $__itemsType = 'Page'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Page) */ $items) { + $this->assertIsArray($items, 'Page', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class Post extends apiModel { + public $content; + public $kind; + protected $__authorType = 'PostAuthor'; + protected $__authorDataType = ''; + public $author; + protected $__repliesType = 'PostReplies'; + protected $__repliesDataType = ''; + public $replies; + public $labels; + public $updated; + protected $__blogType = 'PostBlog'; + protected $__blogDataType = ''; + public $blog; + public $url; + public $published; + public $title; + public $id; + public $selfLink; + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAuthor(PostAuthor $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setReplies(PostReplies $replies) { + $this->replies = $replies; + } + public function getReplies() { + return $this->replies; + } + public function setLabels(/* array(string) */ $labels) { + $this->assertIsArray($labels, 'string', __METHOD__); + $this->labels = $labels; + } + public function getLabels() { + return $this->labels; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setBlog(PostBlog $blog) { + $this->blog = $blog; + } + public function getBlog() { + return $this->blog; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class PostAuthor extends apiModel { + public $url; + protected $__imageType = 'PostAuthorImage'; + protected $__imageDataType = ''; + public $image; + public $displayName; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(PostAuthorImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class PostAuthorImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class PostBlog extends apiModel { + public $id; + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class PostList extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Post'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $prevPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Post) */ $items) { + $this->assertIsArray($items, 'Post', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setPrevPageToken($prevPageToken) { + $this->prevPageToken = $prevPageToken; + } + public function getPrevPageToken() { + return $this->prevPageToken; + } +} + +class PostReplies extends apiModel { + public $totalItems; + public $selfLink; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class User extends apiModel { + public $about; + public $displayName; + public $created; + protected $__localeType = 'UserLocale'; + protected $__localeDataType = ''; + public $locale; + protected $__blogsType = 'UserBlogs'; + protected $__blogsDataType = ''; + public $blogs; + public $kind; + public $url; + public $id; + public $selfLink; + public function setAbout($about) { + $this->about = $about; + } + public function getAbout() { + return $this->about; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setLocale(UserLocale $locale) { + $this->locale = $locale; + } + public function getLocale() { + return $this->locale; + } + public function setBlogs(UserBlogs $blogs) { + $this->blogs = $blogs; + } + public function getBlogs() { + return $this->blogs; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class UserBlogs extends apiModel { + public $selfLink; + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class UserLocale extends apiModel { + public $country; + public $variant; + public $language; + public function setCountry($country) { + $this->country = $country; + } + public function getCountry() { + return $this->country; + } + public function setVariant($variant) { + $this->variant = $variant; + } + public function getVariant() { + return $this->variant; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiBooksService.php b/inc/vendors/social-login/Google/contrib/apiBooksService.php new file mode 100755 index 00000000..a190fa98 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiBooksService.php @@ -0,0 +1,1820 @@ + + * $booksService = new apiBooksService(...); + * $bookshelves = $booksService->bookshelves; + * + */ + class BookshelvesServiceResource extends apiServiceResource { + + + /** + * Retrieves a list of public bookshelves for the specified user. (bookshelves.list) + * @param string $userId Id of user for whom to retrieve bookshelves. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return Bookshelves + */ + public function listBookshelves($userId, $optParams = array()) { + $params = array('userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Bookshelves($data); + } else { + return $data; + } + } + /** + * Retrieves a specific bookshelf for the specified user. (bookshelves.get) + * @param string $userId Id of user for whom to retrieve bookshelves. + * @param string $shelf Id of bookshelf to retrieve. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return Bookshelf + */ + public function get($userId, $shelf, $optParams = array()) { + $params = array('userId' => $userId, 'shelf' => $shelf); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Bookshelf($data); + } else { + return $data; + } + } + } + + + /** + * The "volumes" collection of methods. + * Typical usage is: + * + * $booksService = new apiBooksService(...); + * $volumes = $booksService->volumes; + * + */ + class BookshelvesVolumesServiceResource extends apiServiceResource { + + + /** + * Retrieves volumes in a specific bookshelf for the specified user. (volumes.list) + * @param string $userId Id of user for whom to retrieve bookshelf volumes. + * @param string $shelf Id of bookshelf to retrieve volumes. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param bool showPreorders Set to true to show pre-ordered books. Defaults to false. + * @opt_param string maxResults Maximum number of results to return + * @opt_param string source String to identify the originator of this request. + * @opt_param string startIndex Index of the first element to return (starts at 0) + * @return Volumes + */ + public function listBookshelvesVolumes($userId, $shelf, $optParams = array()) { + $params = array('userId' => $userId, 'shelf' => $shelf); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Volumes($data); + } else { + return $data; + } + } + } + + /** + * The "myconfig" collection of methods. + * Typical usage is: + * + * $booksService = new apiBooksService(...); + * $myconfig = $booksService->myconfig; + * + */ + class MyconfigServiceResource extends apiServiceResource { + + + /** + * Release downloaded content access restriction. (myconfig.releaseDownloadAccess) + * @param string $volumeIds The volume(s) to release restrictions for. + * @param string $cpksver The device/version identifier from which to release the restriction. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string locale ISO-639-1, ISO-3166-1 codes for message localization, i.e. en_US. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return DownloadAccesses + */ + public function releaseDownloadAccess($volumeIds, $cpksver, $optParams = array()) { + $params = array('volumeIds' => $volumeIds, 'cpksver' => $cpksver); + $params = array_merge($params, $optParams); + $data = $this->__call('releaseDownloadAccess', array($params)); + if ($this->useObjects()) { + return new DownloadAccesses($data); + } else { + return $data; + } + } + /** + * Request concurrent and download access restrictions. (myconfig.requestAccess) + * @param string $source String to identify the originator of this request. + * @param string $volumeId The volume to request concurrent/download restrictions for. + * @param string $nonce The client nonce value. + * @param string $cpksver The device/version identifier from which to request the restrictions. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string locale ISO-639-1, ISO-3166-1 codes for message localization, i.e. en_US. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @return RequestAccess + */ + public function requestAccess($source, $volumeId, $nonce, $cpksver, $optParams = array()) { + $params = array('source' => $source, 'volumeId' => $volumeId, 'nonce' => $nonce, 'cpksver' => $cpksver); + $params = array_merge($params, $optParams); + $data = $this->__call('requestAccess', array($params)); + if ($this->useObjects()) { + return new RequestAccess($data); + } else { + return $data; + } + } + /** + * Request downloaded content access for specified volumes on the My eBooks shelf. + * (myconfig.syncVolumeLicenses) + * @param string $source String to identify the originator of this request. + * @param string $nonce The client nonce value. + * @param string $cpksver The device/version identifier from which to release the restriction. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string locale ISO-639-1, ISO-3166-1 codes for message localization, i.e. en_US. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string volumeIds The volume(s) to request download restrictions for. + * @return Volumes + */ + public function syncVolumeLicenses($source, $nonce, $cpksver, $optParams = array()) { + $params = array('source' => $source, 'nonce' => $nonce, 'cpksver' => $cpksver); + $params = array_merge($params, $optParams); + $data = $this->__call('syncVolumeLicenses', array($params)); + if ($this->useObjects()) { + return new Volumes($data); + } else { + return $data; + } + } + } + + /** + * The "volumes" collection of methods. + * Typical usage is: + * + * $booksService = new apiBooksService(...); + * $volumes = $booksService->volumes; + * + */ + class VolumesServiceResource extends apiServiceResource { + + + /** + * Performs a book search. (volumes.list) + * @param string $q Full-text search query string. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string orderBy Sort search results. + * @opt_param string projection Restrict information returned to a set of selected fields. + * @opt_param string libraryRestrict Restrict search to this user's library. + * @opt_param string langRestrict Restrict results to books with this language code. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string printType Restrict to books or magazines. + * @opt_param string maxResults Maximum number of results to return. + * @opt_param string filter Filter search results. + * @opt_param string source String to identify the originator of this request. + * @opt_param string startIndex Index of the first result to return (starts at 0) + * @opt_param string download Restrict to volumes by download availability. + * @opt_param string partner Identifier of partner for whom to restrict and brand results. + * @opt_param bool showPreorders Set to true to show books available for preorder. Defaults to false. + * @return Volumes + */ + public function listVolumes($q, $optParams = array()) { + $params = array('q' => $q); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Volumes($data); + } else { + return $data; + } + } + /** + * Gets volume information for a single volume. (volumes.get) + * @param string $volumeId Id of volume to retrieve. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string source String to identify the originator of this request. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string projection Restrict information returned to a set of selected fields. + * @opt_param string partner Identifier of partner for whom to brand results. + * @return Volume + */ + public function get($volumeId, $optParams = array()) { + $params = array('volumeId' => $volumeId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Volume($data); + } else { + return $data; + } + } + } + + /** + * The "mylibrary" collection of methods. + * Typical usage is: + * + * $booksService = new apiBooksService(...); + * $mylibrary = $booksService->mylibrary; + * + */ + class MylibraryServiceResource extends apiServiceResource { + + + } + + + /** + * The "bookshelves" collection of methods. + * Typical usage is: + * + * $booksService = new apiBooksService(...); + * $bookshelves = $booksService->bookshelves; + * + */ + class MylibraryBookshelvesServiceResource extends apiServiceResource { + + + /** + * Clears all volumes from a bookshelf. (bookshelves.clearVolumes) + * @param string $shelf Id of bookshelf from which to remove a volume. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + */ + public function clearVolumes($shelf, $optParams = array()) { + $params = array('shelf' => $shelf); + $params = array_merge($params, $optParams); + $data = $this->__call('clearVolumes', array($params)); + return $data; + } + /** + * Removes a volume from a bookshelf. (bookshelves.removeVolume) + * @param string $shelf Id of bookshelf from which to remove a volume. + * @param string $volumeId Id of volume to remove. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + */ + public function removeVolume($shelf, $volumeId, $optParams = array()) { + $params = array('shelf' => $shelf, 'volumeId' => $volumeId); + $params = array_merge($params, $optParams); + $data = $this->__call('removeVolume', array($params)); + return $data; + } + /** + * Retrieves a list of bookshelves belonging to the authenticated user. (bookshelves.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return Bookshelves + */ + public function listMylibraryBookshelves($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Bookshelves($data); + } else { + return $data; + } + } + /** + * Adds a volume to a bookshelf. (bookshelves.addVolume) + * @param string $shelf Id of bookshelf to which to add a volume. + * @param string $volumeId Id of volume to add. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + */ + public function addVolume($shelf, $volumeId, $optParams = array()) { + $params = array('shelf' => $shelf, 'volumeId' => $volumeId); + $params = array_merge($params, $optParams); + $data = $this->__call('addVolume', array($params)); + return $data; + } + /** + * Retrieves a specific bookshelf belonging to the authenticated user. (bookshelves.get) + * @param string $shelf Id of bookshelf to retrieve. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return Bookshelf + */ + public function get($shelf, $optParams = array()) { + $params = array('shelf' => $shelf); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Bookshelf($data); + } else { + return $data; + } + } + } + + + /** + * The "volumes" collection of methods. + * Typical usage is: + * + * $booksService = new apiBooksService(...); + * $volumes = $booksService->volumes; + * + */ + class MylibraryBookshelvesVolumesServiceResource extends apiServiceResource { + + + /** + * Gets volume information for volumes on a bookshelf. (volumes.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string shelf The bookshelf id or name retrieve volumes for. + * @opt_param string projection Restrict information returned to a set of selected fields. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param bool showPreorders Set to true to show pre-ordered books. Defaults to false. + * @opt_param string maxResults Maximum number of results to return + * @opt_param string q Full-text search query string in this bookshelf. + * @opt_param string source String to identify the originator of this request. + * @opt_param string startIndex Index of the first element to return (starts at 0) + * @return Volumes + */ + public function listMylibraryBookshelvesVolumes($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Volumes($data); + } else { + return $data; + } + } + } + /** + * The "annotations" collection of methods. + * Typical usage is: + * + * $booksService = new apiBooksService(...); + * $annotations = $booksService->annotations; + * + */ + class MylibraryAnnotationsServiceResource extends apiServiceResource { + + + /** + * Inserts a new annotation. (annotations.insert) + * @param Annotation $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return Annotation + */ + public function insert(Annotation $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Annotation($data); + } else { + return $data; + } + } + /** + * Gets an annotation by its id. (annotations.get) + * @param string $annotationId The annotation identifier for the annotation to retrieve. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return Annotation + */ + public function get($annotationId, $optParams = array()) { + $params = array('annotationId' => $annotationId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Annotation($data); + } else { + return $data; + } + } + /** + * Retrieves a list of annotations, possibly filtered. (annotations.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string source String to identify the originator of this request. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string volumeId The volume to restrict annotations to. + * @opt_param string maxResults Maximum number of results to return + * @opt_param string pageToken The value of the nextToken from the previous page. + * @opt_param string pageIds The page id(s) for the volume that is being queried. + * @opt_param string contentVersion The content version for the requested volume. + * @opt_param string layerId The layer id to limit annotation by. + * @return Annotations + */ + public function listMylibraryAnnotations($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Annotations($data); + } else { + return $data; + } + } + /** + * Updates an existing annotation. (annotations.update) + * @param string $annotationId The annotation identifier for the annotation to update. + * @param Annotation $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + * @return Annotation + */ + public function update($annotationId, Annotation $postBody, $optParams = array()) { + $params = array('annotationId' => $annotationId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Annotation($data); + } else { + return $data; + } + } + /** + * Deletes an annotation. (annotations.delete) + * @param string $annotationId The annotation identifier for the annotation to delete. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string country ISO-3166-1 code to override the IP-based location. + * @opt_param string source String to identify the originator of this request. + */ + public function delete($annotationId, $optParams = array()) { + $params = array('annotationId' => $annotationId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + + +/** + * Service definition for Books (v1). + *

            + * Lets you search for books and manage your Google Books library. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiBooksService extends apiService { + public $bookshelves; + public $bookshelves_volumes; + public $myconfig; + public $volumes; + public $mylibrary; + public $mylibrary_bookshelves; + public $mylibrary_annotations; + /** + * Constructs the internal representation of the Books service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/books/v1/'; + $this->version = 'v1'; + $this->serviceName = 'books'; + + $apiClient->addService($this->serviceName, $this->version); + $this->bookshelves = new BookshelvesServiceResource($this, $this->serviceName, 'bookshelves', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "userId": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "id": "books.bookshelves.list", "httpMethod": "GET", "path": "users/{userId}/bookshelves", "response": {"$ref": "Bookshelves"}}, "get": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "userId": {"required": true, "type": "string", "location": "path"}, "shelf": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "id": "books.bookshelves.get", "httpMethod": "GET", "path": "users/{userId}/bookshelves/{shelf}", "response": {"$ref": "Bookshelf"}}}}', true)); + $this->bookshelves_volumes = new BookshelvesVolumesServiceResource($this, $this->serviceName, 'volumes', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "showPreorders": {"type": "boolean", "location": "query"}, "maxResults": {"format": "uint32", "minimum": "0", "type": "integer", "location": "query"}, "source": {"type": "string", "location": "query"}, "startIndex": {"format": "uint32", "minimum": "0", "type": "integer", "location": "query"}, "shelf": {"required": true, "type": "string", "location": "path"}, "userId": {"required": true, "type": "string", "location": "path"}}, "id": "books.bookshelves.volumes.list", "httpMethod": "GET", "path": "users/{userId}/bookshelves/{shelf}/volumes", "response": {"$ref": "Volumes"}}}}', true)); + $this->myconfig = new MyconfigServiceResource($this, $this->serviceName, 'myconfig', json_decode('{"methods": {"releaseDownloadAccess": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"locale": {"type": "string", "location": "query"}, "country": {"type": "string", "location": "query"}, "source": {"type": "string", "location": "query"}, "cpksver": {"required": true, "type": "string", "location": "query"}, "volumeIds": {"repeated": true, "required": true, "type": "string", "location": "query"}}, "id": "books.myconfig.releaseDownloadAccess", "httpMethod": "POST", "path": "myconfig/releaseDownloadAccess", "response": {"$ref": "DownloadAccesses"}}, "requestAccess": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"nonce": {"required": true, "type": "string", "location": "query"}, "locale": {"type": "string", "location": "query"}, "country": {"type": "string", "location": "query"}, "cpksver": {"required": true, "type": "string", "location": "query"}, "volumeId": {"required": true, "type": "string", "location": "query"}, "source": {"required": true, "type": "string", "location": "query"}}, "id": "books.myconfig.requestAccess", "httpMethod": "POST", "path": "myconfig/requestAccess", "response": {"$ref": "RequestAccess"}}, "syncVolumeLicenses": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"nonce": {"required": true, "type": "string", "location": "query"}, "locale": {"type": "string", "location": "query"}, "country": {"type": "string", "location": "query"}, "cpksver": {"required": true, "type": "string", "location": "query"}, "source": {"required": true, "type": "string", "location": "query"}, "volumeIds": {"repeated": true, "type": "string", "location": "query"}}, "id": "books.myconfig.syncVolumeLicenses", "httpMethod": "POST", "path": "myconfig/syncVolumeLicenses", "response": {"$ref": "Volumes"}}}}', true)); + $this->volumes = new VolumesServiceResource($this, $this->serviceName, 'volumes', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"orderBy": {"enum": ["newest", "relevance"], "type": "string", "location": "query"}, "filter": {"enum": ["ebooks", "free-ebooks", "full", "paid-ebooks", "partial"], "type": "string", "location": "query"}, "projection": {"enum": ["full", "lite"], "type": "string", "location": "query"}, "libraryRestrict": {"enum": ["my-library", "no-restrict"], "type": "string", "location": "query"}, "langRestrict": {"type": "string", "location": "query"}, "country": {"type": "string", "location": "query"}, "printType": {"enum": ["all", "books", "magazines"], "type": "string", "location": "query"}, "maxResults": {"format": "uint32", "maximum": "40", "minimum": "0", "location": "query", "type": "integer"}, "q": {"required": true, "type": "string", "location": "query"}, "source": {"type": "string", "location": "query"}, "startIndex": {"format": "uint32", "minimum": "0", "type": "integer", "location": "query"}, "download": {"enum": ["epub"], "type": "string", "location": "query"}, "partner": {"type": "string", "location": "query"}, "showPreorders": {"type": "boolean", "location": "query"}}, "id": "books.volumes.list", "httpMethod": "GET", "path": "volumes", "response": {"$ref": "Volumes"}}, "get": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"partner": {"type": "string", "location": "query"}, "source": {"type": "string", "location": "query"}, "projection": {"enum": ["full", "lite"], "type": "string", "location": "query"}, "volumeId": {"required": true, "type": "string", "location": "path"}, "country": {"type": "string", "location": "query"}}, "id": "books.volumes.get", "httpMethod": "GET", "path": "volumes/{volumeId}", "response": {"$ref": "Volume"}}}}', true)); + $this->mylibrary = new MylibraryServiceResource($this, $this->serviceName, 'mylibrary', json_decode('{}', true)); + $this->mylibrary_bookshelves = new MylibraryBookshelvesServiceResource($this, $this->serviceName, 'bookshelves', json_decode('{"methods": {"clearVolumes": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "shelf": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "httpMethod": "POST", "path": "mylibrary/bookshelves/{shelf}/clearVolumes", "id": "books.mylibrary.bookshelves.clearVolumes"}, "removeVolume": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "volumeId": {"required": true, "type": "string", "location": "query"}, "shelf": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "httpMethod": "POST", "path": "mylibrary/bookshelves/{shelf}/removeVolume", "id": "books.mylibrary.bookshelves.removeVolume"}, "list": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "source": {"type": "string", "location": "query"}}, "response": {"$ref": "Bookshelves"}, "httpMethod": "GET", "path": "mylibrary/bookshelves", "id": "books.mylibrary.bookshelves.list"}, "addVolume": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "volumeId": {"required": true, "type": "string", "location": "query"}, "shelf": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "httpMethod": "POST", "path": "mylibrary/bookshelves/{shelf}/addVolume", "id": "books.mylibrary.bookshelves.addVolume"}, "get": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "shelf": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "id": "books.mylibrary.bookshelves.get", "httpMethod": "GET", "path": "mylibrary/bookshelves/{shelf}", "response": {"$ref": "Bookshelf"}}}}', true)); + $this->mylibrary_annotations = new MylibraryAnnotationsServiceResource($this, $this->serviceName, 'annotations', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "source": {"type": "string", "location": "query"}}, "request": {"$ref": "Annotation"}, "id": "books.mylibrary.annotations.insert", "httpMethod": "POST", "path": "mylibrary/annotations", "response": {"$ref": "Annotation"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "annotationId": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "httpMethod": "DELETE", "path": "mylibrary/annotations/{annotationId}", "id": "books.mylibrary.annotations.delete"}, "list": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "country": {"type": "string", "location": "query"}, "volumeId": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "maximum": "40", "minimum": "0", "location": "query", "type": "integer"}, "source": {"type": "string", "location": "query"}, "pageIds": {"repeated": true, "type": "string", "location": "query"}, "contentVersion": {"type": "string", "location": "query"}, "layerId": {"type": "string", "location": "query"}}, "response": {"$ref": "Annotations"}, "httpMethod": "GET", "path": "mylibrary/annotations", "id": "books.mylibrary.annotations.list"}, "update": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "annotationId": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "request": {"$ref": "Annotation"}, "id": "books.mylibrary.annotations.update", "httpMethod": "PUT", "path": "mylibrary/annotations/{annotationId}", "response": {"$ref": "Annotation"}}, "get": {"scopes": ["https://www.googleapis.com/auth/books"], "parameters": {"country": {"type": "string", "location": "query"}, "annotationId": {"required": true, "type": "string", "location": "path"}, "source": {"type": "string", "location": "query"}}, "id": "books.mylibrary.annotations.get", "httpMethod": "GET", "path": "mylibrary/annotations/{annotationId}", "response": {"$ref": "Annotation"}}}}', true)); + } +} + +class Annotation extends apiModel { + public $kind; + public $updated; + public $created; + public $beforeSelectedText; + protected $__currentVersionRangesType = 'AnnotationCurrentVersionRanges'; + protected $__currentVersionRangesDataType = ''; + public $currentVersionRanges; + public $afterSelectedText; + protected $__clientVersionRangesType = 'AnnotationClientVersionRanges'; + protected $__clientVersionRangesDataType = ''; + public $clientVersionRanges; + public $volumeId; + public $pageIds; + public $layerId; + public $selectedText; + public $highlightStyle; + public $data; + public $id; + public $selfLink; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setBeforeSelectedText($beforeSelectedText) { + $this->beforeSelectedText = $beforeSelectedText; + } + public function getBeforeSelectedText() { + return $this->beforeSelectedText; + } + public function setCurrentVersionRanges(AnnotationCurrentVersionRanges $currentVersionRanges) { + $this->currentVersionRanges = $currentVersionRanges; + } + public function getCurrentVersionRanges() { + return $this->currentVersionRanges; + } + public function setAfterSelectedText($afterSelectedText) { + $this->afterSelectedText = $afterSelectedText; + } + public function getAfterSelectedText() { + return $this->afterSelectedText; + } + public function setClientVersionRanges(AnnotationClientVersionRanges $clientVersionRanges) { + $this->clientVersionRanges = $clientVersionRanges; + } + public function getClientVersionRanges() { + return $this->clientVersionRanges; + } + public function setVolumeId($volumeId) { + $this->volumeId = $volumeId; + } + public function getVolumeId() { + return $this->volumeId; + } + public function setPageIds(/* array(string) */ $pageIds) { + $this->assertIsArray($pageIds, 'string', __METHOD__); + $this->pageIds = $pageIds; + } + public function getPageIds() { + return $this->pageIds; + } + public function setLayerId($layerId) { + $this->layerId = $layerId; + } + public function getLayerId() { + return $this->layerId; + } + public function setSelectedText($selectedText) { + $this->selectedText = $selectedText; + } + public function getSelectedText() { + return $this->selectedText; + } + public function setHighlightStyle($highlightStyle) { + $this->highlightStyle = $highlightStyle; + } + public function getHighlightStyle() { + return $this->highlightStyle; + } + public function setData($data) { + $this->data = $data; + } + public function getData() { + return $this->data; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class AnnotationClientVersionRanges extends apiModel { + public $contentVersion; + protected $__gbTextRangeType = 'BooksAnnotationsRange'; + protected $__gbTextRangeDataType = ''; + public $gbTextRange; + protected $__cfiRangeType = 'BooksAnnotationsRange'; + protected $__cfiRangeDataType = ''; + public $cfiRange; + protected $__gbImageRangeType = 'BooksAnnotationsRange'; + protected $__gbImageRangeDataType = ''; + public $gbImageRange; + public function setContentVersion($contentVersion) { + $this->contentVersion = $contentVersion; + } + public function getContentVersion() { + return $this->contentVersion; + } + public function setGbTextRange(BooksAnnotationsRange $gbTextRange) { + $this->gbTextRange = $gbTextRange; + } + public function getGbTextRange() { + return $this->gbTextRange; + } + public function setCfiRange(BooksAnnotationsRange $cfiRange) { + $this->cfiRange = $cfiRange; + } + public function getCfiRange() { + return $this->cfiRange; + } + public function setGbImageRange(BooksAnnotationsRange $gbImageRange) { + $this->gbImageRange = $gbImageRange; + } + public function getGbImageRange() { + return $this->gbImageRange; + } +} + +class AnnotationCurrentVersionRanges extends apiModel { + public $contentVersion; + protected $__gbTextRangeType = 'BooksAnnotationsRange'; + protected $__gbTextRangeDataType = ''; + public $gbTextRange; + protected $__cfiRangeType = 'BooksAnnotationsRange'; + protected $__cfiRangeDataType = ''; + public $cfiRange; + protected $__gbImageRangeType = 'BooksAnnotationsRange'; + protected $__gbImageRangeDataType = ''; + public $gbImageRange; + public function setContentVersion($contentVersion) { + $this->contentVersion = $contentVersion; + } + public function getContentVersion() { + return $this->contentVersion; + } + public function setGbTextRange(BooksAnnotationsRange $gbTextRange) { + $this->gbTextRange = $gbTextRange; + } + public function getGbTextRange() { + return $this->gbTextRange; + } + public function setCfiRange(BooksAnnotationsRange $cfiRange) { + $this->cfiRange = $cfiRange; + } + public function getCfiRange() { + return $this->cfiRange; + } + public function setGbImageRange(BooksAnnotationsRange $gbImageRange) { + $this->gbImageRange = $gbImageRange; + } + public function getGbImageRange() { + return $this->gbImageRange; + } +} + +class Annotations extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Annotation'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $totalItems; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Annotation) */ $items) { + $this->assertIsArray($items, 'Annotation', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } +} + +class BooksAnnotationsRange extends apiModel { + public $startPosition; + public $endPosition; + public $startOffset; + public $endOffset; + public function setStartPosition($startPosition) { + $this->startPosition = $startPosition; + } + public function getStartPosition() { + return $this->startPosition; + } + public function setEndPosition($endPosition) { + $this->endPosition = $endPosition; + } + public function getEndPosition() { + return $this->endPosition; + } + public function setStartOffset($startOffset) { + $this->startOffset = $startOffset; + } + public function getStartOffset() { + return $this->startOffset; + } + public function setEndOffset($endOffset) { + $this->endOffset = $endOffset; + } + public function getEndOffset() { + return $this->endOffset; + } +} + +class Bookshelf extends apiModel { + public $kind; + public $description; + public $created; + public $volumeCount; + public $title; + public $updated; + public $access; + public $volumesLastUpdated; + public $id; + public $selfLink; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setVolumeCount($volumeCount) { + $this->volumeCount = $volumeCount; + } + public function getVolumeCount() { + return $this->volumeCount; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setAccess($access) { + $this->access = $access; + } + public function getAccess() { + return $this->access; + } + public function setVolumesLastUpdated($volumesLastUpdated) { + $this->volumesLastUpdated = $volumesLastUpdated; + } + public function getVolumesLastUpdated() { + return $this->volumesLastUpdated; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class Bookshelves extends apiModel { + protected $__itemsType = 'Bookshelf'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Bookshelf) */ $items) { + $this->assertIsArray($items, 'Bookshelf', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class ConcurrentAccessRestriction extends apiModel { + public $nonce; + public $kind; + public $restricted; + public $volumeId; + public $maxConcurrentDevices; + public $deviceAllowed; + public $source; + public $timeWindowSeconds; + public $signature; + public $reasonCode; + public $message; + public function setNonce($nonce) { + $this->nonce = $nonce; + } + public function getNonce() { + return $this->nonce; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setRestricted($restricted) { + $this->restricted = $restricted; + } + public function getRestricted() { + return $this->restricted; + } + public function setVolumeId($volumeId) { + $this->volumeId = $volumeId; + } + public function getVolumeId() { + return $this->volumeId; + } + public function setMaxConcurrentDevices($maxConcurrentDevices) { + $this->maxConcurrentDevices = $maxConcurrentDevices; + } + public function getMaxConcurrentDevices() { + return $this->maxConcurrentDevices; + } + public function setDeviceAllowed($deviceAllowed) { + $this->deviceAllowed = $deviceAllowed; + } + public function getDeviceAllowed() { + return $this->deviceAllowed; + } + public function setSource($source) { + $this->source = $source; + } + public function getSource() { + return $this->source; + } + public function setTimeWindowSeconds($timeWindowSeconds) { + $this->timeWindowSeconds = $timeWindowSeconds; + } + public function getTimeWindowSeconds() { + return $this->timeWindowSeconds; + } + public function setSignature($signature) { + $this->signature = $signature; + } + public function getSignature() { + return $this->signature; + } + public function setReasonCode($reasonCode) { + $this->reasonCode = $reasonCode; + } + public function getReasonCode() { + return $this->reasonCode; + } + public function setMessage($message) { + $this->message = $message; + } + public function getMessage() { + return $this->message; + } +} + +class DownloadAccessRestriction extends apiModel { + public $nonce; + public $kind; + public $justAcquired; + public $maxDownloadDevices; + public $downloadsAcquired; + public $signature; + public $volumeId; + public $deviceAllowed; + public $source; + public $restricted; + public $reasonCode; + public $message; + public function setNonce($nonce) { + $this->nonce = $nonce; + } + public function getNonce() { + return $this->nonce; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setJustAcquired($justAcquired) { + $this->justAcquired = $justAcquired; + } + public function getJustAcquired() { + return $this->justAcquired; + } + public function setMaxDownloadDevices($maxDownloadDevices) { + $this->maxDownloadDevices = $maxDownloadDevices; + } + public function getMaxDownloadDevices() { + return $this->maxDownloadDevices; + } + public function setDownloadsAcquired($downloadsAcquired) { + $this->downloadsAcquired = $downloadsAcquired; + } + public function getDownloadsAcquired() { + return $this->downloadsAcquired; + } + public function setSignature($signature) { + $this->signature = $signature; + } + public function getSignature() { + return $this->signature; + } + public function setVolumeId($volumeId) { + $this->volumeId = $volumeId; + } + public function getVolumeId() { + return $this->volumeId; + } + public function setDeviceAllowed($deviceAllowed) { + $this->deviceAllowed = $deviceAllowed; + } + public function getDeviceAllowed() { + return $this->deviceAllowed; + } + public function setSource($source) { + $this->source = $source; + } + public function getSource() { + return $this->source; + } + public function setRestricted($restricted) { + $this->restricted = $restricted; + } + public function getRestricted() { + return $this->restricted; + } + public function setReasonCode($reasonCode) { + $this->reasonCode = $reasonCode; + } + public function getReasonCode() { + return $this->reasonCode; + } + public function setMessage($message) { + $this->message = $message; + } + public function getMessage() { + return $this->message; + } +} + +class DownloadAccesses extends apiModel { + protected $__downloadAccessListType = 'DownloadAccessRestriction'; + protected $__downloadAccessListDataType = 'array'; + public $downloadAccessList; + public $kind; + public function setDownloadAccessList(/* array(DownloadAccessRestriction) */ $downloadAccessList) { + $this->assertIsArray($downloadAccessList, 'DownloadAccessRestriction', __METHOD__); + $this->downloadAccessList = $downloadAccessList; + } + public function getDownloadAccessList() { + return $this->downloadAccessList; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class ReadingPosition extends apiModel { + public $kind; + public $gbImagePosition; + public $epubCfiPosition; + public $updated; + public $volumeId; + public $pdfPosition; + public $gbTextPosition; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setGbImagePosition($gbImagePosition) { + $this->gbImagePosition = $gbImagePosition; + } + public function getGbImagePosition() { + return $this->gbImagePosition; + } + public function setEpubCfiPosition($epubCfiPosition) { + $this->epubCfiPosition = $epubCfiPosition; + } + public function getEpubCfiPosition() { + return $this->epubCfiPosition; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setVolumeId($volumeId) { + $this->volumeId = $volumeId; + } + public function getVolumeId() { + return $this->volumeId; + } + public function setPdfPosition($pdfPosition) { + $this->pdfPosition = $pdfPosition; + } + public function getPdfPosition() { + return $this->pdfPosition; + } + public function setGbTextPosition($gbTextPosition) { + $this->gbTextPosition = $gbTextPosition; + } + public function getGbTextPosition() { + return $this->gbTextPosition; + } +} + +class RequestAccess extends apiModel { + protected $__downloadAccessType = 'DownloadAccessRestriction'; + protected $__downloadAccessDataType = ''; + public $downloadAccess; + public $kind; + protected $__concurrentAccessType = 'ConcurrentAccessRestriction'; + protected $__concurrentAccessDataType = ''; + public $concurrentAccess; + public function setDownloadAccess(DownloadAccessRestriction $downloadAccess) { + $this->downloadAccess = $downloadAccess; + } + public function getDownloadAccess() { + return $this->downloadAccess; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setConcurrentAccess(ConcurrentAccessRestriction $concurrentAccess) { + $this->concurrentAccess = $concurrentAccess; + } + public function getConcurrentAccess() { + return $this->concurrentAccess; + } +} + +class Review extends apiModel { + public $rating; + public $kind; + protected $__authorType = 'ReviewAuthor'; + protected $__authorDataType = ''; + public $author; + public $title; + public $volumeId; + public $content; + protected $__sourceType = 'ReviewSource'; + protected $__sourceDataType = ''; + public $source; + public $date; + public $type; + public $fullTextUrl; + public function setRating($rating) { + $this->rating = $rating; + } + public function getRating() { + return $this->rating; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAuthor(ReviewAuthor $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setVolumeId($volumeId) { + $this->volumeId = $volumeId; + } + public function getVolumeId() { + return $this->volumeId; + } + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setSource(ReviewSource $source) { + $this->source = $source; + } + public function getSource() { + return $this->source; + } + public function setDate($date) { + $this->date = $date; + } + public function getDate() { + return $this->date; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setFullTextUrl($fullTextUrl) { + $this->fullTextUrl = $fullTextUrl; + } + public function getFullTextUrl() { + return $this->fullTextUrl; + } +} + +class ReviewAuthor extends apiModel { + public $displayName; + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } +} + +class ReviewSource extends apiModel { + public $extraDescription; + public $url; + public $description; + public function setExtraDescription($extraDescription) { + $this->extraDescription = $extraDescription; + } + public function getExtraDescription() { + return $this->extraDescription; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } +} + +class Volume extends apiModel { + public $kind; + protected $__accessInfoType = 'VolumeAccessInfo'; + protected $__accessInfoDataType = ''; + public $accessInfo; + protected $__saleInfoType = 'VolumeSaleInfo'; + protected $__saleInfoDataType = ''; + public $saleInfo; + public $etag; + protected $__userInfoType = 'VolumeUserInfo'; + protected $__userInfoDataType = ''; + public $userInfo; + protected $__volumeInfoType = 'VolumeVolumeInfo'; + protected $__volumeInfoDataType = ''; + public $volumeInfo; + public $id; + public $selfLink; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAccessInfo(VolumeAccessInfo $accessInfo) { + $this->accessInfo = $accessInfo; + } + public function getAccessInfo() { + return $this->accessInfo; + } + public function setSaleInfo(VolumeSaleInfo $saleInfo) { + $this->saleInfo = $saleInfo; + } + public function getSaleInfo() { + return $this->saleInfo; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setUserInfo(VolumeUserInfo $userInfo) { + $this->userInfo = $userInfo; + } + public function getUserInfo() { + return $this->userInfo; + } + public function setVolumeInfo(VolumeVolumeInfo $volumeInfo) { + $this->volumeInfo = $volumeInfo; + } + public function getVolumeInfo() { + return $this->volumeInfo; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class VolumeAccessInfo extends apiModel { + public $publicDomain; + public $embeddable; + protected $__downloadAccessType = 'DownloadAccessRestriction'; + protected $__downloadAccessDataType = ''; + public $downloadAccess; + public $country; + public $textToSpeechPermission; + protected $__pdfType = 'VolumeAccessInfoPdf'; + protected $__pdfDataType = ''; + public $pdf; + public $viewability; + protected $__epubType = 'VolumeAccessInfoEpub'; + protected $__epubDataType = ''; + public $epub; + public $accessViewStatus; + public function setPublicDomain($publicDomain) { + $this->publicDomain = $publicDomain; + } + public function getPublicDomain() { + return $this->publicDomain; + } + public function setEmbeddable($embeddable) { + $this->embeddable = $embeddable; + } + public function getEmbeddable() { + return $this->embeddable; + } + public function setDownloadAccess(DownloadAccessRestriction $downloadAccess) { + $this->downloadAccess = $downloadAccess; + } + public function getDownloadAccess() { + return $this->downloadAccess; + } + public function setCountry($country) { + $this->country = $country; + } + public function getCountry() { + return $this->country; + } + public function setTextToSpeechPermission($textToSpeechPermission) { + $this->textToSpeechPermission = $textToSpeechPermission; + } + public function getTextToSpeechPermission() { + return $this->textToSpeechPermission; + } + public function setPdf(VolumeAccessInfoPdf $pdf) { + $this->pdf = $pdf; + } + public function getPdf() { + return $this->pdf; + } + public function setViewability($viewability) { + $this->viewability = $viewability; + } + public function getViewability() { + return $this->viewability; + } + public function setEpub(VolumeAccessInfoEpub $epub) { + $this->epub = $epub; + } + public function getEpub() { + return $this->epub; + } + public function setAccessViewStatus($accessViewStatus) { + $this->accessViewStatus = $accessViewStatus; + } + public function getAccessViewStatus() { + return $this->accessViewStatus; + } +} + +class VolumeAccessInfoEpub extends apiModel { + public $downloadLink; + public $acsTokenLink; + public function setDownloadLink($downloadLink) { + $this->downloadLink = $downloadLink; + } + public function getDownloadLink() { + return $this->downloadLink; + } + public function setAcsTokenLink($acsTokenLink) { + $this->acsTokenLink = $acsTokenLink; + } + public function getAcsTokenLink() { + return $this->acsTokenLink; + } +} + +class VolumeAccessInfoPdf extends apiModel { + public $downloadLink; + public $acsTokenLink; + public function setDownloadLink($downloadLink) { + $this->downloadLink = $downloadLink; + } + public function getDownloadLink() { + return $this->downloadLink; + } + public function setAcsTokenLink($acsTokenLink) { + $this->acsTokenLink = $acsTokenLink; + } + public function getAcsTokenLink() { + return $this->acsTokenLink; + } +} + +class VolumeSaleInfo extends apiModel { + public $country; + protected $__retailPriceType = 'VolumeSaleInfoRetailPrice'; + protected $__retailPriceDataType = ''; + public $retailPrice; + public $isEbook; + public $saleability; + public $buyLink; + public $onSaleDate; + protected $__listPriceType = 'VolumeSaleInfoListPrice'; + protected $__listPriceDataType = ''; + public $listPrice; + public function setCountry($country) { + $this->country = $country; + } + public function getCountry() { + return $this->country; + } + public function setRetailPrice(VolumeSaleInfoRetailPrice $retailPrice) { + $this->retailPrice = $retailPrice; + } + public function getRetailPrice() { + return $this->retailPrice; + } + public function setIsEbook($isEbook) { + $this->isEbook = $isEbook; + } + public function getIsEbook() { + return $this->isEbook; + } + public function setSaleability($saleability) { + $this->saleability = $saleability; + } + public function getSaleability() { + return $this->saleability; + } + public function setBuyLink($buyLink) { + $this->buyLink = $buyLink; + } + public function getBuyLink() { + return $this->buyLink; + } + public function setOnSaleDate($onSaleDate) { + $this->onSaleDate = $onSaleDate; + } + public function getOnSaleDate() { + return $this->onSaleDate; + } + public function setListPrice(VolumeSaleInfoListPrice $listPrice) { + $this->listPrice = $listPrice; + } + public function getListPrice() { + return $this->listPrice; + } +} + +class VolumeSaleInfoListPrice extends apiModel { + public $amount; + public $currencyCode; + public function setAmount($amount) { + $this->amount = $amount; + } + public function getAmount() { + return $this->amount; + } + public function setCurrencyCode($currencyCode) { + $this->currencyCode = $currencyCode; + } + public function getCurrencyCode() { + return $this->currencyCode; + } +} + +class VolumeSaleInfoRetailPrice extends apiModel { + public $amount; + public $currencyCode; + public function setAmount($amount) { + $this->amount = $amount; + } + public function getAmount() { + return $this->amount; + } + public function setCurrencyCode($currencyCode) { + $this->currencyCode = $currencyCode; + } + public function getCurrencyCode() { + return $this->currencyCode; + } +} + +class VolumeUserInfo extends apiModel { + public $updated; + public $isPreordered; + public $isPurchased; + protected $__readingPositionType = 'ReadingPosition'; + protected $__readingPositionDataType = ''; + public $readingPosition; + protected $__reviewType = 'Review'; + protected $__reviewDataType = ''; + public $review; + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setIsPreordered($isPreordered) { + $this->isPreordered = $isPreordered; + } + public function getIsPreordered() { + return $this->isPreordered; + } + public function setIsPurchased($isPurchased) { + $this->isPurchased = $isPurchased; + } + public function getIsPurchased() { + return $this->isPurchased; + } + public function setReadingPosition(ReadingPosition $readingPosition) { + $this->readingPosition = $readingPosition; + } + public function getReadingPosition() { + return $this->readingPosition; + } + public function setReview(Review $review) { + $this->review = $review; + } + public function getReview() { + return $this->review; + } +} + +class VolumeVolumeInfo extends apiModel { + public $publisher; + public $subtitle; + public $description; + public $language; + public $pageCount; + protected $__imageLinksType = 'VolumeVolumeInfoImageLinks'; + protected $__imageLinksDataType = ''; + public $imageLinks; + public $publishedDate; + public $previewLink; + public $printType; + public $ratingsCount; + public $mainCategory; + protected $__dimensionsType = 'VolumeVolumeInfoDimensions'; + protected $__dimensionsDataType = ''; + public $dimensions; + public $contentVersion; + protected $__industryIdentifiersType = 'VolumeVolumeInfoIndustryIdentifiers'; + protected $__industryIdentifiersDataType = 'array'; + public $industryIdentifiers; + public $authors; + public $title; + public $canonicalVolumeLink; + public $infoLink; + public $categories; + public $averageRating; + public function setPublisher($publisher) { + $this->publisher = $publisher; + } + public function getPublisher() { + return $this->publisher; + } + public function setSubtitle($subtitle) { + $this->subtitle = $subtitle; + } + public function getSubtitle() { + return $this->subtitle; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } + public function setPageCount($pageCount) { + $this->pageCount = $pageCount; + } + public function getPageCount() { + return $this->pageCount; + } + public function setImageLinks(VolumeVolumeInfoImageLinks $imageLinks) { + $this->imageLinks = $imageLinks; + } + public function getImageLinks() { + return $this->imageLinks; + } + public function setPublishedDate($publishedDate) { + $this->publishedDate = $publishedDate; + } + public function getPublishedDate() { + return $this->publishedDate; + } + public function setPreviewLink($previewLink) { + $this->previewLink = $previewLink; + } + public function getPreviewLink() { + return $this->previewLink; + } + public function setPrintType($printType) { + $this->printType = $printType; + } + public function getPrintType() { + return $this->printType; + } + public function setRatingsCount($ratingsCount) { + $this->ratingsCount = $ratingsCount; + } + public function getRatingsCount() { + return $this->ratingsCount; + } + public function setMainCategory($mainCategory) { + $this->mainCategory = $mainCategory; + } + public function getMainCategory() { + return $this->mainCategory; + } + public function setDimensions(VolumeVolumeInfoDimensions $dimensions) { + $this->dimensions = $dimensions; + } + public function getDimensions() { + return $this->dimensions; + } + public function setContentVersion($contentVersion) { + $this->contentVersion = $contentVersion; + } + public function getContentVersion() { + return $this->contentVersion; + } + public function setIndustryIdentifiers(/* array(VolumeVolumeInfoIndustryIdentifiers) */ $industryIdentifiers) { + $this->assertIsArray($industryIdentifiers, 'VolumeVolumeInfoIndustryIdentifiers', __METHOD__); + $this->industryIdentifiers = $industryIdentifiers; + } + public function getIndustryIdentifiers() { + return $this->industryIdentifiers; + } + public function setAuthors(/* array(string) */ $authors) { + $this->assertIsArray($authors, 'string', __METHOD__); + $this->authors = $authors; + } + public function getAuthors() { + return $this->authors; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setCanonicalVolumeLink($canonicalVolumeLink) { + $this->canonicalVolumeLink = $canonicalVolumeLink; + } + public function getCanonicalVolumeLink() { + return $this->canonicalVolumeLink; + } + public function setInfoLink($infoLink) { + $this->infoLink = $infoLink; + } + public function getInfoLink() { + return $this->infoLink; + } + public function setCategories(/* array(string) */ $categories) { + $this->assertIsArray($categories, 'string', __METHOD__); + $this->categories = $categories; + } + public function getCategories() { + return $this->categories; + } + public function setAverageRating($averageRating) { + $this->averageRating = $averageRating; + } + public function getAverageRating() { + return $this->averageRating; + } +} + +class VolumeVolumeInfoDimensions extends apiModel { + public $width; + public $thickness; + public $height; + public function setWidth($width) { + $this->width = $width; + } + public function getWidth() { + return $this->width; + } + public function setThickness($thickness) { + $this->thickness = $thickness; + } + public function getThickness() { + return $this->thickness; + } + public function setHeight($height) { + $this->height = $height; + } + public function getHeight() { + return $this->height; + } +} + +class VolumeVolumeInfoImageLinks extends apiModel { + public $medium; + public $smallThumbnail; + public $large; + public $extraLarge; + public $small; + public $thumbnail; + public function setMedium($medium) { + $this->medium = $medium; + } + public function getMedium() { + return $this->medium; + } + public function setSmallThumbnail($smallThumbnail) { + $this->smallThumbnail = $smallThumbnail; + } + public function getSmallThumbnail() { + return $this->smallThumbnail; + } + public function setLarge($large) { + $this->large = $large; + } + public function getLarge() { + return $this->large; + } + public function setExtraLarge($extraLarge) { + $this->extraLarge = $extraLarge; + } + public function getExtraLarge() { + return $this->extraLarge; + } + public function setSmall($small) { + $this->small = $small; + } + public function getSmall() { + return $this->small; + } + public function setThumbnail($thumbnail) { + $this->thumbnail = $thumbnail; + } + public function getThumbnail() { + return $this->thumbnail; + } +} + +class VolumeVolumeInfoIndustryIdentifiers extends apiModel { + public $identifier; + public $type; + public function setIdentifier($identifier) { + $this->identifier = $identifier; + } + public function getIdentifier() { + return $this->identifier; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class Volumes extends apiModel { + public $totalItems; + protected $__itemsType = 'Volume'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setItems(/* array(Volume) */ $items) { + $this->assertIsArray($items, 'Volume', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiCalendarService.php b/inc/vendors/social-login/Google/contrib/apiCalendarService.php new file mode 100755 index 00000000..cfcbffd6 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiCalendarService.php @@ -0,0 +1,1812 @@ + + * $calendarService = new apiCalendarService(...); + * $freebusy = $calendarService->freebusy; + * + */ + class FreebusyServiceResource extends apiServiceResource { + + + /** + * Returns free/busy information for a set of calendars. (freebusy.query) + * @param FreeBusyRequest $postBody + * @return FreeBusyResponse + */ + public function query(FreeBusyRequest $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('query', array($params)); + if ($this->useObjects()) { + return new FreeBusyResponse($data); + } else { + return $data; + } + } + } + + /** + * The "settings" collection of methods. + * Typical usage is: + * + * $calendarService = new apiCalendarService(...); + * $settings = $calendarService->settings; + * + */ + class SettingsServiceResource extends apiServiceResource { + + + /** + * Returns all user settings for the authenticated user. (settings.list) + * @return Settings + */ + public function listSettings($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Settings($data); + } else { + return $data; + } + } + /** + * Returns a single user setting. (settings.get) + * @param string $setting Name of the user setting. + * @return Setting + */ + public function get($setting, $optParams = array()) { + $params = array('setting' => $setting); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Setting($data); + } else { + return $data; + } + } + } + + /** + * The "calendarList" collection of methods. + * Typical usage is: + * + * $calendarService = new apiCalendarService(...); + * $calendarList = $calendarService->calendarList; + * + */ + class CalendarListServiceResource extends apiServiceResource { + + + /** + * Adds an entry to the user's calendar list. (calendarList.insert) + * @param CalendarListEntry $postBody + * @return CalendarListEntry + */ + public function insert(CalendarListEntry $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new CalendarListEntry($data); + } else { + return $data; + } + } + /** + * Returns an entry on the user's calendar list. (calendarList.get) + * @param string $calendarId Calendar identifier. + * @return CalendarListEntry + */ + public function get($calendarId, $optParams = array()) { + $params = array('calendarId' => $calendarId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new CalendarListEntry($data); + } else { + return $data; + } + } + /** + * Returns entries on the user's calendar list. (calendarList.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken Token specifying which result page to return. Optional. + * @opt_param bool showHidden Whether to show hidden entries. Optional. The default is False. + * @opt_param int maxResults Maximum number of entries returned on one result page. Optional. + * @opt_param string minAccessRole The minimum access role for the user in the returned entires. Optional. The default is no restriction. + * @return CalendarList + */ + public function listCalendarList($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CalendarList($data); + } else { + return $data; + } + } + /** + * Updates an entry on the user's calendar list. (calendarList.update) + * @param string $calendarId Calendar identifier. + * @param CalendarListEntry $postBody + * @return CalendarListEntry + */ + public function update($calendarId, CalendarListEntry $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new CalendarListEntry($data); + } else { + return $data; + } + } + /** + * Updates an entry on the user's calendar list. This method supports patch semantics. + * (calendarList.patch) + * @param string $calendarId Calendar identifier. + * @param CalendarListEntry $postBody + * @return CalendarListEntry + */ + public function patch($calendarId, CalendarListEntry $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new CalendarListEntry($data); + } else { + return $data; + } + } + /** + * Deletes an entry on the user's calendar list. (calendarList.delete) + * @param string $calendarId Calendar identifier. + */ + public function delete($calendarId, $optParams = array()) { + $params = array('calendarId' => $calendarId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "calendars" collection of methods. + * Typical usage is: + * + * $calendarService = new apiCalendarService(...); + * $calendars = $calendarService->calendars; + * + */ + class CalendarsServiceResource extends apiServiceResource { + + + /** + * Creates a secondary calendar. (calendars.insert) + * @param Calendar $postBody + * @return Calendar + */ + public function insert(Calendar $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Calendar($data); + } else { + return $data; + } + } + /** + * Returns metadata for a calendar. (calendars.get) + * @param string $calendarId Calendar identifier. + * @return Calendar + */ + public function get($calendarId, $optParams = array()) { + $params = array('calendarId' => $calendarId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Calendar($data); + } else { + return $data; + } + } + /** + * Clears a primary calendar. This operation deletes all data associated with the primary calendar + * of an account and cannot be undone. (calendars.clear) + * @param string $calendarId Calendar identifier. + */ + public function clear($calendarId, $optParams = array()) { + $params = array('calendarId' => $calendarId); + $params = array_merge($params, $optParams); + $data = $this->__call('clear', array($params)); + return $data; + } + /** + * Updates metadata for a calendar. (calendars.update) + * @param string $calendarId Calendar identifier. + * @param Calendar $postBody + * @return Calendar + */ + public function update($calendarId, Calendar $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Calendar($data); + } else { + return $data; + } + } + /** + * Updates metadata for a calendar. This method supports patch semantics. (calendars.patch) + * @param string $calendarId Calendar identifier. + * @param Calendar $postBody + * @return Calendar + */ + public function patch($calendarId, Calendar $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Calendar($data); + } else { + return $data; + } + } + /** + * Deletes a secondary calendar. (calendars.delete) + * @param string $calendarId Calendar identifier. + */ + public function delete($calendarId, $optParams = array()) { + $params = array('calendarId' => $calendarId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "acl" collection of methods. + * Typical usage is: + * + * $calendarService = new apiCalendarService(...); + * $acl = $calendarService->acl; + * + */ + class AclServiceResource extends apiServiceResource { + + + /** + * Creates an access control rule. (acl.insert) + * @param string $calendarId Calendar identifier. + * @param AclRule $postBody + * @return AclRule + */ + public function insert($calendarId, AclRule $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new AclRule($data); + } else { + return $data; + } + } + /** + * Returns an access control rule. (acl.get) + * @param string $calendarId Calendar identifier. + * @param string $ruleId ACL rule identifier. + * @return AclRule + */ + public function get($calendarId, $ruleId, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'ruleId' => $ruleId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new AclRule($data); + } else { + return $data; + } + } + /** + * Returns the rules in the access control list for the calendar. (acl.list) + * @param string $calendarId Calendar identifier. + * @return Acl + */ + public function listAcl($calendarId, $optParams = array()) { + $params = array('calendarId' => $calendarId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Acl($data); + } else { + return $data; + } + } + /** + * Updates an access control rule. (acl.update) + * @param string $calendarId Calendar identifier. + * @param string $ruleId ACL rule identifier. + * @param AclRule $postBody + * @return AclRule + */ + public function update($calendarId, $ruleId, AclRule $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'ruleId' => $ruleId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new AclRule($data); + } else { + return $data; + } + } + /** + * Updates an access control rule. This method supports patch semantics. (acl.patch) + * @param string $calendarId Calendar identifier. + * @param string $ruleId ACL rule identifier. + * @param AclRule $postBody + * @return AclRule + */ + public function patch($calendarId, $ruleId, AclRule $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'ruleId' => $ruleId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new AclRule($data); + } else { + return $data; + } + } + /** + * Deletes an access control rule. (acl.delete) + * @param string $calendarId Calendar identifier. + * @param string $ruleId ACL rule identifier. + */ + public function delete($calendarId, $ruleId, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'ruleId' => $ruleId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "colors" collection of methods. + * Typical usage is: + * + * $calendarService = new apiCalendarService(...); + * $colors = $calendarService->colors; + * + */ + class ColorsServiceResource extends apiServiceResource { + + + /** + * Returns the color definitions for calendars and events. (colors.get) + * @return Colors + */ + public function get($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Colors($data); + } else { + return $data; + } + } + } + + /** + * The "events" collection of methods. + * Typical usage is: + * + * $calendarService = new apiCalendarService(...); + * $events = $calendarService->events; + * + */ + class EventsServiceResource extends apiServiceResource { + + + /** + * Resets a specialized instance of a recurring event to its original state. (events.reset) + * @param string $calendarId Calendar identifier. + * @param string $eventId Event identifier. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sendNotifications Whether to send notifications about the event update. Optional. The default is False. + * @return Event + */ + public function reset($calendarId, $eventId, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'eventId' => $eventId); + $params = array_merge($params, $optParams); + $data = $this->__call('reset', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Creates an event. (events.insert) + * @param string $calendarId Calendar identifier. + * @param Event $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sendNotifications Whether to send notifications about the creation of the new event. Optional. The default is False. + * @return Event + */ + public function insert($calendarId, Event $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Returns an event. (events.get) + * @param string $calendarId Calendar identifier. + * @param string $eventId Event identifier. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string timeZone Time zone used in the response. Optional. The default is the time zone of the calendar. + * @opt_param int maxAttendees The maximum number of attendees to include in the response. If there are more than the specified number of attendees, only the participant is returned. Optional. + * @return Event + */ + public function get($calendarId, $eventId, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'eventId' => $eventId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Moves an event to another calendar, i.e. changes an event's organizer. (events.move) + * @param string $calendarId Calendar identifier of the source calendar where the event currently is on. + * @param string $eventId Event identifier. + * @param string $destination Calendar identifier of the target calendar where the event is to be moved to. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sendNotifications Whether to send notifications about the change of the event's organizer. Optional. The default is False. + * @return Event + */ + public function move($calendarId, $eventId, $destination, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'eventId' => $eventId, 'destination' => $destination); + $params = array_merge($params, $optParams); + $data = $this->__call('move', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Returns events on the specified calendar. (events.list) + * @param string $calendarId Calendar identifier. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string orderBy The order of the events returned in the result. Optional. The default is an unspecified, stable order. + * @opt_param bool showHiddenInvitations Whether to include hidden invitations in the result. Optional. The default is False. + * @opt_param bool showDeleted Whether to include deleted events (with 'eventStatus' equals 'cancelled') in the result. Optional. The default is False. + * @opt_param string iCalUID Specifies iCalendar UID (iCalUID) of events to be included in the response. Optional. + * @opt_param string updatedMin Lower bound for an event's last modification time (as a RFC 3339 timestamp) to filter by. Optional. The default is not to filter by last modification time. + * @opt_param bool singleEvents Whether to expand recurring events into instances and only return single one-off events and instances of recurring events, but not the underlying recurring events themselves. Optional. The default is False. + * @opt_param int maxResults Maximum number of events returned on one result page. Optional. + * @opt_param string q Free text search terms to find events that match these terms in any field, except for extended properties. Optional. + * @opt_param string pageToken Token specifying which result page to return. Optional. + * @opt_param string timeMin Lower bound (inclusive) for an event's end time to filter by. Optional. The default is not to filter by end time. + * @opt_param string timeZone Time zone used in the response. Optional. The default is the time zone of the calendar. + * @opt_param string timeMax Upper bound (exclusive) for an event's start time to filter by. Optional. The default is not to filter by start time. + * @opt_param int maxAttendees The maximum number of attendees to include in the response. If there are more than the specified number of attendees, only the participant is returned. Optional. + * @return Events + */ + public function listEvents($calendarId, $optParams = array()) { + $params = array('calendarId' => $calendarId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Events($data); + } else { + return $data; + } + } + /** + * Updates an event. (events.update) + * @param string $calendarId Calendar identifier. + * @param string $eventId Event identifier. + * @param Event $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sendNotifications Whether to send notifications about the event update (e.g. attendee's responses, title changes, etc.). Optional. The default is False. + * @return Event + */ + public function update($calendarId, $eventId, Event $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'eventId' => $eventId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Updates an event. This method supports patch semantics. (events.patch) + * @param string $calendarId Calendar identifier. + * @param string $eventId Event identifier. + * @param Event $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sendNotifications Whether to send notifications about the event update (e.g. attendee's responses, title changes, etc.). Optional. The default is False. + * @return Event + */ + public function patch($calendarId, $eventId, Event $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'eventId' => $eventId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Returns instances of the specified recurring event. (events.instances) + * @param string $calendarId Calendar identifier. + * @param string $eventId Recurring event identifier. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool showDeleted Whether to include deleted events (with 'eventStatus' equals 'cancelled') in the result. Optional. The default is False. + * @opt_param int maxResults Maximum number of events returned on one result page. Optional. + * @opt_param string pageToken Token specifying which result page to return. Optional. + * @opt_param string timeZone Time zone used in the response. Optional. The default is the time zone of the calendar. + * @opt_param string originalStart The original start time of the instance in the result. Optional. + * @opt_param int maxAttendees The maximum number of attendees to include in the response. If there are more than the specified number of attendees, only the participant is returned. Optional. + * @return Events + */ + public function instances($calendarId, $eventId, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'eventId' => $eventId); + $params = array_merge($params, $optParams); + $data = $this->__call('instances', array($params)); + if ($this->useObjects()) { + return new Events($data); + } else { + return $data; + } + } + /** + * Imports an event. (events.import) + * @param string $calendarId Calendar identifier. + * @param Event $postBody + * @return Event + */ + public function import($calendarId, Event $postBody, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('import', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Creates an event based on a simple text string. (events.quickAdd) + * @param string $calendarId Calendar identifier. + * @param string $text The text describing the event to be created. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sendNotifications Whether to send notifications about the creation of the event. Optional. The default is False. + * @return Event + */ + public function quickAdd($calendarId, $text, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'text' => $text); + $params = array_merge($params, $optParams); + $data = $this->__call('quickAdd', array($params)); + if ($this->useObjects()) { + return new Event($data); + } else { + return $data; + } + } + /** + * Deletes an event. (events.delete) + * @param string $calendarId Calendar identifier. + * @param string $eventId Event identifier. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sendNotifications Whether to send notifications about the deletion of the event. Optional. The default is False. + */ + public function delete($calendarId, $eventId, $optParams = array()) { + $params = array('calendarId' => $calendarId, 'eventId' => $eventId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + + +/** + * Service definition for Calendar (v3). + *

            + * Lets you manipulate events and other calendar data. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiCalendarService extends apiService { + public $freebusy; + public $settings; + public $calendarList; + public $calendars; + public $acl; + public $colors; + public $events; + /** + * Constructs the internal representation of the Calendar service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/calendar/v3/'; + $this->version = 'v3'; + $this->serviceName = 'calendar'; + + $apiClient->addService($this->serviceName, $this->version); + $this->freebusy = new FreebusyServiceResource($this, $this->serviceName, 'freebusy', json_decode('{"methods": {"query": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "request": {"$ref": "FreeBusyRequest"}, "response": {"$ref": "FreeBusyResponse"}, "httpMethod": "POST", "path": "freeBusy", "id": "calendar.freebusy.query"}}}', true)); + $this->settings = new SettingsServiceResource($this, $this->serviceName, 'settings', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "id": "calendar.settings.list", "httpMethod": "GET", "path": "users/me/settings", "response": {"$ref": "Settings"}}, "get": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"setting": {"required": true, "type": "string", "location": "path"}}, "id": "calendar.settings.get", "httpMethod": "GET", "path": "users/me/settings/{setting}", "response": {"$ref": "Setting"}}}}', true)); + $this->calendarList = new CalendarListServiceResource($this, $this->serviceName, 'calendarList', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/calendar"], "request": {"$ref": "CalendarListEntry"}, "response": {"$ref": "CalendarListEntry"}, "httpMethod": "POST", "path": "users/me/calendarList", "id": "calendar.calendarList.insert"}, "get": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "id": "calendar.calendarList.get", "httpMethod": "GET", "path": "users/me/calendarList/{calendarId}", "response": {"$ref": "CalendarListEntry"}}, "list": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "showHidden": {"type": "boolean", "location": "query"}, "maxResults": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}, "minAccessRole": {"enum": ["freeBusyReader", "owner", "reader", "writer"], "type": "string", "location": "query"}}, "response": {"$ref": "CalendarList"}, "httpMethod": "GET", "path": "users/me/calendarList", "id": "calendar.calendarList.list"}, "update": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "CalendarListEntry"}, "id": "calendar.calendarList.update", "httpMethod": "PUT", "path": "users/me/calendarList/{calendarId}", "response": {"$ref": "CalendarListEntry"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "CalendarListEntry"}, "id": "calendar.calendarList.patch", "httpMethod": "PATCH", "path": "users/me/calendarList/{calendarId}", "response": {"$ref": "CalendarListEntry"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "users/me/calendarList/{calendarId}", "id": "calendar.calendarList.delete"}}}', true)); + $this->calendars = new CalendarsServiceResource($this, $this->serviceName, 'calendars', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/calendar"], "request": {"$ref": "Calendar"}, "response": {"$ref": "Calendar"}, "httpMethod": "POST", "path": "calendars", "id": "calendar.calendars.insert"}, "get": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "id": "calendar.calendars.get", "httpMethod": "GET", "path": "calendars/{calendarId}", "response": {"$ref": "Calendar"}}, "clear": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "POST", "path": "calendars/{calendarId}/clear", "id": "calendar.calendars.clear"}, "update": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Calendar"}, "id": "calendar.calendars.update", "httpMethod": "PUT", "path": "calendars/{calendarId}", "response": {"$ref": "Calendar"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Calendar"}, "id": "calendar.calendars.patch", "httpMethod": "PATCH", "path": "calendars/{calendarId}", "response": {"$ref": "Calendar"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "calendars/{calendarId}", "id": "calendar.calendars.delete"}}}', true)); + $this->acl = new AclServiceResource($this, $this->serviceName, 'acl', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "AclRule"}, "id": "calendar.acl.insert", "httpMethod": "POST", "path": "calendars/{calendarId}/acl", "response": {"$ref": "AclRule"}}, "get": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}, "ruleId": {"required": true, "type": "string", "location": "path"}}, "id": "calendar.acl.get", "httpMethod": "GET", "path": "calendars/{calendarId}/acl/{ruleId}", "response": {"$ref": "AclRule"}}, "list": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "id": "calendar.acl.list", "httpMethod": "GET", "path": "calendars/{calendarId}/acl", "response": {"$ref": "Acl"}}, "update": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}, "ruleId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "AclRule"}, "id": "calendar.acl.update", "httpMethod": "PUT", "path": "calendars/{calendarId}/acl/{ruleId}", "response": {"$ref": "AclRule"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}, "ruleId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "AclRule"}, "id": "calendar.acl.patch", "httpMethod": "PATCH", "path": "calendars/{calendarId}/acl/{ruleId}", "response": {"$ref": "AclRule"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}, "ruleId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "calendars/{calendarId}/acl/{ruleId}", "id": "calendar.acl.delete"}}}', true)); + $this->colors = new ColorsServiceResource($this, $this->serviceName, 'colors', json_decode('{"methods": {"get": {"id": "calendar.colors.get", "path": "colors", "httpMethod": "GET", "response": {"$ref": "Colors"}}}}', true)); + $this->events = new EventsServiceResource($this, $this->serviceName, 'events', json_decode('{"methods": {"reset": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"eventId": {"required": true, "type": "string", "location": "path"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "sendNotifications": {"type": "boolean", "location": "query"}}, "id": "calendar.events.reset", "httpMethod": "POST", "path": "calendars/{calendarId}/events/{eventId}/reset", "response": {"$ref": "Event"}}, "insert": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}, "sendNotifications": {"type": "boolean", "location": "query"}}, "request": {"$ref": "Event"}, "id": "calendar.events.insert", "httpMethod": "POST", "path": "calendars/{calendarId}/events", "response": {"$ref": "Event"}}, "get": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"eventId": {"required": true, "type": "string", "location": "path"}, "timeZone": {"type": "string", "location": "query"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "maxAttendees": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}}, "id": "calendar.events.get", "httpMethod": "GET", "path": "calendars/{calendarId}/events/{eventId}", "response": {"$ref": "Event"}}, "move": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"eventId": {"required": true, "type": "string", "location": "path"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "destination": {"required": true, "type": "string", "location": "query"}, "sendNotifications": {"type": "boolean", "location": "query"}}, "id": "calendar.events.move", "httpMethod": "POST", "path": "calendars/{calendarId}/events/{eventId}/move", "response": {"$ref": "Event"}}, "list": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"orderBy": {"enum": ["startTime", "updated"], "type": "string", "location": "query"}, "showHiddenInvitations": {"type": "boolean", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "iCalUID": {"type": "string", "location": "query"}, "updatedMin": {"type": "string", "location": "query"}, "singleEvents": {"type": "boolean", "location": "query"}, "maxResults": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}, "q": {"type": "string", "location": "query"}, "showDeleted": {"type": "boolean", "location": "query"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "timeMin": {"type": "string", "location": "query"}, "timeZone": {"type": "string", "location": "query"}, "timeMax": {"type": "string", "location": "query"}, "maxAttendees": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}}, "id": "calendar.events.list", "httpMethod": "GET", "path": "calendars/{calendarId}/events", "response": {"$ref": "Events"}}, "update": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"eventId": {"required": true, "type": "string", "location": "path"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "sendNotifications": {"type": "boolean", "location": "query"}}, "request": {"$ref": "Event"}, "id": "calendar.events.update", "httpMethod": "PUT", "path": "calendars/{calendarId}/events/{eventId}", "response": {"$ref": "Event"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"eventId": {"required": true, "type": "string", "location": "path"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "sendNotifications": {"type": "boolean", "location": "query"}}, "request": {"$ref": "Event"}, "id": "calendar.events.patch", "httpMethod": "PATCH", "path": "calendars/{calendarId}/events/{eventId}", "response": {"$ref": "Event"}}, "instances": {"scopes": ["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.readonly"], "parameters": {"eventId": {"required": true, "type": "string", "location": "path"}, "pageToken": {"type": "string", "location": "query"}, "maxResults": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}, "showDeleted": {"type": "boolean", "location": "query"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "timeZone": {"type": "string", "location": "query"}, "originalStart": {"type": "string", "location": "query"}, "maxAttendees": {"format": "int32", "minimum": "1", "type": "integer", "location": "query"}}, "id": "calendar.events.instances", "httpMethod": "GET", "path": "calendars/{calendarId}/events/{eventId}/instances", "response": {"$ref": "Events"}}, "import": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"calendarId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Event"}, "id": "calendar.events.import", "httpMethod": "POST", "path": "calendars/{calendarId}/events/import", "response": {"$ref": "Event"}}, "quickAdd": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"text": {"required": true, "type": "string", "location": "query"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "sendNotifications": {"type": "boolean", "location": "query"}}, "id": "calendar.events.quickAdd", "httpMethod": "POST", "path": "calendars/{calendarId}/events/quickAdd", "response": {"$ref": "Event"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/calendar"], "parameters": {"eventId": {"required": true, "type": "string", "location": "path"}, "calendarId": {"required": true, "type": "string", "location": "path"}, "sendNotifications": {"type": "boolean", "location": "query"}}, "httpMethod": "DELETE", "path": "calendars/{calendarId}/events/{eventId}", "id": "calendar.events.delete"}}}', true)); + } +} + +class Acl extends apiModel { + public $nextPageToken; + protected $__itemsType = 'AclRule'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(AclRule) */ $items) { + $this->assertIsArray($items, 'AclRule', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class AclRule extends apiModel { + protected $__scopeType = 'AclRuleScope'; + protected $__scopeDataType = ''; + public $scope; + public $kind; + public $etag; + public $role; + public $id; + public function setScope(AclRuleScope $scope) { + $this->scope = $scope; + } + public function getScope() { + return $this->scope; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setRole($role) { + $this->role = $role; + } + public function getRole() { + return $this->role; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class AclRuleScope extends apiModel { + public $type; + public $value; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class Calendar extends apiModel { + public $kind; + public $description; + public $summary; + public $etag; + public $location; + public $timeZone; + public $id; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setSummary($summary) { + $this->summary = $summary; + } + public function getSummary() { + return $this->summary; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setTimeZone($timeZone) { + $this->timeZone = $timeZone; + } + public function getTimeZone() { + return $this->timeZone; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CalendarList extends apiModel { + public $nextPageToken; + protected $__itemsType = 'CalendarListEntry'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(CalendarListEntry) */ $items) { + $this->assertIsArray($items, 'CalendarListEntry', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class CalendarListEntry extends apiModel { + public $kind; + protected $__defaultRemindersType = 'EventReminder'; + protected $__defaultRemindersDataType = 'array'; + public $defaultReminders; + public $description; + public $colorId; + public $selected; + public $summary; + public $etag; + public $location; + public $summaryOverride; + public $timeZone; + public $hidden; + public $accessRole; + public $id; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDefaultReminders(/* array(EventReminder) */ $defaultReminders) { + $this->assertIsArray($defaultReminders, 'EventReminder', __METHOD__); + $this->defaultReminders = $defaultReminders; + } + public function getDefaultReminders() { + return $this->defaultReminders; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setColorId($colorId) { + $this->colorId = $colorId; + } + public function getColorId() { + return $this->colorId; + } + public function setSelected($selected) { + $this->selected = $selected; + } + public function getSelected() { + return $this->selected; + } + public function setSummary($summary) { + $this->summary = $summary; + } + public function getSummary() { + return $this->summary; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setSummaryOverride($summaryOverride) { + $this->summaryOverride = $summaryOverride; + } + public function getSummaryOverride() { + return $this->summaryOverride; + } + public function setTimeZone($timeZone) { + $this->timeZone = $timeZone; + } + public function getTimeZone() { + return $this->timeZone; + } + public function setHidden($hidden) { + $this->hidden = $hidden; + } + public function getHidden() { + return $this->hidden; + } + public function setAccessRole($accessRole) { + $this->accessRole = $accessRole; + } + public function getAccessRole() { + return $this->accessRole; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ColorDefinition extends apiModel { + public $foreground; + public $background; + public function setForeground($foreground) { + $this->foreground = $foreground; + } + public function getForeground() { + return $this->foreground; + } + public function setBackground($background) { + $this->background = $background; + } + public function getBackground() { + return $this->background; + } +} + +class Colors extends apiModel { + protected $__calendarType = 'ColorDefinition'; + protected $__calendarDataType = 'map'; + public $calendar; + public $updated; + protected $__eventType = 'ColorDefinition'; + protected $__eventDataType = 'map'; + public $event; + public $kind; + public function setCalendar(ColorDefinition $calendar) { + $this->calendar = $calendar; + } + public function getCalendar() { + return $this->calendar; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setEvent(ColorDefinition $event) { + $this->event = $event; + } + public function getEvent() { + return $this->event; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class Error extends apiModel { + public $domain; + public $reason; + public function setDomain($domain) { + $this->domain = $domain; + } + public function getDomain() { + return $this->domain; + } + public function setReason($reason) { + $this->reason = $reason; + } + public function getReason() { + return $this->reason; + } +} + +class Event extends apiModel { + protected $__creatorType = 'EventCreator'; + protected $__creatorDataType = ''; + public $creator; + protected $__organizerType = 'EventOrganizer'; + protected $__organizerDataType = ''; + public $organizer; + public $id; + protected $__attendeesType = 'EventAttendee'; + protected $__attendeesDataType = 'array'; + public $attendees; + public $htmlLink; + public $recurrence; + protected $__startType = 'EventDateTime'; + protected $__startDataType = ''; + public $start; + public $etag; + public $location; + public $recurringEventId; + protected $__originalStartTimeType = 'EventDateTime'; + protected $__originalStartTimeDataType = ''; + public $originalStartTime; + public $status; + public $updated; + protected $__gadgetType = 'EventGadget'; + protected $__gadgetDataType = ''; + public $gadget; + public $description; + public $iCalUID; + protected $__extendedPropertiesType = 'EventExtendedProperties'; + protected $__extendedPropertiesDataType = ''; + public $extendedProperties; + public $sequence; + public $visibility; + public $guestsCanModify; + protected $__endType = 'EventDateTime'; + protected $__endDataType = ''; + public $end; + public $attendeesOmitted; + public $kind; + public $created; + public $colorId; + public $anyoneCanAddSelf; + protected $__remindersType = 'EventReminders'; + protected $__remindersDataType = ''; + public $reminders; + public $guestsCanSeeOtherGuests; + public $summary; + public $guestsCanInviteOthers; + public $transparency; + public $privateCopy; + public function setCreator(EventCreator $creator) { + $this->creator = $creator; + } + public function getCreator() { + return $this->creator; + } + public function setOrganizer(EventOrganizer $organizer) { + $this->organizer = $organizer; + } + public function getOrganizer() { + return $this->organizer; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setAttendees(/* array(EventAttendee) */ $attendees) { + $this->assertIsArray($attendees, 'EventAttendee', __METHOD__); + $this->attendees = $attendees; + } + public function getAttendees() { + return $this->attendees; + } + public function setHtmlLink($htmlLink) { + $this->htmlLink = $htmlLink; + } + public function getHtmlLink() { + return $this->htmlLink; + } + public function setRecurrence(/* array(string) */ $recurrence) { + $this->assertIsArray($recurrence, 'string', __METHOD__); + $this->recurrence = $recurrence; + } + public function getRecurrence() { + return $this->recurrence; + } + public function setStart(EventDateTime $start) { + $this->start = $start; + } + public function getStart() { + return $this->start; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setRecurringEventId($recurringEventId) { + $this->recurringEventId = $recurringEventId; + } + public function getRecurringEventId() { + return $this->recurringEventId; + } + public function setOriginalStartTime(EventDateTime $originalStartTime) { + $this->originalStartTime = $originalStartTime; + } + public function getOriginalStartTime() { + return $this->originalStartTime; + } + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setGadget(EventGadget $gadget) { + $this->gadget = $gadget; + } + public function getGadget() { + return $this->gadget; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setICalUID($iCalUID) { + $this->iCalUID = $iCalUID; + } + public function getICalUID() { + return $this->iCalUID; + } + public function setExtendedProperties(EventExtendedProperties $extendedProperties) { + $this->extendedProperties = $extendedProperties; + } + public function getExtendedProperties() { + return $this->extendedProperties; + } + public function setSequence($sequence) { + $this->sequence = $sequence; + } + public function getSequence() { + return $this->sequence; + } + public function setVisibility($visibility) { + $this->visibility = $visibility; + } + public function getVisibility() { + return $this->visibility; + } + public function setGuestsCanModify($guestsCanModify) { + $this->guestsCanModify = $guestsCanModify; + } + public function getGuestsCanModify() { + return $this->guestsCanModify; + } + public function setEnd(EventDateTime $end) { + $this->end = $end; + } + public function getEnd() { + return $this->end; + } + public function setAttendeesOmitted($attendeesOmitted) { + $this->attendeesOmitted = $attendeesOmitted; + } + public function getAttendeesOmitted() { + return $this->attendeesOmitted; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setColorId($colorId) { + $this->colorId = $colorId; + } + public function getColorId() { + return $this->colorId; + } + public function setAnyoneCanAddSelf($anyoneCanAddSelf) { + $this->anyoneCanAddSelf = $anyoneCanAddSelf; + } + public function getAnyoneCanAddSelf() { + return $this->anyoneCanAddSelf; + } + public function setReminders(EventReminders $reminders) { + $this->reminders = $reminders; + } + public function getReminders() { + return $this->reminders; + } + public function setGuestsCanSeeOtherGuests($guestsCanSeeOtherGuests) { + $this->guestsCanSeeOtherGuests = $guestsCanSeeOtherGuests; + } + public function getGuestsCanSeeOtherGuests() { + return $this->guestsCanSeeOtherGuests; + } + public function setSummary($summary) { + $this->summary = $summary; + } + public function getSummary() { + return $this->summary; + } + public function setGuestsCanInviteOthers($guestsCanInviteOthers) { + $this->guestsCanInviteOthers = $guestsCanInviteOthers; + } + public function getGuestsCanInviteOthers() { + return $this->guestsCanInviteOthers; + } + public function setTransparency($transparency) { + $this->transparency = $transparency; + } + public function getTransparency() { + return $this->transparency; + } + public function setPrivateCopy($privateCopy) { + $this->privateCopy = $privateCopy; + } + public function getPrivateCopy() { + return $this->privateCopy; + } +} + +class EventAttendee extends apiModel { + public $comment; + public $displayName; + public $self; + public $responseStatus; + public $additionalGuests; + public $resource; + public $organizer; + public $optional; + public $email; + public function setComment($comment) { + $this->comment = $comment; + } + public function getComment() { + return $this->comment; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setSelf($self) { + $this->self = $self; + } + public function getSelf() { + return $this->self; + } + public function setResponseStatus($responseStatus) { + $this->responseStatus = $responseStatus; + } + public function getResponseStatus() { + return $this->responseStatus; + } + public function setAdditionalGuests($additionalGuests) { + $this->additionalGuests = $additionalGuests; + } + public function getAdditionalGuests() { + return $this->additionalGuests; + } + public function setResource($resource) { + $this->resource = $resource; + } + public function getResource() { + return $this->resource; + } + public function setOrganizer($organizer) { + $this->organizer = $organizer; + } + public function getOrganizer() { + return $this->organizer; + } + public function setOptional($optional) { + $this->optional = $optional; + } + public function getOptional() { + return $this->optional; + } + public function setEmail($email) { + $this->email = $email; + } + public function getEmail() { + return $this->email; + } +} + +class EventCreator extends apiModel { + public $displayName; + public $email; + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setEmail($email) { + $this->email = $email; + } + public function getEmail() { + return $this->email; + } +} + +class EventDateTime extends apiModel { + public $date; + public $timeZone; + public $dateTime; + public function setDate($date) { + $this->date = $date; + } + public function getDate() { + return $this->date; + } + public function setTimeZone($timeZone) { + $this->timeZone = $timeZone; + } + public function getTimeZone() { + return $this->timeZone; + } + public function setDateTime($dateTime) { + $this->dateTime = $dateTime; + } + public function getDateTime() { + return $this->dateTime; + } +} + +class EventExtendedProperties extends apiModel { + public $shared; + public $private; + public function setShared($shared) { + $this->shared = $shared; + } + public function getShared() { + return $this->shared; + } + public function setPrivate($private) { + $this->private = $private; + } + public function getPrivate() { + return $this->private; + } +} + +class EventGadget extends apiModel { + public $preferences; + public $title; + public $height; + public $width; + public $link; + public $type; + public $display; + public $iconLink; + public function setPreferences($preferences) { + $this->preferences = $preferences; + } + public function getPreferences() { + return $this->preferences; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setHeight($height) { + $this->height = $height; + } + public function getHeight() { + return $this->height; + } + public function setWidth($width) { + $this->width = $width; + } + public function getWidth() { + return $this->width; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setDisplay($display) { + $this->display = $display; + } + public function getDisplay() { + return $this->display; + } + public function setIconLink($iconLink) { + $this->iconLink = $iconLink; + } + public function getIconLink() { + return $this->iconLink; + } +} + +class EventOrganizer extends apiModel { + public $displayName; + public $email; + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setEmail($email) { + $this->email = $email; + } + public function getEmail() { + return $this->email; + } +} + +class EventReminder extends apiModel { + public $minutes; + public $method; + public function setMinutes($minutes) { + $this->minutes = $minutes; + } + public function getMinutes() { + return $this->minutes; + } + public function setMethod($method) { + $this->method = $method; + } + public function getMethod() { + return $this->method; + } +} + +class EventReminders extends apiModel { + protected $__overridesType = 'EventReminder'; + protected $__overridesDataType = 'array'; + public $overrides; + public $useDefault; + public function setOverrides(/* array(EventReminder) */ $overrides) { + $this->assertIsArray($overrides, 'EventReminder', __METHOD__); + $this->overrides = $overrides; + } + public function getOverrides() { + return $this->overrides; + } + public function setUseDefault($useDefault) { + $this->useDefault = $useDefault; + } + public function getUseDefault() { + return $this->useDefault; + } +} + +class Events extends apiModel { + public $nextPageToken; + public $kind; + protected $__defaultRemindersType = 'EventReminder'; + protected $__defaultRemindersDataType = 'array'; + public $defaultReminders; + public $description; + protected $__itemsType = 'Event'; + protected $__itemsDataType = 'array'; + public $items; + public $updated; + public $summary; + public $etag; + public $timeZone; + public $accessRole; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDefaultReminders(/* array(EventReminder) */ $defaultReminders) { + $this->assertIsArray($defaultReminders, 'EventReminder', __METHOD__); + $this->defaultReminders = $defaultReminders; + } + public function getDefaultReminders() { + return $this->defaultReminders; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setItems(/* array(Event) */ $items) { + $this->assertIsArray($items, 'Event', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setSummary($summary) { + $this->summary = $summary; + } + public function getSummary() { + return $this->summary; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setTimeZone($timeZone) { + $this->timeZone = $timeZone; + } + public function getTimeZone() { + return $this->timeZone; + } + public function setAccessRole($accessRole) { + $this->accessRole = $accessRole; + } + public function getAccessRole() { + return $this->accessRole; + } +} + +class FreeBusyCalendar extends apiModel { + protected $__busyType = 'TimePeriod'; + protected $__busyDataType = 'array'; + public $busy; + protected $__errorsType = 'Error'; + protected $__errorsDataType = 'array'; + public $errors; + public function setBusy(/* array(TimePeriod) */ $busy) { + $this->assertIsArray($busy, 'TimePeriod', __METHOD__); + $this->busy = $busy; + } + public function getBusy() { + return $this->busy; + } + public function setErrors(/* array(Error) */ $errors) { + $this->assertIsArray($errors, 'Error', __METHOD__); + $this->errors = $errors; + } + public function getErrors() { + return $this->errors; + } +} + +class FreeBusyGroup extends apiModel { + protected $__errorsType = 'Error'; + protected $__errorsDataType = 'array'; + public $errors; + public $calendars; + public function setErrors(/* array(Error) */ $errors) { + $this->assertIsArray($errors, 'Error', __METHOD__); + $this->errors = $errors; + } + public function getErrors() { + return $this->errors; + } + public function setCalendars(/* array(string) */ $calendars) { + $this->assertIsArray($calendars, 'string', __METHOD__); + $this->calendars = $calendars; + } + public function getCalendars() { + return $this->calendars; + } +} + +class FreeBusyRequest extends apiModel { + public $calendarExpansionMax; + public $groupExpansionMax; + public $timeMax; + protected $__itemsType = 'FreeBusyRequestItem'; + protected $__itemsDataType = 'array'; + public $items; + public $timeMin; + public $timeZone; + public function setCalendarExpansionMax($calendarExpansionMax) { + $this->calendarExpansionMax = $calendarExpansionMax; + } + public function getCalendarExpansionMax() { + return $this->calendarExpansionMax; + } + public function setGroupExpansionMax($groupExpansionMax) { + $this->groupExpansionMax = $groupExpansionMax; + } + public function getGroupExpansionMax() { + return $this->groupExpansionMax; + } + public function setTimeMax($timeMax) { + $this->timeMax = $timeMax; + } + public function getTimeMax() { + return $this->timeMax; + } + public function setItems(/* array(FreeBusyRequestItem) */ $items) { + $this->assertIsArray($items, 'FreeBusyRequestItem', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setTimeMin($timeMin) { + $this->timeMin = $timeMin; + } + public function getTimeMin() { + return $this->timeMin; + } + public function setTimeZone($timeZone) { + $this->timeZone = $timeZone; + } + public function getTimeZone() { + return $this->timeZone; + } +} + +class FreeBusyRequestItem extends apiModel { + public $id; + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class FreeBusyResponse extends apiModel { + public $timeMax; + public $kind; + protected $__calendarsType = 'FreeBusyCalendar'; + protected $__calendarsDataType = 'map'; + public $calendars; + public $timeMin; + protected $__groupsType = 'FreeBusyGroup'; + protected $__groupsDataType = 'map'; + public $groups; + public function setTimeMax($timeMax) { + $this->timeMax = $timeMax; + } + public function getTimeMax() { + return $this->timeMax; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setCalendars(FreeBusyCalendar $calendars) { + $this->calendars = $calendars; + } + public function getCalendars() { + return $this->calendars; + } + public function setTimeMin($timeMin) { + $this->timeMin = $timeMin; + } + public function getTimeMin() { + return $this->timeMin; + } + public function setGroups(FreeBusyGroup $groups) { + $this->groups = $groups; + } + public function getGroups() { + return $this->groups; + } +} + +class Setting extends apiModel { + public $kind; + public $etag; + public $id; + public $value; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class Settings extends apiModel { + protected $__itemsType = 'Setting'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setItems(/* array(Setting) */ $items) { + $this->assertIsArray($items, 'Setting', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class TimePeriod extends apiModel { + public $start; + public $end; + public function setStart($start) { + $this->start = $start; + } + public function getStart() { + return $this->start; + } + public function setEnd($end) { + $this->end = $end; + } + public function getEnd() { + return $this->end; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiCustomsearchService.php b/inc/vendors/social-login/Google/contrib/apiCustomsearchService.php new file mode 100755 index 00000000..eddce975 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiCustomsearchService.php @@ -0,0 +1,479 @@ + + * $customsearchService = new apiCustomsearchService(...); + * $cse = $customsearchService->cse; + * + */ + class CseServiceResource extends apiServiceResource { + + + /** + * Returns metadata about the search performed, metadata about the custom search engine used for the + * search, and the search results. (cse.list) + * @param string $q Query + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string sort The sort expression to apply to the results + * @opt_param string num Number of search results to return + * @opt_param string googlehost The local Google domain to use to perform the search. + * @opt_param string safe Search safety level + * @opt_param string filter Controls turning on or off the duplicate content filter. + * @opt_param string start The index of the first result to return + * @opt_param string cx The custom search engine ID to scope this search query + * @opt_param string lr The language restriction for the search results + * @opt_param string cr Country restrict(s). + * @opt_param string gl Geolocation of end user. + * @opt_param string cref The URL of a linked custom search engine + * @return Search + */ + public function listCse($q, $optParams = array()) { + $params = array('q' => $q); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Search($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Customsearch (v1). + *

            + * Lets you search over a website or collection of websites + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiCustomsearchService extends apiService { + public $cse; + /** + * Constructs the internal representation of the Customsearch service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/customsearch/'; + $this->version = 'v1'; + $this->serviceName = 'customsearch'; + + $apiClient->addService($this->serviceName, $this->version); + $this->cse = new CseServiceResource($this, $this->serviceName, 'cse', json_decode('{"methods": {"list": {"parameters": {"sort": {"type": "string", "location": "query"}, "filter": {"enum": ["0", "1"], "type": "string", "location": "query"}, "cx": {"type": "string", "location": "query"}, "googlehost": {"type": "string", "location": "query"}, "safe": {"default": "off", "enum": ["high", "medium", "off"], "location": "query", "type": "string"}, "q": {"required": true, "type": "string", "location": "query"}, "start": {"type": "string", "location": "query"}, "num": {"default": "10", "type": "string", "location": "query"}, "lr": {"enum": ["lang_ar", "lang_bg", "lang_ca", "lang_cs", "lang_da", "lang_de", "lang_el", "lang_en", "lang_es", "lang_et", "lang_fi", "lang_fr", "lang_hr", "lang_hu", "lang_id", "lang_is", "lang_it", "lang_iw", "lang_ja", "lang_ko", "lang_lt", "lang_lv", "lang_nl", "lang_no", "lang_pl", "lang_pt", "lang_ro", "lang_ru", "lang_sk", "lang_sl", "lang_sr", "lang_sv", "lang_tr", "lang_zh-CN", "lang_zh-TW"], "type": "string", "location": "query"}, "cr": {"type": "string", "location": "query"}, "gl": {"type": "string", "location": "query"}, "cref": {"type": "string", "location": "query"}}, "id": "search.cse.list", "httpMethod": "GET", "path": "v1", "response": {"$ref": "Search"}}}}', true)); + } +} + +class Context extends apiModel { + protected $__facetsType = 'ContextFacets'; + protected $__facetsDataType = 'array'; + public $facets; + public $title; + public function setFacets(/* array(ContextFacets) */ $facets) { + $this->assertIsArray($facets, 'ContextFacets', __METHOD__); + $this->facets = $facets; + } + public function getFacets() { + return $this->facets; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } +} + +class ContextFacets extends apiModel { + public $anchor; + public $label; + public function setAnchor($anchor) { + $this->anchor = $anchor; + } + public function getAnchor() { + return $this->anchor; + } + public function setLabel($label) { + $this->label = $label; + } + public function getLabel() { + return $this->label; + } +} + +class Promotion extends apiModel { + public $link; + public $displayLink; + protected $__imageType = 'PromotionImage'; + protected $__imageDataType = ''; + public $image; + protected $__bodyLinesType = 'PromotionBodyLines'; + protected $__bodyLinesDataType = 'array'; + public $bodyLines; + public $title; + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setDisplayLink($displayLink) { + $this->displayLink = $displayLink; + } + public function getDisplayLink() { + return $this->displayLink; + } + public function setImage(PromotionImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setBodyLines(/* array(PromotionBodyLines) */ $bodyLines) { + $this->assertIsArray($bodyLines, 'PromotionBodyLines', __METHOD__); + $this->bodyLines = $bodyLines; + } + public function getBodyLines() { + return $this->bodyLines; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } +} + +class PromotionBodyLines extends apiModel { + public $url; + public $link; + public $title; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } +} + +class PromotionImage extends apiModel { + public $source; + public $width; + public $height; + public function setSource($source) { + $this->source = $source; + } + public function getSource() { + return $this->source; + } + public function setWidth($width) { + $this->width = $width; + } + public function getWidth() { + return $this->width; + } + public function setHeight($height) { + $this->height = $height; + } + public function getHeight() { + return $this->height; + } +} + +class Query extends apiModel { + public $count; + public $sort; + public $outputEncoding; + public $language; + public $title; + public $googleHost; + public $safe; + public $searchTerms; + public $filter; + public $startIndex; + public $cx; + public $startPage; + public $inputEncoding; + public $cr; + public $gl; + public $totalResults; + public $cref; + public function setCount($count) { + $this->count = $count; + } + public function getCount() { + return $this->count; + } + public function setSort($sort) { + $this->sort = $sort; + } + public function getSort() { + return $this->sort; + } + public function setOutputEncoding($outputEncoding) { + $this->outputEncoding = $outputEncoding; + } + public function getOutputEncoding() { + return $this->outputEncoding; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setGoogleHost($googleHost) { + $this->googleHost = $googleHost; + } + public function getGoogleHost() { + return $this->googleHost; + } + public function setSafe($safe) { + $this->safe = $safe; + } + public function getSafe() { + return $this->safe; + } + public function setSearchTerms($searchTerms) { + $this->searchTerms = $searchTerms; + } + public function getSearchTerms() { + return $this->searchTerms; + } + public function setFilter($filter) { + $this->filter = $filter; + } + public function getFilter() { + return $this->filter; + } + public function setStartIndex($startIndex) { + $this->startIndex = $startIndex; + } + public function getStartIndex() { + return $this->startIndex; + } + public function setCx($cx) { + $this->cx = $cx; + } + public function getCx() { + return $this->cx; + } + public function setStartPage($startPage) { + $this->startPage = $startPage; + } + public function getStartPage() { + return $this->startPage; + } + public function setInputEncoding($inputEncoding) { + $this->inputEncoding = $inputEncoding; + } + public function getInputEncoding() { + return $this->inputEncoding; + } + public function setCr($cr) { + $this->cr = $cr; + } + public function getCr() { + return $this->cr; + } + public function setGl($gl) { + $this->gl = $gl; + } + public function getGl() { + return $this->gl; + } + public function setTotalResults($totalResults) { + $this->totalResults = $totalResults; + } + public function getTotalResults() { + return $this->totalResults; + } + public function setCref($cref) { + $this->cref = $cref; + } + public function getCref() { + return $this->cref; + } +} + +class Result extends apiModel { + public $kind; + public $title; + public $displayLink; + public $cacheId; + public $pagemap; + public $snippet; + public $htmlSnippet; + public $link; + public $htmlTitle; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setDisplayLink($displayLink) { + $this->displayLink = $displayLink; + } + public function getDisplayLink() { + return $this->displayLink; + } + public function setCacheId($cacheId) { + $this->cacheId = $cacheId; + } + public function getCacheId() { + return $this->cacheId; + } + public function setPagemap($pagemap) { + $this->pagemap = $pagemap; + } + public function getPagemap() { + return $this->pagemap; + } + public function setSnippet($snippet) { + $this->snippet = $snippet; + } + public function getSnippet() { + return $this->snippet; + } + public function setHtmlSnippet($htmlSnippet) { + $this->htmlSnippet = $htmlSnippet; + } + public function getHtmlSnippet() { + return $this->htmlSnippet; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setHtmlTitle($htmlTitle) { + $this->htmlTitle = $htmlTitle; + } + public function getHtmlTitle() { + return $this->htmlTitle; + } +} + +class Search extends apiModel { + protected $__promotionsType = 'Promotion'; + protected $__promotionsDataType = 'array'; + public $promotions; + public $kind; + protected $__urlType = 'SearchUrl'; + protected $__urlDataType = ''; + public $url; + protected $__itemsType = 'Result'; + protected $__itemsDataType = 'array'; + public $items; + protected $__contextType = 'Context'; + protected $__contextDataType = ''; + public $context; + protected $__queriesType = 'Query'; + protected $__queriesDataType = 'map'; + public $queries; + public function setPromotions(/* array(Promotion) */ $promotions) { + $this->assertIsArray($promotions, 'Promotion', __METHOD__); + $this->promotions = $promotions; + } + public function getPromotions() { + return $this->promotions; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setUrl(SearchUrl $url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setItems(/* array(Result) */ $items) { + $this->assertIsArray($items, 'Result', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setContext(Context $context) { + $this->context = $context; + } + public function getContext() { + return $this->context; + } + public function setQueries(Query $queries) { + $this->queries = $queries; + } + public function getQueries() { + return $this->queries; + } +} + +class SearchUrl extends apiModel { + public $type; + public $template; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setTemplate($template) { + $this->template = $template; + } + public function getTemplate() { + return $this->template; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiFreebaseService.php b/inc/vendors/social-login/Google/contrib/apiFreebaseService.php new file mode 100755 index 00000000..19a430c2 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiFreebaseService.php @@ -0,0 +1,153 @@ + + * $freebaseService = new apiFreebaseService(...); + * $text = $freebaseService->text; + * + */ + class TextServiceResource extends apiServiceResource { + + + /** + * Returns blob attached to node at specified id as HTML (text.get) + * @param string $id The id of the item that you want data about + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string maxlength The max number of characters to return. Valid only for 'plain' format. + * @opt_param string format Sanitizing transformation. + * @return ContentserviceGet + */ + public function get($id, $optParams = array()) { + $params = array('id' => $id); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new ContentserviceGet($data); + } else { + return $data; + } + } + } + + + /** + * The "mqlread" collection of methods. + * Typical usage is: + * + * $freebaseService = new apiFreebaseService(...); + * $mqlread = $freebaseService->mqlread; + * + */ + class MqlreadServiceResource extends apiServiceResource { + /** + * Performs MQL Queries. (mqlread.mqlread) + * @param string $query An envelope containing a single MQL query. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string lang The language of the results - an id of a /type/lang object. + * @opt_param bool html_escape Whether or not to escape entities. + * @opt_param string indent How many spaces to indent the json. + * @opt_param string uniqueness_failure How MQL responds to uniqueness failures. + * @opt_param string dateline The dateline that you get in a mqlwrite response to ensure consistent results. + * @opt_param string cursor The mql cursor. + * @opt_param string callback JS method name for JSONP callbacks. + * @opt_param bool cost Show the costs or not. + * @opt_param string as_of_time Run the query as it would've been run at the specified point in time. + */ + public function mqlread($query, $optParams = array()) { + $params = array('query' => $query); + $params = array_merge($params, $optParams); + $data = $this->__call('mqlread', array($params)); + return $data; + } + + } + + /** + * The "image" collection of methods. + * Typical usage is: + * + * $freebaseService = new apiFreebaseService(...); + * $image = $freebaseService->image; + * + */ + class ImageServiceResource extends apiServiceResource { + /** + * Returns the scaled/cropped image attached to a freebase node. (image.image) + * @param string $id Freebase entity or content id, mid, or guid. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string maxwidth Maximum width in pixels for resulting image. + * @opt_param string maxheight Maximum height in pixels for resulting image. + * @opt_param string fallbackid Use the image associated with this secondary id if no image is associated with the primary id. + * @opt_param bool pad A boolean specifying whether the resulting image should be padded up to the requested dimensions. + * @opt_param string mode Method used to scale or crop image. + */ + public function image($id, $optParams = array()) { + $params = array('id' => $id); + $params = array_merge($params, $optParams); + $data = $this->__call('image', array($params)); + return $data; + } + + } + + +/** + * Service definition for Freebase (v1). + *

            + * Lets you access the Freebase repository of open data. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiFreebaseService extends apiService { + public $mqlread; + public $image; + public $text; + /** + * Constructs the internal representation of the Freebase service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/freebase/v1/'; + $this->version = 'v1'; + $this->serviceName = 'freebase'; + + $apiClient->addService($this->serviceName, $this->version); + $this->text = new TextServiceResource($this, $this->serviceName, 'text', json_decode('{"methods": {"get": {"parameters": {"format": {"default": "plain", "enum": ["html", "plain", "raw"], "location": "query", "type": "string"}, "id": {"repeated": true, "required": true, "type": "string", "location": "path"}, "maxlength": {"format": "uint32", "type": "integer", "location": "query"}}, "id": "freebase.text.get", "httpMethod": "GET", "path": "text{/id*}", "response": {"$ref": "ContentserviceGet"}}}}', true)); + $this->mqlread = new MqlreadServiceResource($this, $this->serviceName, 'mqlread', json_decode('{"httpMethod": "GET", "parameters": {"lang": {"default": "/lang/en", "type": "string", "location": "query"}, "cursor": {"type": "string", "location": "query"}, "indent": {"format": "uint32", "default": "0", "maximum": "10", "location": "query", "type": "integer"}, "uniqueness_failure": {"default": "hard", "enum": ["hard", "soft"], "location": "query", "type": "string"}, "dateline": {"type": "string", "location": "query"}, "html_escape": {"default": "true", "type": "boolean", "location": "query"}, "callback": {"type": "string", "location": "query"}, "cost": {"default": "false", "type": "boolean", "location": "query"}, "query": {"required": true, "type": "string", "location": "query"}, "as_of_time": {"type": "string", "location": "query"}}, "path": "mqlread", "id": "freebase.mqlread"}', true)); + $this->image = new ImageServiceResource($this, $this->serviceName, 'image', json_decode('{"httpMethod": "GET", "parameters": {"maxwidth": {"format": "uint32", "type": "integer", "location": "query", "maximum": "4096"}, "maxheight": {"format": "uint32", "type": "integer", "location": "query", "maximum": "4096"}, "fallbackid": {"default": "/freebase/no_image_png", "type": "string", "location": "query"}, "pad": {"default": "false", "type": "boolean", "location": "query"}, "mode": {"default": "fit", "enum": ["fill", "fillcrop", "fillcropmid", "fit"], "location": "query", "type": "string"}, "id": {"repeated": true, "required": true, "type": "string", "location": "path"}}, "path": "image{/id*}", "id": "freebase.image"}', true)); + } +} + +class ContentserviceGet extends apiModel { + public $result; + public function setResult($result) { + $this->result = $result; + } + public function getResult() { + return $this->result; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiGanService.php b/inc/vendors/social-login/Google/contrib/apiGanService.php new file mode 100755 index 00000000..60fefc70 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiGanService.php @@ -0,0 +1,1510 @@ + + * $ganService = new apiGanService(...); + * $advertisers = $ganService->advertisers; + * + */ + class AdvertisersServiceResource extends apiServiceResource { + + + /** + * Retrieves data about all advertisers that the requesting advertiser/publisher has access to. + * (advertisers.list) + * @param string $role The role of the requester. Valid values: 'advertisers' or 'publishers'. + * @param string $roleId The ID of the requesting advertiser or publisher. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string relationshipStatus Filters out all advertisers for which do not have the given relationship status with the requesting publisher. + * @opt_param double minSevenDayEpc Filters out all advertisers that have a seven day EPC average lower than the given value (inclusive). Min value: 0.0. Optional. + * @opt_param string advertiserCategory Caret(^) delimted list of advertiser categories. Valid categories are defined here: http://www.google.com/support/affiliatenetwork/advertiser/bin/answer.py?hl=en=107581. Filters out all advertisers not in one of the given advertiser categories. Optional. + * @opt_param double minNinetyDayEpc Filters out all advertisers that have a ninety day EPC average lower than the given value (inclusive). Min value: 0.0. Optional. + * @opt_param string pageToken The value of 'nextPageToken' from the previous page. Optional. + * @opt_param string maxResults Max number of items to return in this page. Optional. Defaults to 20. + * @opt_param int minPayoutRank A value between 1 and 4, where 1 represents the quartile of advertisers with the lowest ranks and 4 represents the quartile of advertisers with the highest ranks. Filters out all advertisers with a lower rank than the given quartile. For example if a 2 was given only advertisers with a payout rank of 25 or higher would be included. Optional. + * @return Advertisers + */ + public function listAdvertisers($role, $roleId, $optParams = array()) { + $params = array('role' => $role, 'roleId' => $roleId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Advertisers($data); + } else { + return $data; + } + } + /** + * Retrieves data about a single advertiser if that the requesting advertiser/publisher has access + * to it. Only publishers can lookup advertisers. Advertisers can request information about + * themselves by omitting the advertiserId query parameter. (advertisers.get) + * @param string $role The role of the requester. Valid values: 'advertisers' or 'publishers'. + * @param string $roleId The ID of the requesting advertiser or publisher. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string advertiserId The ID of the advertiser to look up. Optional. + * @return Advertiser + */ + public function get($role, $roleId, $optParams = array()) { + $params = array('role' => $role, 'roleId' => $roleId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Advertiser($data); + } else { + return $data; + } + } + } + + /** + * The "ccOffers" collection of methods. + * Typical usage is: + * + * $ganService = new apiGanService(...); + * $ccOffers = $ganService->ccOffers; + * + */ + class CcOffersServiceResource extends apiServiceResource { + + + /** + * Retrieves credit card offers for the given publisher. (ccOffers.list) + * @param string $publisher The ID of the publisher in question. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string advertiser The advertiser ID of a card issuer whose offers to include. Optional, may be repeated. + * @opt_param string projection The set of fields to return. + * @return CcOffers + */ + public function listCcOffers($publisher, $optParams = array()) { + $params = array('publisher' => $publisher); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CcOffers($data); + } else { + return $data; + } + } + } + + /** + * The "events" collection of methods. + * Typical usage is: + * + * $ganService = new apiGanService(...); + * $events = $ganService->events; + * + */ + class EventsServiceResource extends apiServiceResource { + + + /** + * Retrieves event data for a given advertiser/publisher. (events.list) + * @param string $role The role of the requester. Valid values: 'advertisers' or 'publishers'. + * @param string $roleId The ID of the requesting advertiser or publisher. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string orderId Caret(^) delimited list of order IDs. Filters out all events that do not reference one of the given order IDs. Optional. + * @opt_param string sku Caret(^) delimited list of SKUs. Filters out all events that do not reference one of the given SKU. Optional. + * @opt_param string eventDateMax Filters out all events later than given date. Optional. Defaults to 24 hours after eventMin. + * @opt_param string type Filters out all events that are not of the given type. Valid values: 'action', 'transaction', 'charge'. Optional. + * @opt_param string linkId Caret(^) delimited list of link IDs. Filters out all events that do not reference one of the given link IDs. Optional. + * @opt_param string status Filters out all events that do not have the given status. Valid values: 'active', 'canceled'. Optional. + * @opt_param string eventDateMin Filters out all events earlier than given date. Optional. Defaults to 24 hours from current date/time. + * @opt_param string memberId Caret(^) delimited list of member IDs. Filters out all events that do not reference one of the given member IDs. Optional. + * @opt_param string maxResults Max number of offers to return in this page. Optional. Defaults to 20. + * @opt_param string advertiserId Caret(^) delimited list of advertiser IDs. Filters out all events that do not reference one of the given advertiser IDs. Only used when under publishers role. Optional. + * @opt_param string pageToken The value of 'nextPageToken' from the previous page. Optional. + * @opt_param string productCategory Caret(^) delimited list of product categories. Filters out all events that do not reference a product in one of the given product categories. Optional. + * @opt_param string chargeType Filters out all charge events that are not of the given charge type. Valid values: 'other', 'slotting_fee', 'monthly_minimum', 'tier_bonus', 'credit', 'debit'. Optional. + * @opt_param string publisherId Caret(^) delimited list of publisher IDs. Filters out all events that do not reference one of the given publishers IDs. Only used when under advertiser role. Optional. + * @return Events + */ + public function listEvents($role, $roleId, $optParams = array()) { + $params = array('role' => $role, 'roleId' => $roleId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Events($data); + } else { + return $data; + } + } + } + + /** + * The "publishers" collection of methods. + * Typical usage is: + * + * $ganService = new apiGanService(...); + * $publishers = $ganService->publishers; + * + */ + class PublishersServiceResource extends apiServiceResource { + + + /** + * Retrieves data about all publishers that the requesting advertiser/publisher has access to. + * (publishers.list) + * @param string $role The role of the requester. Valid values: 'advertisers' or 'publishers'. + * @param string $roleId The ID of the requesting advertiser or publisher. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string publisherCategory Caret(^) delimted list of publisher categories. Valid categories: (unclassified|community_and_content|shopping_and_promotion|loyalty_and_rewards|network|search_specialist|comparison_shopping|email). Filters out all publishers not in one of the given advertiser categories. Optional. + * @opt_param string relationshipStatus Filters out all publishers for which do not have the given relationship status with the requesting publisher. + * @opt_param double minSevenDayEpc Filters out all publishers that have a seven day EPC average lower than the given value (inclusive). Min value 0.0. Optional. + * @opt_param double minNinetyDayEpc Filters out all publishers that have a ninety day EPC average lower than the given value (inclusive). Min value: 0.0. Optional. + * @opt_param string pageToken The value of 'nextPageToken' from the previous page. Optional. + * @opt_param string maxResults Max number of items to return in this page. Optional. Defaults to 20. + * @opt_param int minPayoutRank A value between 1 and 4, where 1 represents the quartile of publishers with the lowest ranks and 4 represents the quartile of publishers with the highest ranks. Filters out all publishers with a lower rank than the given quartile. For example if a 2 was given only publishers with a payout rank of 25 or higher would be included. Optional. + * @return Publishers + */ + public function listPublishers($role, $roleId, $optParams = array()) { + $params = array('role' => $role, 'roleId' => $roleId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Publishers($data); + } else { + return $data; + } + } + /** + * Retrieves data about a single advertiser if that the requesting advertiser/publisher has access + * to it. Only advertisers can look up publishers. Publishers can request information about + * themselves by omitting the publisherId query parameter. (publishers.get) + * @param string $role The role of the requester. Valid values: 'advertisers' or 'publishers'. + * @param string $roleId The ID of the requesting advertiser or publisher. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string publisherId The ID of the publisher to look up. Optional. + * @return Publisher + */ + public function get($role, $roleId, $optParams = array()) { + $params = array('role' => $role, 'roleId' => $roleId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Publisher($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Gan (v1beta1). + *

            + * Lets you have programmatic access to your Google Affiliate Network data + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiGanService extends apiService { + public $advertisers; + public $ccOffers; + public $events; + public $publishers; + /** + * Constructs the internal representation of the Gan service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/gan/v1beta1/'; + $this->version = 'v1beta1'; + $this->serviceName = 'gan'; + + $apiClient->addService($this->serviceName, $this->version); + $this->advertisers = new AdvertisersServiceResource($this, $this->serviceName, 'advertisers', json_decode('{"methods": {"list": {"parameters": {"relationshipStatus": {"enum": ["approved", "available", "deactivated", "declined", "pending"], "type": "string", "location": "query"}, "minSevenDayEpc": {"format": "double", "type": "number", "location": "query"}, "advertiserCategory": {"type": "string", "location": "query"}, "minNinetyDayEpc": {"format": "double", "type": "number", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "role": {"required": true, "enum": ["advertisers", "publishers"], "location": "path", "type": "string"}, "maxResults": {"format": "uint32", "maximum": "100", "minimum": "0", "location": "query", "type": "integer"}, "roleId": {"required": true, "type": "string", "location": "path"}, "minPayoutRank": {"format": "int32", "maximum": "4", "minimum": "1", "location": "query", "type": "integer"}}, "id": "gan.advertisers.list", "httpMethod": "GET", "path": "{role}/{roleId}/advertisers", "response": {"$ref": "Advertisers"}}, "get": {"parameters": {"advertiserId": {"type": "string", "location": "query"}, "roleId": {"required": true, "type": "string", "location": "path"}, "role": {"required": true, "enum": ["advertisers", "publishers"], "location": "path", "type": "string"}}, "id": "gan.advertisers.get", "httpMethod": "GET", "path": "{role}/{roleId}/advertiser", "response": {"$ref": "Advertiser"}}}}', true)); + $this->ccOffers = new CcOffersServiceResource($this, $this->serviceName, 'ccOffers', json_decode('{"methods": {"list": {"parameters": {"advertiser": {"repeated": true, "type": "string", "location": "query"}, "projection": {"enum": ["full", "summary"], "type": "string", "location": "query"}, "publisher": {"required": true, "type": "string", "location": "path"}}, "id": "gan.ccOffers.list", "httpMethod": "GET", "path": "publishers/{publisher}/ccOffers", "response": {"$ref": "CcOffers"}}}}', true)); + $this->events = new EventsServiceResource($this, $this->serviceName, 'events', json_decode('{"methods": {"list": {"parameters": {"orderId": {"type": "string", "location": "query"}, "sku": {"type": "string", "location": "query"}, "eventDateMax": {"type": "string", "location": "query"}, "linkId": {"type": "string", "location": "query"}, "eventDateMin": {"type": "string", "location": "query"}, "memberId": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "maximum": "100", "minimum": "0", "location": "query", "type": "integer"}, "advertiserId": {"type": "string", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "publisherId": {"type": "string", "location": "query"}, "status": {"enum": ["active", "canceled"], "type": "string", "location": "query"}, "productCategory": {"type": "string", "location": "query"}, "chargeType": {"enum": ["credit", "debit", "monthly_minimum", "other", "slotting_fee", "tier_bonus"], "type": "string", "location": "query"}, "roleId": {"required": true, "type": "string", "location": "path"}, "role": {"required": true, "enum": ["advertisers", "publishers"], "location": "path", "type": "string"}, "type": {"enum": ["action", "charge", "transaction"], "type": "string", "location": "query"}}, "id": "gan.events.list", "httpMethod": "GET", "path": "{role}/{roleId}/events", "response": {"$ref": "Events"}}}}', true)); + $this->publishers = new PublishersServiceResource($this, $this->serviceName, 'publishers', json_decode('{"methods": {"list": {"parameters": {"publisherCategory": {"type": "string", "location": "query"}, "relationshipStatus": {"enum": ["approved", "available", "deactivated", "declined", "pending"], "type": "string", "location": "query"}, "minSevenDayEpc": {"format": "double", "type": "number", "location": "query"}, "minNinetyDayEpc": {"format": "double", "type": "number", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "role": {"required": true, "enum": ["advertisers", "publishers"], "location": "path", "type": "string"}, "maxResults": {"format": "uint32", "maximum": "100", "minimum": "0", "location": "query", "type": "integer"}, "roleId": {"required": true, "type": "string", "location": "path"}, "minPayoutRank": {"format": "int32", "maximum": "4", "minimum": "1", "location": "query", "type": "integer"}}, "id": "gan.publishers.list", "httpMethod": "GET", "path": "{role}/{roleId}/publishers", "response": {"$ref": "Publishers"}}, "get": {"parameters": {"publisherId": {"type": "string", "location": "query"}, "role": {"required": true, "enum": ["advertisers", "publishers"], "location": "path", "type": "string"}, "roleId": {"required": true, "type": "string", "location": "path"}}, "id": "gan.publishers.get", "httpMethod": "GET", "path": "{role}/{roleId}/publisher", "response": {"$ref": "Publisher"}}}}', true)); + } +} + +class Advertiser extends apiModel { + public $category; + public $productFeedsEnabled; + public $kind; + public $siteUrl; + public $contactPhone; + public $description; + public $payoutRank; + protected $__epcSevenDayAverageType = 'Money'; + protected $__epcSevenDayAverageDataType = ''; + public $epcSevenDayAverage; + public $commissionDuration; + public $status; + protected $__epcNinetyDayAverageType = 'Money'; + protected $__epcNinetyDayAverageDataType = ''; + public $epcNinetyDayAverage; + public $contactEmail; + protected $__itemType = 'Advertiser'; + protected $__itemDataType = ''; + public $item; + public $joinDate; + public $logoUrl; + public $id; + public $name; + public function setCategory($category) { + $this->category = $category; + } + public function getCategory() { + return $this->category; + } + public function setProductFeedsEnabled($productFeedsEnabled) { + $this->productFeedsEnabled = $productFeedsEnabled; + } + public function getProductFeedsEnabled() { + return $this->productFeedsEnabled; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setSiteUrl($siteUrl) { + $this->siteUrl = $siteUrl; + } + public function getSiteUrl() { + return $this->siteUrl; + } + public function setContactPhone($contactPhone) { + $this->contactPhone = $contactPhone; + } + public function getContactPhone() { + return $this->contactPhone; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setPayoutRank($payoutRank) { + $this->payoutRank = $payoutRank; + } + public function getPayoutRank() { + return $this->payoutRank; + } + public function setEpcSevenDayAverage(Money $epcSevenDayAverage) { + $this->epcSevenDayAverage = $epcSevenDayAverage; + } + public function getEpcSevenDayAverage() { + return $this->epcSevenDayAverage; + } + public function setCommissionDuration($commissionDuration) { + $this->commissionDuration = $commissionDuration; + } + public function getCommissionDuration() { + return $this->commissionDuration; + } + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setEpcNinetyDayAverage(Money $epcNinetyDayAverage) { + $this->epcNinetyDayAverage = $epcNinetyDayAverage; + } + public function getEpcNinetyDayAverage() { + return $this->epcNinetyDayAverage; + } + public function setContactEmail($contactEmail) { + $this->contactEmail = $contactEmail; + } + public function getContactEmail() { + return $this->contactEmail; + } + public function setItem(Advertiser $item) { + $this->item = $item; + } + public function getItem() { + return $this->item; + } + public function setJoinDate($joinDate) { + $this->joinDate = $joinDate; + } + public function getJoinDate() { + return $this->joinDate; + } + public function setLogoUrl($logoUrl) { + $this->logoUrl = $logoUrl; + } + public function getLogoUrl() { + return $this->logoUrl; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class Advertisers extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Advertiser'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Advertiser) */ $items) { + $this->assertIsArray($items, 'Advertiser', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class CcOffer extends apiModel { + public $rewardsHaveBlackoutDates; + public $introPurchasePeriodLength; + public $introBalanceTransferRate; + public $cardBenefits; + public $introBalanceTransferAprDisplay; + public $issuer; + public $introBalanceTransferFeeRate; + public $cashAdvanceFeeDisplay; + public $annualFeeDisplay; + public $minimumFinanceCharge; + public $balanceTransferFeeDisplay; + public $landingPageUrl; + public $introPurchaseRate; + public $cashAdvanceAprDisplay; + public $maxCashAdvanceRate; + public $firstYearAnnualFee; + public $introBalanceTransferPeriodUnits; + public $variableRatesUpdateFrequency; + public $overLimitFee; + public $rewardsExpire; + public $additionalCardBenefits; + public $ageMinimum; + public $balanceTransferAprDisplay; + public $introBalanceTransferPeriodLength; + public $network; + public $introPurchaseRateType; + public $introAprDisplay; + public $flightAccidentInsurance; + public $annualRewardMaximum; + public $disclaimer; + public $creditLimitMin; + public $creditLimitMax; + public $gracePeriodDisplay; + public $cashAdvanceFeeAmount; + public $travelInsurance; + public $existingCustomerOnly; + public $initialSetupAndProcessingFee; + public $issuerId; + public $rewardUnit; + public $prohibitedCategories; + protected $__defaultFeesType = 'CcOfferDefaultFees'; + protected $__defaultFeesDataType = 'array'; + public $defaultFees; + public $introPurchasePeriodUnits; + public $trackingUrl; + public $latePaymentFee; + public $statementCopyFee; + public $variableRatesLastUpdated; + public $minBalanceTransferRate; + public $emergencyInsurance; + public $introPurchasePeriodEndDate; + public $cardName; + public $returnedPaymentFee; + public $cashAdvanceAdditionalDetails; + public $cashAdvanceLimit; + public $balanceTransferFeeRate; + public $balanceTransferRateType; + protected $__rewardsType = 'CcOfferRewards'; + protected $__rewardsDataType = 'array'; + public $rewards; + public $extendedWarranty; + public $carRentalInsurance; + public $cashAdvanceFeeRate; + public $rewardPartner; + public $foreignCurrencyTransactionFee; + public $kind; + public $introBalanceTransferFeeAmount; + public $creditRatingDisplay; + public $additionalCardHolderFee; + public $purchaseRateType; + public $cashAdvanceRateType; + protected $__bonusRewardsType = 'CcOfferBonusRewards'; + protected $__bonusRewardsDataType = 'array'; + public $bonusRewards; + public $balanceTransferLimit; + public $luggageInsurance; + public $minCashAdvanceRate; + public $offerId; + public $minPurchaseRate; + public $offersImmediateCashReward; + public $fraudLiability; + public $cardType; + public $approvedCategories; + public $annualFee; + public $maxBalanceTransferRate; + public $maxPurchaseRate; + public $issuerWebsite; + public $introBalanceTransferRateType; + public $aprDisplay; + public $imageUrl; + public $ageMinimumDetails; + public $balanceTransferFeeAmount; + public $introBalanceTransferPeriodEndDate; + public function setRewardsHaveBlackoutDates($rewardsHaveBlackoutDates) { + $this->rewardsHaveBlackoutDates = $rewardsHaveBlackoutDates; + } + public function getRewardsHaveBlackoutDates() { + return $this->rewardsHaveBlackoutDates; + } + public function setIntroPurchasePeriodLength($introPurchasePeriodLength) { + $this->introPurchasePeriodLength = $introPurchasePeriodLength; + } + public function getIntroPurchasePeriodLength() { + return $this->introPurchasePeriodLength; + } + public function setIntroBalanceTransferRate($introBalanceTransferRate) { + $this->introBalanceTransferRate = $introBalanceTransferRate; + } + public function getIntroBalanceTransferRate() { + return $this->introBalanceTransferRate; + } + public function setCardBenefits(/* array(string) */ $cardBenefits) { + $this->assertIsArray($cardBenefits, 'string', __METHOD__); + $this->cardBenefits = $cardBenefits; + } + public function getCardBenefits() { + return $this->cardBenefits; + } + public function setIntroBalanceTransferAprDisplay($introBalanceTransferAprDisplay) { + $this->introBalanceTransferAprDisplay = $introBalanceTransferAprDisplay; + } + public function getIntroBalanceTransferAprDisplay() { + return $this->introBalanceTransferAprDisplay; + } + public function setIssuer($issuer) { + $this->issuer = $issuer; + } + public function getIssuer() { + return $this->issuer; + } + public function setIntroBalanceTransferFeeRate($introBalanceTransferFeeRate) { + $this->introBalanceTransferFeeRate = $introBalanceTransferFeeRate; + } + public function getIntroBalanceTransferFeeRate() { + return $this->introBalanceTransferFeeRate; + } + public function setCashAdvanceFeeDisplay($cashAdvanceFeeDisplay) { + $this->cashAdvanceFeeDisplay = $cashAdvanceFeeDisplay; + } + public function getCashAdvanceFeeDisplay() { + return $this->cashAdvanceFeeDisplay; + } + public function setAnnualFeeDisplay($annualFeeDisplay) { + $this->annualFeeDisplay = $annualFeeDisplay; + } + public function getAnnualFeeDisplay() { + return $this->annualFeeDisplay; + } + public function setMinimumFinanceCharge($minimumFinanceCharge) { + $this->minimumFinanceCharge = $minimumFinanceCharge; + } + public function getMinimumFinanceCharge() { + return $this->minimumFinanceCharge; + } + public function setBalanceTransferFeeDisplay($balanceTransferFeeDisplay) { + $this->balanceTransferFeeDisplay = $balanceTransferFeeDisplay; + } + public function getBalanceTransferFeeDisplay() { + return $this->balanceTransferFeeDisplay; + } + public function setLandingPageUrl($landingPageUrl) { + $this->landingPageUrl = $landingPageUrl; + } + public function getLandingPageUrl() { + return $this->landingPageUrl; + } + public function setIntroPurchaseRate($introPurchaseRate) { + $this->introPurchaseRate = $introPurchaseRate; + } + public function getIntroPurchaseRate() { + return $this->introPurchaseRate; + } + public function setCashAdvanceAprDisplay($cashAdvanceAprDisplay) { + $this->cashAdvanceAprDisplay = $cashAdvanceAprDisplay; + } + public function getCashAdvanceAprDisplay() { + return $this->cashAdvanceAprDisplay; + } + public function setMaxCashAdvanceRate($maxCashAdvanceRate) { + $this->maxCashAdvanceRate = $maxCashAdvanceRate; + } + public function getMaxCashAdvanceRate() { + return $this->maxCashAdvanceRate; + } + public function setFirstYearAnnualFee($firstYearAnnualFee) { + $this->firstYearAnnualFee = $firstYearAnnualFee; + } + public function getFirstYearAnnualFee() { + return $this->firstYearAnnualFee; + } + public function setIntroBalanceTransferPeriodUnits($introBalanceTransferPeriodUnits) { + $this->introBalanceTransferPeriodUnits = $introBalanceTransferPeriodUnits; + } + public function getIntroBalanceTransferPeriodUnits() { + return $this->introBalanceTransferPeriodUnits; + } + public function setVariableRatesUpdateFrequency($variableRatesUpdateFrequency) { + $this->variableRatesUpdateFrequency = $variableRatesUpdateFrequency; + } + public function getVariableRatesUpdateFrequency() { + return $this->variableRatesUpdateFrequency; + } + public function setOverLimitFee($overLimitFee) { + $this->overLimitFee = $overLimitFee; + } + public function getOverLimitFee() { + return $this->overLimitFee; + } + public function setRewardsExpire($rewardsExpire) { + $this->rewardsExpire = $rewardsExpire; + } + public function getRewardsExpire() { + return $this->rewardsExpire; + } + public function setAdditionalCardBenefits(/* array(string) */ $additionalCardBenefits) { + $this->assertIsArray($additionalCardBenefits, 'string', __METHOD__); + $this->additionalCardBenefits = $additionalCardBenefits; + } + public function getAdditionalCardBenefits() { + return $this->additionalCardBenefits; + } + public function setAgeMinimum($ageMinimum) { + $this->ageMinimum = $ageMinimum; + } + public function getAgeMinimum() { + return $this->ageMinimum; + } + public function setBalanceTransferAprDisplay($balanceTransferAprDisplay) { + $this->balanceTransferAprDisplay = $balanceTransferAprDisplay; + } + public function getBalanceTransferAprDisplay() { + return $this->balanceTransferAprDisplay; + } + public function setIntroBalanceTransferPeriodLength($introBalanceTransferPeriodLength) { + $this->introBalanceTransferPeriodLength = $introBalanceTransferPeriodLength; + } + public function getIntroBalanceTransferPeriodLength() { + return $this->introBalanceTransferPeriodLength; + } + public function setNetwork($network) { + $this->network = $network; + } + public function getNetwork() { + return $this->network; + } + public function setIntroPurchaseRateType($introPurchaseRateType) { + $this->introPurchaseRateType = $introPurchaseRateType; + } + public function getIntroPurchaseRateType() { + return $this->introPurchaseRateType; + } + public function setIntroAprDisplay($introAprDisplay) { + $this->introAprDisplay = $introAprDisplay; + } + public function getIntroAprDisplay() { + return $this->introAprDisplay; + } + public function setFlightAccidentInsurance($flightAccidentInsurance) { + $this->flightAccidentInsurance = $flightAccidentInsurance; + } + public function getFlightAccidentInsurance() { + return $this->flightAccidentInsurance; + } + public function setAnnualRewardMaximum($annualRewardMaximum) { + $this->annualRewardMaximum = $annualRewardMaximum; + } + public function getAnnualRewardMaximum() { + return $this->annualRewardMaximum; + } + public function setDisclaimer($disclaimer) { + $this->disclaimer = $disclaimer; + } + public function getDisclaimer() { + return $this->disclaimer; + } + public function setCreditLimitMin($creditLimitMin) { + $this->creditLimitMin = $creditLimitMin; + } + public function getCreditLimitMin() { + return $this->creditLimitMin; + } + public function setCreditLimitMax($creditLimitMax) { + $this->creditLimitMax = $creditLimitMax; + } + public function getCreditLimitMax() { + return $this->creditLimitMax; + } + public function setGracePeriodDisplay($gracePeriodDisplay) { + $this->gracePeriodDisplay = $gracePeriodDisplay; + } + public function getGracePeriodDisplay() { + return $this->gracePeriodDisplay; + } + public function setCashAdvanceFeeAmount($cashAdvanceFeeAmount) { + $this->cashAdvanceFeeAmount = $cashAdvanceFeeAmount; + } + public function getCashAdvanceFeeAmount() { + return $this->cashAdvanceFeeAmount; + } + public function setTravelInsurance($travelInsurance) { + $this->travelInsurance = $travelInsurance; + } + public function getTravelInsurance() { + return $this->travelInsurance; + } + public function setExistingCustomerOnly($existingCustomerOnly) { + $this->existingCustomerOnly = $existingCustomerOnly; + } + public function getExistingCustomerOnly() { + return $this->existingCustomerOnly; + } + public function setInitialSetupAndProcessingFee($initialSetupAndProcessingFee) { + $this->initialSetupAndProcessingFee = $initialSetupAndProcessingFee; + } + public function getInitialSetupAndProcessingFee() { + return $this->initialSetupAndProcessingFee; + } + public function setIssuerId($issuerId) { + $this->issuerId = $issuerId; + } + public function getIssuerId() { + return $this->issuerId; + } + public function setRewardUnit($rewardUnit) { + $this->rewardUnit = $rewardUnit; + } + public function getRewardUnit() { + return $this->rewardUnit; + } + public function setProhibitedCategories(/* array(string) */ $prohibitedCategories) { + $this->assertIsArray($prohibitedCategories, 'string', __METHOD__); + $this->prohibitedCategories = $prohibitedCategories; + } + public function getProhibitedCategories() { + return $this->prohibitedCategories; + } + public function setDefaultFees(/* array(CcOfferDefaultFees) */ $defaultFees) { + $this->assertIsArray($defaultFees, 'CcOfferDefaultFees', __METHOD__); + $this->defaultFees = $defaultFees; + } + public function getDefaultFees() { + return $this->defaultFees; + } + public function setIntroPurchasePeriodUnits($introPurchasePeriodUnits) { + $this->introPurchasePeriodUnits = $introPurchasePeriodUnits; + } + public function getIntroPurchasePeriodUnits() { + return $this->introPurchasePeriodUnits; + } + public function setTrackingUrl($trackingUrl) { + $this->trackingUrl = $trackingUrl; + } + public function getTrackingUrl() { + return $this->trackingUrl; + } + public function setLatePaymentFee($latePaymentFee) { + $this->latePaymentFee = $latePaymentFee; + } + public function getLatePaymentFee() { + return $this->latePaymentFee; + } + public function setStatementCopyFee($statementCopyFee) { + $this->statementCopyFee = $statementCopyFee; + } + public function getStatementCopyFee() { + return $this->statementCopyFee; + } + public function setVariableRatesLastUpdated($variableRatesLastUpdated) { + $this->variableRatesLastUpdated = $variableRatesLastUpdated; + } + public function getVariableRatesLastUpdated() { + return $this->variableRatesLastUpdated; + } + public function setMinBalanceTransferRate($minBalanceTransferRate) { + $this->minBalanceTransferRate = $minBalanceTransferRate; + } + public function getMinBalanceTransferRate() { + return $this->minBalanceTransferRate; + } + public function setEmergencyInsurance($emergencyInsurance) { + $this->emergencyInsurance = $emergencyInsurance; + } + public function getEmergencyInsurance() { + return $this->emergencyInsurance; + } + public function setIntroPurchasePeriodEndDate($introPurchasePeriodEndDate) { + $this->introPurchasePeriodEndDate = $introPurchasePeriodEndDate; + } + public function getIntroPurchasePeriodEndDate() { + return $this->introPurchasePeriodEndDate; + } + public function setCardName($cardName) { + $this->cardName = $cardName; + } + public function getCardName() { + return $this->cardName; + } + public function setReturnedPaymentFee($returnedPaymentFee) { + $this->returnedPaymentFee = $returnedPaymentFee; + } + public function getReturnedPaymentFee() { + return $this->returnedPaymentFee; + } + public function setCashAdvanceAdditionalDetails($cashAdvanceAdditionalDetails) { + $this->cashAdvanceAdditionalDetails = $cashAdvanceAdditionalDetails; + } + public function getCashAdvanceAdditionalDetails() { + return $this->cashAdvanceAdditionalDetails; + } + public function setCashAdvanceLimit($cashAdvanceLimit) { + $this->cashAdvanceLimit = $cashAdvanceLimit; + } + public function getCashAdvanceLimit() { + return $this->cashAdvanceLimit; + } + public function setBalanceTransferFeeRate($balanceTransferFeeRate) { + $this->balanceTransferFeeRate = $balanceTransferFeeRate; + } + public function getBalanceTransferFeeRate() { + return $this->balanceTransferFeeRate; + } + public function setBalanceTransferRateType($balanceTransferRateType) { + $this->balanceTransferRateType = $balanceTransferRateType; + } + public function getBalanceTransferRateType() { + return $this->balanceTransferRateType; + } + public function setRewards(/* array(CcOfferRewards) */ $rewards) { + $this->assertIsArray($rewards, 'CcOfferRewards', __METHOD__); + $this->rewards = $rewards; + } + public function getRewards() { + return $this->rewards; + } + public function setExtendedWarranty($extendedWarranty) { + $this->extendedWarranty = $extendedWarranty; + } + public function getExtendedWarranty() { + return $this->extendedWarranty; + } + public function setCarRentalInsurance($carRentalInsurance) { + $this->carRentalInsurance = $carRentalInsurance; + } + public function getCarRentalInsurance() { + return $this->carRentalInsurance; + } + public function setCashAdvanceFeeRate($cashAdvanceFeeRate) { + $this->cashAdvanceFeeRate = $cashAdvanceFeeRate; + } + public function getCashAdvanceFeeRate() { + return $this->cashAdvanceFeeRate; + } + public function setRewardPartner($rewardPartner) { + $this->rewardPartner = $rewardPartner; + } + public function getRewardPartner() { + return $this->rewardPartner; + } + public function setForeignCurrencyTransactionFee($foreignCurrencyTransactionFee) { + $this->foreignCurrencyTransactionFee = $foreignCurrencyTransactionFee; + } + public function getForeignCurrencyTransactionFee() { + return $this->foreignCurrencyTransactionFee; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setIntroBalanceTransferFeeAmount($introBalanceTransferFeeAmount) { + $this->introBalanceTransferFeeAmount = $introBalanceTransferFeeAmount; + } + public function getIntroBalanceTransferFeeAmount() { + return $this->introBalanceTransferFeeAmount; + } + public function setCreditRatingDisplay($creditRatingDisplay) { + $this->creditRatingDisplay = $creditRatingDisplay; + } + public function getCreditRatingDisplay() { + return $this->creditRatingDisplay; + } + public function setAdditionalCardHolderFee($additionalCardHolderFee) { + $this->additionalCardHolderFee = $additionalCardHolderFee; + } + public function getAdditionalCardHolderFee() { + return $this->additionalCardHolderFee; + } + public function setPurchaseRateType($purchaseRateType) { + $this->purchaseRateType = $purchaseRateType; + } + public function getPurchaseRateType() { + return $this->purchaseRateType; + } + public function setCashAdvanceRateType($cashAdvanceRateType) { + $this->cashAdvanceRateType = $cashAdvanceRateType; + } + public function getCashAdvanceRateType() { + return $this->cashAdvanceRateType; + } + public function setBonusRewards(/* array(CcOfferBonusRewards) */ $bonusRewards) { + $this->assertIsArray($bonusRewards, 'CcOfferBonusRewards', __METHOD__); + $this->bonusRewards = $bonusRewards; + } + public function getBonusRewards() { + return $this->bonusRewards; + } + public function setBalanceTransferLimit($balanceTransferLimit) { + $this->balanceTransferLimit = $balanceTransferLimit; + } + public function getBalanceTransferLimit() { + return $this->balanceTransferLimit; + } + public function setLuggageInsurance($luggageInsurance) { + $this->luggageInsurance = $luggageInsurance; + } + public function getLuggageInsurance() { + return $this->luggageInsurance; + } + public function setMinCashAdvanceRate($minCashAdvanceRate) { + $this->minCashAdvanceRate = $minCashAdvanceRate; + } + public function getMinCashAdvanceRate() { + return $this->minCashAdvanceRate; + } + public function setOfferId($offerId) { + $this->offerId = $offerId; + } + public function getOfferId() { + return $this->offerId; + } + public function setMinPurchaseRate($minPurchaseRate) { + $this->minPurchaseRate = $minPurchaseRate; + } + public function getMinPurchaseRate() { + return $this->minPurchaseRate; + } + public function setOffersImmediateCashReward($offersImmediateCashReward) { + $this->offersImmediateCashReward = $offersImmediateCashReward; + } + public function getOffersImmediateCashReward() { + return $this->offersImmediateCashReward; + } + public function setFraudLiability($fraudLiability) { + $this->fraudLiability = $fraudLiability; + } + public function getFraudLiability() { + return $this->fraudLiability; + } + public function setCardType($cardType) { + $this->cardType = $cardType; + } + public function getCardType() { + return $this->cardType; + } + public function setApprovedCategories(/* array(string) */ $approvedCategories) { + $this->assertIsArray($approvedCategories, 'string', __METHOD__); + $this->approvedCategories = $approvedCategories; + } + public function getApprovedCategories() { + return $this->approvedCategories; + } + public function setAnnualFee($annualFee) { + $this->annualFee = $annualFee; + } + public function getAnnualFee() { + return $this->annualFee; + } + public function setMaxBalanceTransferRate($maxBalanceTransferRate) { + $this->maxBalanceTransferRate = $maxBalanceTransferRate; + } + public function getMaxBalanceTransferRate() { + return $this->maxBalanceTransferRate; + } + public function setMaxPurchaseRate($maxPurchaseRate) { + $this->maxPurchaseRate = $maxPurchaseRate; + } + public function getMaxPurchaseRate() { + return $this->maxPurchaseRate; + } + public function setIssuerWebsite($issuerWebsite) { + $this->issuerWebsite = $issuerWebsite; + } + public function getIssuerWebsite() { + return $this->issuerWebsite; + } + public function setIntroBalanceTransferRateType($introBalanceTransferRateType) { + $this->introBalanceTransferRateType = $introBalanceTransferRateType; + } + public function getIntroBalanceTransferRateType() { + return $this->introBalanceTransferRateType; + } + public function setAprDisplay($aprDisplay) { + $this->aprDisplay = $aprDisplay; + } + public function getAprDisplay() { + return $this->aprDisplay; + } + public function setImageUrl($imageUrl) { + $this->imageUrl = $imageUrl; + } + public function getImageUrl() { + return $this->imageUrl; + } + public function setAgeMinimumDetails($ageMinimumDetails) { + $this->ageMinimumDetails = $ageMinimumDetails; + } + public function getAgeMinimumDetails() { + return $this->ageMinimumDetails; + } + public function setBalanceTransferFeeAmount($balanceTransferFeeAmount) { + $this->balanceTransferFeeAmount = $balanceTransferFeeAmount; + } + public function getBalanceTransferFeeAmount() { + return $this->balanceTransferFeeAmount; + } + public function setIntroBalanceTransferPeriodEndDate($introBalanceTransferPeriodEndDate) { + $this->introBalanceTransferPeriodEndDate = $introBalanceTransferPeriodEndDate; + } + public function getIntroBalanceTransferPeriodEndDate() { + return $this->introBalanceTransferPeriodEndDate; + } +} + +class CcOfferBonusRewards extends apiModel { + public $amount; + public $details; + public function setAmount($amount) { + $this->amount = $amount; + } + public function getAmount() { + return $this->amount; + } + public function setDetails($details) { + $this->details = $details; + } + public function getDetails() { + return $this->details; + } +} + +class CcOfferDefaultFees extends apiModel { + public $category; + public $maxRate; + public $minRate; + public $rateType; + public function setCategory($category) { + $this->category = $category; + } + public function getCategory() { + return $this->category; + } + public function setMaxRate($maxRate) { + $this->maxRate = $maxRate; + } + public function getMaxRate() { + return $this->maxRate; + } + public function setMinRate($minRate) { + $this->minRate = $minRate; + } + public function getMinRate() { + return $this->minRate; + } + public function setRateType($rateType) { + $this->rateType = $rateType; + } + public function getRateType() { + return $this->rateType; + } +} + +class CcOfferRewards extends apiModel { + public $category; + public $minRewardTier; + public $maxRewardTier; + public $expirationMonths; + public $amount; + public $additionalDetails; + public function setCategory($category) { + $this->category = $category; + } + public function getCategory() { + return $this->category; + } + public function setMinRewardTier($minRewardTier) { + $this->minRewardTier = $minRewardTier; + } + public function getMinRewardTier() { + return $this->minRewardTier; + } + public function setMaxRewardTier($maxRewardTier) { + $this->maxRewardTier = $maxRewardTier; + } + public function getMaxRewardTier() { + return $this->maxRewardTier; + } + public function setExpirationMonths($expirationMonths) { + $this->expirationMonths = $expirationMonths; + } + public function getExpirationMonths() { + return $this->expirationMonths; + } + public function setAmount($amount) { + $this->amount = $amount; + } + public function getAmount() { + return $this->amount; + } + public function setAdditionalDetails($additionalDetails) { + $this->additionalDetails = $additionalDetails; + } + public function getAdditionalDetails() { + return $this->additionalDetails; + } +} + +class CcOffers extends apiModel { + protected $__itemsType = 'CcOffer'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(CcOffer) */ $items) { + $this->assertIsArray($items, 'CcOffer', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class Event extends apiModel { + protected $__networkFeeType = 'Money'; + protected $__networkFeeDataType = ''; + public $networkFee; + public $advertiserName; + public $kind; + public $modifyDate; + public $type; + public $orderId; + public $publisherName; + public $memberId; + public $advertiserId; + public $status; + public $chargeId; + protected $__productsType = 'EventProducts'; + protected $__productsDataType = 'array'; + public $products; + protected $__earningsType = 'Money'; + protected $__earningsDataType = ''; + public $earnings; + public $chargeType; + protected $__publisherFeeType = 'Money'; + protected $__publisherFeeDataType = ''; + public $publisherFee; + protected $__commissionableSalesType = 'Money'; + protected $__commissionableSalesDataType = ''; + public $commissionableSales; + public $publisherId; + public $eventDate; + public function setNetworkFee(Money $networkFee) { + $this->networkFee = $networkFee; + } + public function getNetworkFee() { + return $this->networkFee; + } + public function setAdvertiserName($advertiserName) { + $this->advertiserName = $advertiserName; + } + public function getAdvertiserName() { + return $this->advertiserName; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setModifyDate($modifyDate) { + $this->modifyDate = $modifyDate; + } + public function getModifyDate() { + return $this->modifyDate; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setOrderId($orderId) { + $this->orderId = $orderId; + } + public function getOrderId() { + return $this->orderId; + } + public function setPublisherName($publisherName) { + $this->publisherName = $publisherName; + } + public function getPublisherName() { + return $this->publisherName; + } + public function setMemberId($memberId) { + $this->memberId = $memberId; + } + public function getMemberId() { + return $this->memberId; + } + public function setAdvertiserId($advertiserId) { + $this->advertiserId = $advertiserId; + } + public function getAdvertiserId() { + return $this->advertiserId; + } + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setChargeId($chargeId) { + $this->chargeId = $chargeId; + } + public function getChargeId() { + return $this->chargeId; + } + public function setProducts(/* array(EventProducts) */ $products) { + $this->assertIsArray($products, 'EventProducts', __METHOD__); + $this->products = $products; + } + public function getProducts() { + return $this->products; + } + public function setEarnings(Money $earnings) { + $this->earnings = $earnings; + } + public function getEarnings() { + return $this->earnings; + } + public function setChargeType($chargeType) { + $this->chargeType = $chargeType; + } + public function getChargeType() { + return $this->chargeType; + } + public function setPublisherFee(Money $publisherFee) { + $this->publisherFee = $publisherFee; + } + public function getPublisherFee() { + return $this->publisherFee; + } + public function setCommissionableSales(Money $commissionableSales) { + $this->commissionableSales = $commissionableSales; + } + public function getCommissionableSales() { + return $this->commissionableSales; + } + public function setPublisherId($publisherId) { + $this->publisherId = $publisherId; + } + public function getPublisherId() { + return $this->publisherId; + } + public function setEventDate($eventDate) { + $this->eventDate = $eventDate; + } + public function getEventDate() { + return $this->eventDate; + } +} + +class EventProducts extends apiModel { + protected $__networkFeeType = 'Money'; + protected $__networkFeeDataType = ''; + public $networkFee; + public $sku; + public $categoryName; + public $skuName; + protected $__publisherFeeType = 'Money'; + protected $__publisherFeeDataType = ''; + public $publisherFee; + protected $__earningsType = 'Money'; + protected $__earningsDataType = ''; + public $earnings; + protected $__unitPriceType = 'Money'; + protected $__unitPriceDataType = ''; + public $unitPrice; + public $categoryId; + public $quantity; + public function setNetworkFee(Money $networkFee) { + $this->networkFee = $networkFee; + } + public function getNetworkFee() { + return $this->networkFee; + } + public function setSku($sku) { + $this->sku = $sku; + } + public function getSku() { + return $this->sku; + } + public function setCategoryName($categoryName) { + $this->categoryName = $categoryName; + } + public function getCategoryName() { + return $this->categoryName; + } + public function setSkuName($skuName) { + $this->skuName = $skuName; + } + public function getSkuName() { + return $this->skuName; + } + public function setPublisherFee(Money $publisherFee) { + $this->publisherFee = $publisherFee; + } + public function getPublisherFee() { + return $this->publisherFee; + } + public function setEarnings(Money $earnings) { + $this->earnings = $earnings; + } + public function getEarnings() { + return $this->earnings; + } + public function setUnitPrice(Money $unitPrice) { + $this->unitPrice = $unitPrice; + } + public function getUnitPrice() { + return $this->unitPrice; + } + public function setCategoryId($categoryId) { + $this->categoryId = $categoryId; + } + public function getCategoryId() { + return $this->categoryId; + } + public function setQuantity($quantity) { + $this->quantity = $quantity; + } + public function getQuantity() { + return $this->quantity; + } +} + +class Events extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Event'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Event) */ $items) { + $this->assertIsArray($items, 'Event', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class Money extends apiModel { + public $amount; + public $currencyCode; + public function setAmount($amount) { + $this->amount = $amount; + } + public function getAmount() { + return $this->amount; + } + public function setCurrencyCode($currencyCode) { + $this->currencyCode = $currencyCode; + } + public function getCurrencyCode() { + return $this->currencyCode; + } +} + +class Publisher extends apiModel { + public $status; + public $kind; + public $name; + public $classification; + protected $__epcSevenDayAverageType = 'Money'; + protected $__epcSevenDayAverageDataType = ''; + public $epcSevenDayAverage; + public $payoutRank; + protected $__epcNinetyDayAverageType = 'Money'; + protected $__epcNinetyDayAverageDataType = ''; + public $epcNinetyDayAverage; + protected $__itemType = 'Publisher2'; + protected $__itemDataType = ''; + public $item; + public $joinDate; + public $sites; + public $id; + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setClassification($classification) { + $this->classification = $classification; + } + public function getClassification() { + return $this->classification; + } + public function setEpcSevenDayAverage(Money $epcSevenDayAverage) { + $this->epcSevenDayAverage = $epcSevenDayAverage; + } + public function getEpcSevenDayAverage() { + return $this->epcSevenDayAverage; + } + public function setPayoutRank($payoutRank) { + $this->payoutRank = $payoutRank; + } + public function getPayoutRank() { + return $this->payoutRank; + } + public function setEpcNinetyDayAverage(Money $epcNinetyDayAverage) { + $this->epcNinetyDayAverage = $epcNinetyDayAverage; + } + public function getEpcNinetyDayAverage() { + return $this->epcNinetyDayAverage; + } + public function setItem(Publisher2 $item) { + $this->item = $item; + } + public function getItem() { + return $this->item; + } + public function setJoinDate($joinDate) { + $this->joinDate = $joinDate; + } + public function getJoinDate() { + return $this->joinDate; + } + public function setSites(/* array(string) */ $sites) { + $this->assertIsArray($sites, 'string', __METHOD__); + $this->sites = $sites; + } + public function getSites() { + return $this->sites; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class Publishers extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Publisher'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Publisher) */ $items) { + $this->assertIsArray($items, 'Publisher', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiLatitudeService.php b/inc/vendors/social-login/Google/contrib/apiLatitudeService.php new file mode 100755 index 00000000..fa7365f6 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiLatitudeService.php @@ -0,0 +1,270 @@ + + * $latitudeService = new apiLatitudeService(...); + * $currentLocation = $latitudeService->currentLocation; + * + */ + class CurrentLocationServiceResource extends apiServiceResource { + + + /** + * Updates or creates the user's current location. (currentLocation.insert) + * @param Location $postBody + * @return Location + */ + public function insert(Location $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Location($data); + } else { + return $data; + } + } + /** + * Returns the authenticated user's current location. (currentLocation.get) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string granularity Granularity of the requested location. + * @return Location + */ + public function get($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Location($data); + } else { + return $data; + } + } + /** + * Deletes the authenticated user's current location. (currentLocation.delete) + */ + public function delete($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "location" collection of methods. + * Typical usage is: + * + * $latitudeService = new apiLatitudeService(...); + * $location = $latitudeService->location; + * + */ + class LocationServiceResource extends apiServiceResource { + + + /** + * Inserts or updates a location in the user's location history. (location.insert) + * @param Location $postBody + * @return Location + */ + public function insert(Location $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Location($data); + } else { + return $data; + } + } + /** + * Reads a location from the user's location history. (location.get) + * @param string $locationId Timestamp of the location to read (ms since epoch). + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string granularity Granularity of the location to return. + * @return Location + */ + public function get($locationId, $optParams = array()) { + $params = array('locationId' => $locationId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Location($data); + } else { + return $data; + } + } + /** + * Lists the user's location history. (location.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of locations to return. + * @opt_param string max-time Maximum timestamp of locations to return (ms since epoch). + * @opt_param string min-time Minimum timestamp of locations to return (ms since epoch). + * @opt_param string granularity Granularity of the requested locations. + * @return LocationFeed + */ + public function listLocation($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new LocationFeed($data); + } else { + return $data; + } + } + /** + * Deletes a location from the user's location history. (location.delete) + * @param string $locationId Timestamp of the location to delete (ms since epoch). + */ + public function delete($locationId, $optParams = array()) { + $params = array('locationId' => $locationId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + + +/** + * Service definition for Latitude (v1). + *

            + * Lets you read and update your current location and work with your location history + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiLatitudeService extends apiService { + public $currentLocation; + public $location; + /** + * Constructs the internal representation of the Latitude service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/latitude/v1/'; + $this->version = 'v1'; + $this->serviceName = 'latitude'; + + $apiClient->addService($this->serviceName, $this->version); + $this->currentLocation = new CurrentLocationServiceResource($this, $this->serviceName, 'currentLocation', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/latitude.all.best", "https://www.googleapis.com/auth/latitude.all.city", "https://www.googleapis.com/auth/latitude.current.best", "https://www.googleapis.com/auth/latitude.current.city"], "request": {"$ref": "LatitudeCurrentlocationResourceJson"}, "response": {"$ref": "LatitudeCurrentlocationResourceJson"}, "httpMethod": "POST", "path": "currentLocation", "id": "latitude.currentLocation.insert"}, "delete": {"id": "latitude.currentLocation.delete", "path": "currentLocation", "httpMethod": "DELETE", "scopes": ["https://www.googleapis.com/auth/latitude.all.best", "https://www.googleapis.com/auth/latitude.all.city", "https://www.googleapis.com/auth/latitude.current.best", "https://www.googleapis.com/auth/latitude.current.city"]}, "get": {"scopes": ["https://www.googleapis.com/auth/latitude.all.best", "https://www.googleapis.com/auth/latitude.all.city", "https://www.googleapis.com/auth/latitude.current.best", "https://www.googleapis.com/auth/latitude.current.city"], "parameters": {"granularity": {"type": "string", "location": "query"}}, "response": {"$ref": "LatitudeCurrentlocationResourceJson"}, "httpMethod": "GET", "path": "currentLocation", "id": "latitude.currentLocation.get"}}}', true)); + $this->location = new LocationServiceResource($this, $this->serviceName, 'location', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/latitude.all.best", "https://www.googleapis.com/auth/latitude.all.city"], "request": {"$ref": "Location"}, "response": {"$ref": "Location"}, "httpMethod": "POST", "path": "location", "id": "latitude.location.insert"}, "delete": {"scopes": ["https://www.googleapis.com/auth/latitude.all.best", "https://www.googleapis.com/auth/latitude.all.city"], "parameters": {"locationId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "location/{locationId}", "id": "latitude.location.delete"}, "list": {"scopes": ["https://www.googleapis.com/auth/latitude.all.best", "https://www.googleapis.com/auth/latitude.all.city"], "parameters": {"max-results": {"type": "string", "location": "query"}, "max-time": {"type": "string", "location": "query"}, "min-time": {"type": "string", "location": "query"}, "granularity": {"type": "string", "location": "query"}}, "response": {"$ref": "LocationFeed"}, "httpMethod": "GET", "path": "location", "id": "latitude.location.list"}, "get": {"scopes": ["https://www.googleapis.com/auth/latitude.all.best", "https://www.googleapis.com/auth/latitude.all.city"], "parameters": {"locationId": {"required": true, "type": "string", "location": "path"}, "granularity": {"type": "string", "location": "query"}}, "id": "latitude.location.get", "httpMethod": "GET", "path": "location/{locationId}", "response": {"$ref": "Location"}}}}', true)); + } +} + +class Location extends apiModel { + public $kind; + public $altitude; + public $longitude; + public $activityId; + public $latitude; + public $altitudeAccuracy; + public $timestampMs; + public $speed; + public $heading; + public $accuracy; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAltitude($altitude) { + $this->altitude = $altitude; + } + public function getAltitude() { + return $this->altitude; + } + public function setLongitude($longitude) { + $this->longitude = $longitude; + } + public function getLongitude() { + return $this->longitude; + } + public function setActivityId($activityId) { + $this->activityId = $activityId; + } + public function getActivityId() { + return $this->activityId; + } + public function setLatitude($latitude) { + $this->latitude = $latitude; + } + public function getLatitude() { + return $this->latitude; + } + public function setAltitudeAccuracy($altitudeAccuracy) { + $this->altitudeAccuracy = $altitudeAccuracy; + } + public function getAltitudeAccuracy() { + return $this->altitudeAccuracy; + } + public function setTimestampMs($timestampMs) { + $this->timestampMs = $timestampMs; + } + public function getTimestampMs() { + return $this->timestampMs; + } + public function setSpeed($speed) { + $this->speed = $speed; + } + public function getSpeed() { + return $this->speed; + } + public function setHeading($heading) { + $this->heading = $heading; + } + public function getHeading() { + return $this->heading; + } + public function setAccuracy($accuracy) { + $this->accuracy = $accuracy; + } + public function getAccuracy() { + return $this->accuracy; + } +} + +class LocationFeed extends apiModel { + protected $__itemsType = 'Location'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Location) */ $items) { + $this->assertIsArray($items, 'Location', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiModeratorService.php b/inc/vendors/social-login/Google/contrib/apiModeratorService.php new file mode 100755 index 00000000..4ef81b5d --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiModeratorService.php @@ -0,0 +1,1850 @@ + + * $moderatorService = new apiModeratorService(...); + * $votes = $moderatorService->votes; + * + */ + class VotesServiceResource extends apiServiceResource { + + + /** + * Inserts a new vote by the authenticated user for the specified submission within the specified + * series. (votes.insert) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param Vote $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string unauthToken User identifier for unauthenticated usage mode + * @return Vote + */ + public function insert($seriesId, $submissionId, Vote $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Vote($data); + } else { + return $data; + } + } + /** + * Updates the votes by the authenticated user for the specified submission within the specified + * series. This method supports patch semantics. (votes.patch) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param Vote $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string userId + * @opt_param string unauthToken User identifier for unauthenticated usage mode + * @return Vote + */ + public function patch($seriesId, $submissionId, Vote $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Vote($data); + } else { + return $data; + } + } + /** + * Lists the votes by the authenticated user for the given series. (votes.list) + * @param string $seriesId The decimal ID of the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of results to return. + * @opt_param string start-index Index of the first result to be retrieved. + * @return VoteList + */ + public function listVotes($seriesId, $optParams = array()) { + $params = array('seriesId' => $seriesId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new VoteList($data); + } else { + return $data; + } + } + /** + * Updates the votes by the authenticated user for the specified submission within the specified + * series. (votes.update) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param Vote $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string userId + * @opt_param string unauthToken User identifier for unauthenticated usage mode + * @return Vote + */ + public function update($seriesId, $submissionId, Vote $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Vote($data); + } else { + return $data; + } + } + /** + * Returns the votes by the authenticated user for the specified submission within the specified + * series. (votes.get) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string userId + * @opt_param string unauthToken User identifier for unauthenticated usage mode + * @return Vote + */ + public function get($seriesId, $submissionId, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Vote($data); + } else { + return $data; + } + } + } + + /** + * The "responses" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $responses = $moderatorService->responses; + * + */ + class ResponsesServiceResource extends apiServiceResource { + + + /** + * Inserts a response for the specified submission in the specified topic within the specified + * series. (responses.insert) + * @param string $seriesId The decimal ID of the Series. + * @param string $topicId The decimal ID of the Topic within the Series. + * @param string $parentSubmissionId The decimal ID of the parent Submission within the Series. + * @param Submission $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string unauthToken User identifier for unauthenticated usage mode + * @opt_param bool anonymous Set to true to mark the new submission as anonymous. + * @return Submission + */ + public function insert($seriesId, $topicId, $parentSubmissionId, Submission $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'topicId' => $topicId, 'parentSubmissionId' => $parentSubmissionId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Submission($data); + } else { + return $data; + } + } + /** + * Lists or searches the responses for the specified submission within the specified series and + * returns the search results. (responses.list) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of results to return. + * @opt_param string sort Sort order. + * @opt_param string author Restricts the results to submissions by a specific author. + * @opt_param string start-index Index of the first result to be retrieved. + * @opt_param string q Search query. + * @opt_param bool hasAttachedVideo Specifies whether to restrict to submissions that have videos attached. + * @return SubmissionList + */ + public function listResponses($seriesId, $submissionId, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SubmissionList($data); + } else { + return $data; + } + } + } + + /** + * The "tags" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $tags = $moderatorService->tags; + * + */ + class TagsServiceResource extends apiServiceResource { + + + /** + * Inserts a new tag for the specified submission within the specified series. (tags.insert) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param Tag $postBody + * @return Tag + */ + public function insert($seriesId, $submissionId, Tag $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Tag($data); + } else { + return $data; + } + } + /** + * Lists all tags for the specified submission within the specified series. (tags.list) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @return TagList + */ + public function listTags($seriesId, $submissionId, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new TagList($data); + } else { + return $data; + } + } + /** + * Deletes the specified tag from the specified submission within the specified series. + * (tags.delete) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param string $tagId + */ + public function delete($seriesId, $submissionId, $tagId, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId, 'tagId' => $tagId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "series" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $series = $moderatorService->series; + * + */ + class SeriesServiceResource extends apiServiceResource { + + + /** + * Inserts a new series. (series.insert) + * @param Series $postBody + * @return Series + */ + public function insert(Series $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Series($data); + } else { + return $data; + } + } + /** + * Updates the specified series. This method supports patch semantics. (series.patch) + * @param string $seriesId The decimal ID of the Series. + * @param Series $postBody + * @return Series + */ + public function patch($seriesId, Series $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Series($data); + } else { + return $data; + } + } + /** + * Searches the series and returns the search results. (series.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of results to return. + * @opt_param string q Search query. + * @opt_param string start-index Index of the first result to be retrieved. + * @return SeriesList + */ + public function listSeries($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SeriesList($data); + } else { + return $data; + } + } + /** + * Updates the specified series. (series.update) + * @param string $seriesId The decimal ID of the Series. + * @param Series $postBody + * @return Series + */ + public function update($seriesId, Series $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Series($data); + } else { + return $data; + } + } + /** + * Returns the specified series. (series.get) + * @param string $seriesId The decimal ID of the Series. + * @return Series + */ + public function get($seriesId, $optParams = array()) { + $params = array('seriesId' => $seriesId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Series($data); + } else { + return $data; + } + } + } + + + /** + * The "submissions" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $submissions = $moderatorService->submissions; + * + */ + class SeriesSubmissionsServiceResource extends apiServiceResource { + + + /** + * Searches the submissions for the specified series and returns the search results. + * (submissions.list) + * @param string $seriesId The decimal ID of the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string lang The language code for the language the client prefers resuls in. + * @opt_param string max-results Maximum number of results to return. + * @opt_param bool includeVotes Specifies whether to include the current user's vote + * @opt_param string start-index Index of the first result to be retrieved. + * @opt_param string author Restricts the results to submissions by a specific author. + * @opt_param string sort Sort order. + * @opt_param string q Search query. + * @opt_param bool hasAttachedVideo Specifies whether to restrict to submissions that have videos attached. + * @return SubmissionList + */ + public function listSeriesSubmissions($seriesId, $optParams = array()) { + $params = array('seriesId' => $seriesId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SubmissionList($data); + } else { + return $data; + } + } + } + /** + * The "responses" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $responses = $moderatorService->responses; + * + */ + class SeriesResponsesServiceResource extends apiServiceResource { + + + /** + * Searches the responses for the specified series and returns the search results. (responses.list) + * @param string $seriesId The decimal ID of the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of results to return. + * @opt_param string sort Sort order. + * @opt_param string author Restricts the results to submissions by a specific author. + * @opt_param string start-index Index of the first result to be retrieved. + * @opt_param string q Search query. + * @opt_param bool hasAttachedVideo Specifies whether to restrict to submissions that have videos attached. + * @return SeriesList + */ + public function listSeriesResponses($seriesId, $optParams = array()) { + $params = array('seriesId' => $seriesId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SeriesList($data); + } else { + return $data; + } + } + } + + /** + * The "topics" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $topics = $moderatorService->topics; + * + */ + class TopicsServiceResource extends apiServiceResource { + + + /** + * Inserts a new topic into the specified series. (topics.insert) + * @param string $seriesId The decimal ID of the Series. + * @param Topic $postBody + * @return Topic + */ + public function insert($seriesId, Topic $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Topic($data); + } else { + return $data; + } + } + /** + * Searches the topics within the specified series and returns the search results. (topics.list) + * @param string $seriesId The decimal ID of the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of results to return. + * @opt_param string q Search query. + * @opt_param string start-index Index of the first result to be retrieved. + * @opt_param string mode + * @return TopicList + */ + public function listTopics($seriesId, $optParams = array()) { + $params = array('seriesId' => $seriesId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new TopicList($data); + } else { + return $data; + } + } + /** + * Updates the specified topic within the specified series. (topics.update) + * @param string $seriesId The decimal ID of the Series. + * @param string $topicId The decimal ID of the Topic within the Series. + * @param Topic $postBody + * @return Topic + */ + public function update($seriesId, $topicId, Topic $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'topicId' => $topicId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Topic($data); + } else { + return $data; + } + } + /** + * Returns the specified topic from the specified series. (topics.get) + * @param string $seriesId The decimal ID of the Series. + * @param string $topicId The decimal ID of the Topic within the Series. + * @return Topic + */ + public function get($seriesId, $topicId, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'topicId' => $topicId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Topic($data); + } else { + return $data; + } + } + } + + + /** + * The "submissions" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $submissions = $moderatorService->submissions; + * + */ + class TopicsSubmissionsServiceResource extends apiServiceResource { + + + /** + * Searches the submissions for the specified topic within the specified series and returns the + * search results. (submissions.list) + * @param string $seriesId The decimal ID of the Series. + * @param string $topicId The decimal ID of the Topic within the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of results to return. + * @opt_param bool includeVotes Specifies whether to include the current user's vote + * @opt_param string start-index Index of the first result to be retrieved. + * @opt_param string author Restricts the results to submissions by a specific author. + * @opt_param string sort Sort order. + * @opt_param string q Search query. + * @opt_param bool hasAttachedVideo Specifies whether to restrict to submissions that have videos attached. + * @return SubmissionList + */ + public function listTopicsSubmissions($seriesId, $topicId, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'topicId' => $topicId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SubmissionList($data); + } else { + return $data; + } + } + } + + /** + * The "global" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $global = $moderatorService->global; + * + */ + class ModeratorGlobalServiceResource extends apiServiceResource { + + + } + + + /** + * The "series" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $series = $moderatorService->series; + * + */ + class ModeratorGlobalSeriesServiceResource extends apiServiceResource { + + + /** + * Searches the public series and returns the search results. (series.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string max-results Maximum number of results to return. + * @opt_param string q Search query. + * @opt_param string start-index Index of the first result to be retrieved. + * @return SeriesList + */ + public function listModeratorGlobalSeries($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SeriesList($data); + } else { + return $data; + } + } + } + + /** + * The "profiles" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $profiles = $moderatorService->profiles; + * + */ + class ProfilesServiceResource extends apiServiceResource { + + + /** + * Updates the profile information for the authenticated user. This method supports patch semantics. + * (profiles.patch) + * @param Profile $postBody + * @return Profile + */ + public function patch(Profile $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Profile($data); + } else { + return $data; + } + } + /** + * Updates the profile information for the authenticated user. (profiles.update) + * @param Profile $postBody + * @return Profile + */ + public function update(Profile $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Profile($data); + } else { + return $data; + } + } + /** + * Returns the profile information for the authenticated user. (profiles.get) + * @return Profile + */ + public function get($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Profile($data); + } else { + return $data; + } + } + } + + /** + * The "featured" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $featured = $moderatorService->featured; + * + */ + class FeaturedServiceResource extends apiServiceResource { + + + } + + + /** + * The "series" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $series = $moderatorService->series; + * + */ + class FeaturedSeriesServiceResource extends apiServiceResource { + + + /** + * Lists the featured series. (series.list) + * @return SeriesList + */ + public function listFeaturedSeries($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SeriesList($data); + } else { + return $data; + } + } + } + + /** + * The "myrecent" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $myrecent = $moderatorService->myrecent; + * + */ + class MyrecentServiceResource extends apiServiceResource { + + + } + + + /** + * The "series" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $series = $moderatorService->series; + * + */ + class MyrecentSeriesServiceResource extends apiServiceResource { + + + /** + * Lists the series the authenticated user has visited. (series.list) + * @return SeriesList + */ + public function listMyrecentSeries($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SeriesList($data); + } else { + return $data; + } + } + } + + /** + * The "my" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $my = $moderatorService->my; + * + */ + class MyServiceResource extends apiServiceResource { + + + } + + + /** + * The "series" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $series = $moderatorService->series; + * + */ + class MySeriesServiceResource extends apiServiceResource { + + + /** + * Lists all series created by the authenticated user. (series.list) + * @return SeriesList + */ + public function listMySeries($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SeriesList($data); + } else { + return $data; + } + } + } + + /** + * The "submissions" collection of methods. + * Typical usage is: + * + * $moderatorService = new apiModeratorService(...); + * $submissions = $moderatorService->submissions; + * + */ + class SubmissionsServiceResource extends apiServiceResource { + + + /** + * Inserts a new submission in the specified topic within the specified series. (submissions.insert) + * @param string $seriesId The decimal ID of the Series. + * @param string $topicId The decimal ID of the Topic within the Series. + * @param Submission $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string unauthToken User identifier for unauthenticated usage mode + * @opt_param bool anonymous Set to true to mark the new submission as anonymous. + * @return Submission + */ + public function insert($seriesId, $topicId, Submission $postBody, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'topicId' => $topicId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Submission($data); + } else { + return $data; + } + } + /** + * Returns the specified submission within the specified series. (submissions.get) + * @param string $seriesId The decimal ID of the Series. + * @param string $submissionId The decimal ID of the Submission within the Series. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string lang The language code for the language the client prefers resuls in. + * @opt_param bool includeVotes Specifies whether to include the current user's vote + * @return Submission + */ + public function get($seriesId, $submissionId, $optParams = array()) { + $params = array('seriesId' => $seriesId, 'submissionId' => $submissionId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Submission($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Moderator (v1). + *

            + * Moderator API + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiModeratorService extends apiService { + public $votes; + public $responses; + public $tags; + public $series; + public $series_submissions; + public $series_submissions_submissions; + public $series_submissions_responses; + public $series_responses; + public $series_responses_submissions; + public $series_responses_responses; + public $topics; + public $topics_submissions; + public $topics_submissions_submissions; + public $global; + public $global_series; + public $global_series_series; + public $profiles; + public $featured; + public $featured_series; + public $featured_series_series; + public $myrecent; + public $myrecent_series; + public $myrecent_series_series; + public $my; + public $my_series; + public $my_series_series; + public $submissions; + /** + * Constructs the internal representation of the Moderator service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/moderator/v1/'; + $this->version = 'v1'; + $this->serviceName = 'moderator'; + + $apiClient->addService($this->serviceName, $this->version); + $this->votes = new VotesServiceResource($this, $this->serviceName, 'votes', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "unauthToken": {"type": "string", "location": "query"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Vote"}, "id": "moderator.votes.insert", "httpMethod": "POST", "path": "series/{seriesId}/submissions/{submissionId}/votes/@me", "response": {"$ref": "Vote"}}, "get": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "userId": {"type": "string", "location": "query"}, "unauthToken": {"type": "string", "location": "query"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "id": "moderator.votes.get", "httpMethod": "GET", "path": "series/{seriesId}/submissions/{submissionId}/votes/@me", "response": {"$ref": "Vote"}}, "list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"max-results": {"format": "uint32", "type": "integer", "location": "query"}, "seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}}, "id": "moderator.votes.list", "httpMethod": "GET", "path": "series/{seriesId}/votes/@me", "response": {"$ref": "VoteList"}}, "update": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "userId": {"type": "string", "location": "query"}, "unauthToken": {"type": "string", "location": "query"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Vote"}, "id": "moderator.votes.update", "httpMethod": "PUT", "path": "series/{seriesId}/submissions/{submissionId}/votes/@me", "response": {"$ref": "Vote"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "userId": {"type": "string", "location": "query"}, "unauthToken": {"type": "string", "location": "query"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Vote"}, "id": "moderator.votes.patch", "httpMethod": "PATCH", "path": "series/{seriesId}/submissions/{submissionId}/votes/@me", "response": {"$ref": "Vote"}}}}', true)); + $this->responses = new ResponsesServiceResource($this, $this->serviceName, 'responses', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "parentSubmissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "unauthToken": {"type": "string", "location": "query"}, "anonymous": {"type": "boolean", "location": "query"}, "topicId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Submission"}, "id": "moderator.responses.insert", "httpMethod": "POST", "path": "series/{seriesId}/topics/{topicId}/submissions/{parentSubmissionId}/responses", "response": {"$ref": "Submission"}}, "list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"max-results": {"format": "uint32", "type": "integer", "location": "query"}, "sort": {"type": "string", "location": "query"}, "seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "author": {"type": "string", "location": "query"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "q": {"type": "string", "location": "query"}, "hasAttachedVideo": {"type": "boolean", "location": "query"}}, "id": "moderator.responses.list", "httpMethod": "GET", "path": "series/{seriesId}/submissions/{submissionId}/responses", "response": {"$ref": "SubmissionList"}}}}', true)); + $this->tags = new TagsServiceResource($this, $this->serviceName, 'tags', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Tag"}, "id": "moderator.tags.insert", "httpMethod": "POST", "path": "series/{seriesId}/submissions/{submissionId}/tags", "response": {"$ref": "Tag"}}, "list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "id": "moderator.tags.list", "httpMethod": "GET", "path": "series/{seriesId}/submissions/{submissionId}/tags", "response": {"$ref": "TagList"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "tagId": {"required": true, "type": "string", "location": "path"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "httpMethod": "DELETE", "path": "series/{seriesId}/submissions/{submissionId}/tags/{tagId}", "id": "moderator.tags.delete"}}}', true)); + $this->series = new SeriesServiceResource($this, $this->serviceName, 'series', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/moderator"], "request": {"$ref": "Series"}, "response": {"$ref": "Series"}, "httpMethod": "POST", "path": "series", "id": "moderator.series.insert"}, "get": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "id": "moderator.series.get", "httpMethod": "GET", "path": "series/{seriesId}", "response": {"$ref": "Series"}}, "list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"max-results": {"format": "uint32", "type": "integer", "location": "query"}, "q": {"type": "string", "location": "query"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}}, "response": {"$ref": "SeriesList"}, "httpMethod": "GET", "path": "series", "id": "moderator.series.list"}, "update": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Series"}, "id": "moderator.series.update", "httpMethod": "PUT", "path": "series/{seriesId}", "response": {"$ref": "Series"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Series"}, "id": "moderator.series.patch", "httpMethod": "PATCH", "path": "series/{seriesId}", "response": {"$ref": "Series"}}}}', true)); + $this->series_submissions = new SeriesSubmissionsServiceResource($this, $this->serviceName, 'submissions', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"lang": {"type": "string", "location": "query"}, "max-results": {"format": "uint32", "type": "integer", "location": "query"}, "seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "author": {"type": "string", "location": "query"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}, "includeVotes": {"type": "boolean", "location": "query"}, "sort": {"type": "string", "location": "query"}, "q": {"type": "string", "location": "query"}, "hasAttachedVideo": {"type": "boolean", "location": "query"}}, "id": "moderator.series.submissions.list", "httpMethod": "GET", "path": "series/{seriesId}/submissions", "response": {"$ref": "SubmissionList"}}}}', true)); + $this->series_responses = new SeriesResponsesServiceResource($this, $this->serviceName, 'responses', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"max-results": {"format": "uint32", "type": "integer", "location": "query"}, "sort": {"type": "string", "location": "query"}, "seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "author": {"type": "string", "location": "query"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}, "q": {"type": "string", "location": "query"}, "hasAttachedVideo": {"type": "boolean", "location": "query"}}, "id": "moderator.series.responses.list", "httpMethod": "GET", "path": "series/{seriesId}/responses", "response": {"$ref": "SeriesList"}}}}', true)); + $this->topics = new TopicsServiceResource($this, $this->serviceName, 'topics', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Topic"}, "id": "moderator.topics.insert", "httpMethod": "POST", "path": "series/{seriesId}/topics", "response": {"$ref": "Topic"}}, "list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"max-results": {"format": "uint32", "type": "integer", "location": "query"}, "q": {"type": "string", "location": "query"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}, "mode": {"type": "string", "location": "query"}, "seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "id": "moderator.topics.list", "httpMethod": "GET", "path": "series/{seriesId}/topics", "response": {"$ref": "TopicList"}}, "update": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "topicId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "Topic"}, "id": "moderator.topics.update", "httpMethod": "PUT", "path": "series/{seriesId}/topics/{topicId}", "response": {"$ref": "Topic"}}, "get": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "topicId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "id": "moderator.topics.get", "httpMethod": "GET", "path": "series/{seriesId}/topics/{topicId}", "response": {"$ref": "Topic"}}}}', true)); + $this->topics_submissions = new TopicsSubmissionsServiceResource($this, $this->serviceName, 'submissions', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"max-results": {"format": "uint32", "type": "integer", "location": "query"}, "seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "includeVotes": {"type": "boolean", "location": "query"}, "topicId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}, "author": {"type": "string", "location": "query"}, "sort": {"type": "string", "location": "query"}, "q": {"type": "string", "location": "query"}, "hasAttachedVideo": {"type": "boolean", "location": "query"}}, "id": "moderator.topics.submissions.list", "httpMethod": "GET", "path": "series/{seriesId}/topics/{topicId}/submissions", "response": {"$ref": "SubmissionList"}}}}', true)); + $this->global = new ModeratorGlobalServiceResource($this, $this->serviceName, 'global', json_decode('{}', true)); + $this->global_series = new ModeratorGlobalSeriesServiceResource($this, $this->serviceName, 'series', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"max-results": {"format": "uint32", "type": "integer", "location": "query"}, "q": {"type": "string", "location": "query"}, "start-index": {"format": "uint32", "type": "integer", "location": "query"}}, "response": {"$ref": "SeriesList"}, "httpMethod": "GET", "path": "search", "id": "moderator.global.series.list"}}}', true)); + $this->profiles = new ProfilesServiceResource($this, $this->serviceName, 'profiles', json_decode('{"methods": {"get": {"scopes": ["https://www.googleapis.com/auth/moderator"], "id": "moderator.profiles.get", "httpMethod": "GET", "path": "profiles/@me", "response": {"$ref": "Profile"}}, "update": {"scopes": ["https://www.googleapis.com/auth/moderator"], "request": {"$ref": "Profile"}, "response": {"$ref": "Profile"}, "httpMethod": "PUT", "path": "profiles/@me", "id": "moderator.profiles.update"}, "patch": {"scopes": ["https://www.googleapis.com/auth/moderator"], "request": {"$ref": "Profile"}, "response": {"$ref": "Profile"}, "httpMethod": "PATCH", "path": "profiles/@me", "id": "moderator.profiles.patch"}}}', true)); + $this->featured = new FeaturedServiceResource($this, $this->serviceName, 'featured', json_decode('{}', true)); + $this->featured_series = new FeaturedSeriesServiceResource($this, $this->serviceName, 'series', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "id": "moderator.featured.series.list", "httpMethod": "GET", "path": "series/featured", "response": {"$ref": "SeriesList"}}}}', true)); + $this->myrecent = new MyrecentServiceResource($this, $this->serviceName, 'myrecent', json_decode('{}', true)); + $this->myrecent_series = new MyrecentSeriesServiceResource($this, $this->serviceName, 'series', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "id": "moderator.myrecent.series.list", "httpMethod": "GET", "path": "series/@me/recent", "response": {"$ref": "SeriesList"}}}}', true)); + $this->my = new MyServiceResource($this, $this->serviceName, 'my', json_decode('{}', true)); + $this->my_series = new MySeriesServiceResource($this, $this->serviceName, 'series', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/moderator"], "id": "moderator.my.series.list", "httpMethod": "GET", "path": "series/@me/mine", "response": {"$ref": "SeriesList"}}}}', true)); + $this->submissions = new SubmissionsServiceResource($this, $this->serviceName, 'submissions', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "topicId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "unauthToken": {"type": "string", "location": "query"}, "anonymous": {"type": "boolean", "location": "query"}}, "request": {"$ref": "Submission"}, "id": "moderator.submissions.insert", "httpMethod": "POST", "path": "series/{seriesId}/topics/{topicId}/submissions", "response": {"$ref": "Submission"}}, "get": {"scopes": ["https://www.googleapis.com/auth/moderator"], "parameters": {"lang": {"type": "string", "location": "query"}, "seriesId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "includeVotes": {"type": "boolean", "location": "query"}, "submissionId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}}, "id": "moderator.submissions.get", "httpMethod": "GET", "path": "series/{seriesId}/submissions/{submissionId}", "response": {"$ref": "Submission"}}}}', true)); + } +} + +class ModeratorTopicsResourcePartial extends apiModel { + protected $__idType = 'ModeratorTopicsResourcePartialId'; + protected $__idDataType = ''; + public $id; + public function setId(ModeratorTopicsResourcePartialId $id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ModeratorTopicsResourcePartialId extends apiModel { + public $seriesId; + public $topicId; + public function setSeriesId($seriesId) { + $this->seriesId = $seriesId; + } + public function getSeriesId() { + return $this->seriesId; + } + public function setTopicId($topicId) { + $this->topicId = $topicId; + } + public function getTopicId() { + return $this->topicId; + } +} + +class ModeratorVotesResourcePartial extends apiModel { + public $vote; + public $flag; + public function setVote($vote) { + $this->vote = $vote; + } + public function getVote() { + return $this->vote; + } + public function setFlag($flag) { + $this->flag = $flag; + } + public function getFlag() { + return $this->flag; + } +} + +class Profile extends apiModel { + public $kind; + protected $__attributionType = 'ProfileAttribution'; + protected $__attributionDataType = ''; + public $attribution; + protected $__idType = 'ProfileId'; + protected $__idDataType = ''; + public $id; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAttribution(ProfileAttribution $attribution) { + $this->attribution = $attribution; + } + public function getAttribution() { + return $this->attribution; + } + public function setId(ProfileId $id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ProfileAttribution extends apiModel { + protected $__geoType = 'ProfileAttributionGeo'; + protected $__geoDataType = ''; + public $geo; + public $displayName; + public $location; + public $avatarUrl; + public function setGeo(ProfileAttributionGeo $geo) { + $this->geo = $geo; + } + public function getGeo() { + return $this->geo; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setAvatarUrl($avatarUrl) { + $this->avatarUrl = $avatarUrl; + } + public function getAvatarUrl() { + return $this->avatarUrl; + } +} + +class ProfileAttributionGeo extends apiModel { + public $latitude; + public $location; + public $longitude; + public function setLatitude($latitude) { + $this->latitude = $latitude; + } + public function getLatitude() { + return $this->latitude; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setLongitude($longitude) { + $this->longitude = $longitude; + } + public function getLongitude() { + return $this->longitude; + } +} + +class ProfileId extends apiModel { + public $user; + public function setUser($user) { + $this->user = $user; + } + public function getUser() { + return $this->user; + } +} + +class Series extends apiModel { + public $kind; + public $description; + protected $__rulesType = 'SeriesRules'; + protected $__rulesDataType = ''; + public $rules; + public $unauthVotingAllowed; + public $videoSubmissionAllowed; + public $name; + public $numTopics; + public $anonymousSubmissionAllowed; + public $unauthSubmissionAllowed; + protected $__idType = 'SeriesId'; + protected $__idDataType = ''; + public $id; + protected $__countersType = 'SeriesCounters'; + protected $__countersDataType = ''; + public $counters; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setRules(SeriesRules $rules) { + $this->rules = $rules; + } + public function getRules() { + return $this->rules; + } + public function setUnauthVotingAllowed($unauthVotingAllowed) { + $this->unauthVotingAllowed = $unauthVotingAllowed; + } + public function getUnauthVotingAllowed() { + return $this->unauthVotingAllowed; + } + public function setVideoSubmissionAllowed($videoSubmissionAllowed) { + $this->videoSubmissionAllowed = $videoSubmissionAllowed; + } + public function getVideoSubmissionAllowed() { + return $this->videoSubmissionAllowed; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setNumTopics($numTopics) { + $this->numTopics = $numTopics; + } + public function getNumTopics() { + return $this->numTopics; + } + public function setAnonymousSubmissionAllowed($anonymousSubmissionAllowed) { + $this->anonymousSubmissionAllowed = $anonymousSubmissionAllowed; + } + public function getAnonymousSubmissionAllowed() { + return $this->anonymousSubmissionAllowed; + } + public function setUnauthSubmissionAllowed($unauthSubmissionAllowed) { + $this->unauthSubmissionAllowed = $unauthSubmissionAllowed; + } + public function getUnauthSubmissionAllowed() { + return $this->unauthSubmissionAllowed; + } + public function setId(SeriesId $id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setCounters(SeriesCounters $counters) { + $this->counters = $counters; + } + public function getCounters() { + return $this->counters; + } +} + +class SeriesCounters extends apiModel { + public $users; + public $noneVotes; + public $videoSubmissions; + public $minusVotes; + public $anonymousSubmissions; + public $submissions; + public $plusVotes; + public function setUsers($users) { + $this->users = $users; + } + public function getUsers() { + return $this->users; + } + public function setNoneVotes($noneVotes) { + $this->noneVotes = $noneVotes; + } + public function getNoneVotes() { + return $this->noneVotes; + } + public function setVideoSubmissions($videoSubmissions) { + $this->videoSubmissions = $videoSubmissions; + } + public function getVideoSubmissions() { + return $this->videoSubmissions; + } + public function setMinusVotes($minusVotes) { + $this->minusVotes = $minusVotes; + } + public function getMinusVotes() { + return $this->minusVotes; + } + public function setAnonymousSubmissions($anonymousSubmissions) { + $this->anonymousSubmissions = $anonymousSubmissions; + } + public function getAnonymousSubmissions() { + return $this->anonymousSubmissions; + } + public function setSubmissions($submissions) { + $this->submissions = $submissions; + } + public function getSubmissions() { + return $this->submissions; + } + public function setPlusVotes($plusVotes) { + $this->plusVotes = $plusVotes; + } + public function getPlusVotes() { + return $this->plusVotes; + } +} + +class SeriesId extends apiModel { + public $seriesId; + public function setSeriesId($seriesId) { + $this->seriesId = $seriesId; + } + public function getSeriesId() { + return $this->seriesId; + } +} + +class SeriesList extends apiModel { + protected $__itemsType = 'Series'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Series) */ $items) { + $this->assertIsArray($items, 'Series', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class SeriesRules extends apiModel { + protected $__votesType = 'SeriesRulesVotes'; + protected $__votesDataType = ''; + public $votes; + protected $__submissionsType = 'SeriesRulesSubmissions'; + protected $__submissionsDataType = ''; + public $submissions; + public function setVotes(SeriesRulesVotes $votes) { + $this->votes = $votes; + } + public function getVotes() { + return $this->votes; + } + public function setSubmissions(SeriesRulesSubmissions $submissions) { + $this->submissions = $submissions; + } + public function getSubmissions() { + return $this->submissions; + } +} + +class SeriesRulesSubmissions extends apiModel { + public $close; + public $open; + public function setClose($close) { + $this->close = $close; + } + public function getClose() { + return $this->close; + } + public function setOpen($open) { + $this->open = $open; + } + public function getOpen() { + return $this->open; + } +} + +class SeriesRulesVotes extends apiModel { + public $close; + public $open; + public function setClose($close) { + $this->close = $close; + } + public function getClose() { + return $this->close; + } + public function setOpen($open) { + $this->open = $open; + } + public function getOpen() { + return $this->open; + } +} + +class Submission extends apiModel { + public $kind; + protected $__attributionType = 'SubmissionAttribution'; + protected $__attributionDataType = ''; + public $attribution; + public $created; + public $text; + protected $__topicsType = 'ModeratorTopicsResourcePartial'; + protected $__topicsDataType = 'array'; + public $topics; + public $author; + protected $__translationsType = 'SubmissionTranslations'; + protected $__translationsDataType = 'array'; + public $translations; + protected $__parentSubmissionIdType = 'SubmissionParentSubmissionId'; + protected $__parentSubmissionIdDataType = ''; + public $parentSubmissionId; + protected $__voteType = 'ModeratorVotesResourcePartial'; + protected $__voteDataType = ''; + public $vote; + public $attachmentUrl; + protected $__geoType = 'SubmissionGeo'; + protected $__geoDataType = ''; + public $geo; + protected $__idType = 'SubmissionId'; + protected $__idDataType = ''; + public $id; + protected $__countersType = 'SubmissionCounters'; + protected $__countersDataType = ''; + public $counters; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAttribution(SubmissionAttribution $attribution) { + $this->attribution = $attribution; + } + public function getAttribution() { + return $this->attribution; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setText($text) { + $this->text = $text; + } + public function getText() { + return $this->text; + } + public function setTopics(/* array(ModeratorTopicsResourcePartial) */ $topics) { + $this->assertIsArray($topics, 'ModeratorTopicsResourcePartial', __METHOD__); + $this->topics = $topics; + } + public function getTopics() { + return $this->topics; + } + public function setAuthor($author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setTranslations(/* array(SubmissionTranslations) */ $translations) { + $this->assertIsArray($translations, 'SubmissionTranslations', __METHOD__); + $this->translations = $translations; + } + public function getTranslations() { + return $this->translations; + } + public function setParentSubmissionId(SubmissionParentSubmissionId $parentSubmissionId) { + $this->parentSubmissionId = $parentSubmissionId; + } + public function getParentSubmissionId() { + return $this->parentSubmissionId; + } + public function setVote(ModeratorVotesResourcePartial $vote) { + $this->vote = $vote; + } + public function getVote() { + return $this->vote; + } + public function setAttachmentUrl($attachmentUrl) { + $this->attachmentUrl = $attachmentUrl; + } + public function getAttachmentUrl() { + return $this->attachmentUrl; + } + public function setGeo(SubmissionGeo $geo) { + $this->geo = $geo; + } + public function getGeo() { + return $this->geo; + } + public function setId(SubmissionId $id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setCounters(SubmissionCounters $counters) { + $this->counters = $counters; + } + public function getCounters() { + return $this->counters; + } +} + +class SubmissionAttribution extends apiModel { + public $displayName; + public $location; + public $avatarUrl; + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setAvatarUrl($avatarUrl) { + $this->avatarUrl = $avatarUrl; + } + public function getAvatarUrl() { + return $this->avatarUrl; + } +} + +class SubmissionCounters extends apiModel { + public $noneVotes; + public $minusVotes; + public $plusVotes; + public function setNoneVotes($noneVotes) { + $this->noneVotes = $noneVotes; + } + public function getNoneVotes() { + return $this->noneVotes; + } + public function setMinusVotes($minusVotes) { + $this->minusVotes = $minusVotes; + } + public function getMinusVotes() { + return $this->minusVotes; + } + public function setPlusVotes($plusVotes) { + $this->plusVotes = $plusVotes; + } + public function getPlusVotes() { + return $this->plusVotes; + } +} + +class SubmissionGeo extends apiModel { + public $latitude; + public $location; + public $longitude; + public function setLatitude($latitude) { + $this->latitude = $latitude; + } + public function getLatitude() { + return $this->latitude; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setLongitude($longitude) { + $this->longitude = $longitude; + } + public function getLongitude() { + return $this->longitude; + } +} + +class SubmissionId extends apiModel { + public $seriesId; + public $submissionId; + public function setSeriesId($seriesId) { + $this->seriesId = $seriesId; + } + public function getSeriesId() { + return $this->seriesId; + } + public function setSubmissionId($submissionId) { + $this->submissionId = $submissionId; + } + public function getSubmissionId() { + return $this->submissionId; + } +} + +class SubmissionList extends apiModel { + protected $__itemsType = 'Submission'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Submission) */ $items) { + $this->assertIsArray($items, 'Submission', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class SubmissionParentSubmissionId extends apiModel { + public $seriesId; + public $submissionId; + public function setSeriesId($seriesId) { + $this->seriesId = $seriesId; + } + public function getSeriesId() { + return $this->seriesId; + } + public function setSubmissionId($submissionId) { + $this->submissionId = $submissionId; + } + public function getSubmissionId() { + return $this->submissionId; + } +} + +class SubmissionTranslations extends apiModel { + public $lang; + public $text; + public function setLang($lang) { + $this->lang = $lang; + } + public function getLang() { + return $this->lang; + } + public function setText($text) { + $this->text = $text; + } + public function getText() { + return $this->text; + } +} + +class Tag extends apiModel { + public $text; + public $kind; + protected $__idType = 'TagId'; + protected $__idDataType = ''; + public $id; + public function setText($text) { + $this->text = $text; + } + public function getText() { + return $this->text; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setId(TagId $id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class TagId extends apiModel { + public $seriesId; + public $tagId; + public $submissionId; + public function setSeriesId($seriesId) { + $this->seriesId = $seriesId; + } + public function getSeriesId() { + return $this->seriesId; + } + public function setTagId($tagId) { + $this->tagId = $tagId; + } + public function getTagId() { + return $this->tagId; + } + public function setSubmissionId($submissionId) { + $this->submissionId = $submissionId; + } + public function getSubmissionId() { + return $this->submissionId; + } +} + +class TagList extends apiModel { + protected $__itemsType = 'Tag'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Tag) */ $items) { + $this->assertIsArray($items, 'Tag', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class Topic extends apiModel { + public $kind; + public $description; + protected $__rulesType = 'TopicRules'; + protected $__rulesDataType = ''; + public $rules; + protected $__featuredSubmissionType = 'Submission'; + protected $__featuredSubmissionDataType = ''; + public $featuredSubmission; + public $presenter; + protected $__countersType = 'TopicCounters'; + protected $__countersDataType = ''; + public $counters; + protected $__idType = 'TopicId'; + protected $__idDataType = ''; + public $id; + public $name; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setRules(TopicRules $rules) { + $this->rules = $rules; + } + public function getRules() { + return $this->rules; + } + public function setFeaturedSubmission(Submission $featuredSubmission) { + $this->featuredSubmission = $featuredSubmission; + } + public function getFeaturedSubmission() { + return $this->featuredSubmission; + } + public function setPresenter($presenter) { + $this->presenter = $presenter; + } + public function getPresenter() { + return $this->presenter; + } + public function setCounters(TopicCounters $counters) { + $this->counters = $counters; + } + public function getCounters() { + return $this->counters; + } + public function setId(TopicId $id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class TopicCounters extends apiModel { + public $users; + public $noneVotes; + public $videoSubmissions; + public $minusVotes; + public $submissions; + public $plusVotes; + public function setUsers($users) { + $this->users = $users; + } + public function getUsers() { + return $this->users; + } + public function setNoneVotes($noneVotes) { + $this->noneVotes = $noneVotes; + } + public function getNoneVotes() { + return $this->noneVotes; + } + public function setVideoSubmissions($videoSubmissions) { + $this->videoSubmissions = $videoSubmissions; + } + public function getVideoSubmissions() { + return $this->videoSubmissions; + } + public function setMinusVotes($minusVotes) { + $this->minusVotes = $minusVotes; + } + public function getMinusVotes() { + return $this->minusVotes; + } + public function setSubmissions($submissions) { + $this->submissions = $submissions; + } + public function getSubmissions() { + return $this->submissions; + } + public function setPlusVotes($plusVotes) { + $this->plusVotes = $plusVotes; + } + public function getPlusVotes() { + return $this->plusVotes; + } +} + +class TopicId extends apiModel { + public $seriesId; + public $topicId; + public function setSeriesId($seriesId) { + $this->seriesId = $seriesId; + } + public function getSeriesId() { + return $this->seriesId; + } + public function setTopicId($topicId) { + $this->topicId = $topicId; + } + public function getTopicId() { + return $this->topicId; + } +} + +class TopicList extends apiModel { + protected $__itemsType = 'Topic'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Topic) */ $items) { + $this->assertIsArray($items, 'Topic', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class TopicRules extends apiModel { + protected $__votesType = 'TopicRulesVotes'; + protected $__votesDataType = ''; + public $votes; + protected $__submissionsType = 'TopicRulesSubmissions'; + protected $__submissionsDataType = ''; + public $submissions; + public function setVotes(TopicRulesVotes $votes) { + $this->votes = $votes; + } + public function getVotes() { + return $this->votes; + } + public function setSubmissions(TopicRulesSubmissions $submissions) { + $this->submissions = $submissions; + } + public function getSubmissions() { + return $this->submissions; + } +} + +class TopicRulesSubmissions extends apiModel { + public $close; + public $open; + public function setClose($close) { + $this->close = $close; + } + public function getClose() { + return $this->close; + } + public function setOpen($open) { + $this->open = $open; + } + public function getOpen() { + return $this->open; + } +} + +class TopicRulesVotes extends apiModel { + public $close; + public $open; + public function setClose($close) { + $this->close = $close; + } + public function getClose() { + return $this->close; + } + public function setOpen($open) { + $this->open = $open; + } + public function getOpen() { + return $this->open; + } +} + +class Vote extends apiModel { + public $vote; + public $flag; + protected $__idType = 'VoteId'; + protected $__idDataType = ''; + public $id; + public $kind; + public function setVote($vote) { + $this->vote = $vote; + } + public function getVote() { + return $this->vote; + } + public function setFlag($flag) { + $this->flag = $flag; + } + public function getFlag() { + return $this->flag; + } + public function setId(VoteId $id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class VoteId extends apiModel { + public $seriesId; + public $submissionId; + public function setSeriesId($seriesId) { + $this->seriesId = $seriesId; + } + public function getSeriesId() { + return $this->seriesId; + } + public function setSubmissionId($submissionId) { + $this->submissionId = $submissionId; + } + public function getSubmissionId() { + return $this->submissionId; + } +} + +class VoteList extends apiModel { + protected $__itemsType = 'Vote'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Vote) */ $items) { + $this->assertIsArray($items, 'Vote', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiOauth2Service.php b/inc/vendors/social-login/Google/contrib/apiOauth2Service.php new file mode 100755 index 00000000..28e5b996 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiOauth2Service.php @@ -0,0 +1,296 @@ + + * $oauth2Service = new apiOauth2Service(...); + * $userinfo = $oauth2Service->userinfo; + * + */ + class UserinfoServiceResource extends apiServiceResource { + + + /** + * (userinfo.get) + * @return Userinfo + */ + public function get($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Userinfo($data); + } else { + return $data; + } + } + } + + + /** + * The "v2" collection of methods. + * Typical usage is: + * + * $oauth2Service = new apiOauth2Service(...); + * $v2 = $oauth2Service->v2; + * + */ + class UserinfoV2ServiceResource extends apiServiceResource { + + + } + + + /** + * The "me" collection of methods. + * Typical usage is: + * + * $oauth2Service = new apiOauth2Service(...); + * $me = $oauth2Service->me; + * + */ + class UserinfoV2MeServiceResource extends apiServiceResource { + + + /** + * (me.get) + * @return Userinfo + */ + public function get($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Userinfo($data); + } else { + return $data; + } + } + } + + + /** + * The "tokeninfo" collection of methods. + * Typical usage is: + * + * $oauth2Service = new apiOauth2Service(...); + * $tokeninfo = $oauth2Service->tokeninfo; + * + */ + class TokeninfoServiceResource extends apiServiceResource { + /** + * (tokeninfo.tokeninfo) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string access_token + * @opt_param string id_token + * @return Tokeninfo + */ + public function tokeninfo($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('tokeninfo', array($params)); + if ($this->useObjects()) { + return new Tokeninfo($data); + } else { + return $data; + } + } + + } + + +/** + * Service definition for Oauth2 (v2). + *

            + * OAuth2 API + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiOauth2Service extends apiService { + public $tokeninfo; + public $userinfo; + public $userinfo_v2; + /** + * Constructs the internal representation of the Oauth2 service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/'; + $this->version = 'v2'; + $this->serviceName = 'oauth2'; + + $apiClient->addService($this->serviceName, $this->version); + $this->userinfo = new UserinfoServiceResource($this, $this->serviceName, 'userinfo', json_decode('{"methods": {"get": {"path": "oauth2/v2/userinfo", "response": {"$ref": "Userinfo"}, "httpMethod": "GET", "id": "oauth2.userinfo.get"}}}', true)); + $this->userinfo_v2 = new UserinfoV2ServiceResource($this, $this->serviceName, 'v2', json_decode('{}', true)); + $this->tokeninfo = new TokeninfoServiceResource($this, $this->serviceName, 'tokeninfo', json_decode('{"id": "oauth2.tokeninfo", "path": "oauth2/v2/tokeninfo", "response": {"$ref": "Tokeninfo"}, "parameters": {"access_token": {"type": "string", "location": "query"}, "id_token": {"type": "string", "location": "query"}}, "httpMethod": "GET"}', true)); + } +} + +class Tokeninfo extends apiModel { + public $issued_to; + public $user_id; + public $expires_in; + public $access_type; + public $audience; + public $scope; + public $email; + public $verified_email; + public function setIssued_to($issued_to) { + $this->issued_to = $issued_to; + } + public function getIssued_to() { + return $this->issued_to; + } + public function setUser_id($user_id) { + $this->user_id = $user_id; + } + public function getUser_id() { + return $this->user_id; + } + public function setExpires_in($expires_in) { + $this->expires_in = $expires_in; + } + public function getExpires_in() { + return $this->expires_in; + } + public function setAccess_type($access_type) { + $this->access_type = $access_type; + } + public function getAccess_type() { + return $this->access_type; + } + public function setAudience($audience) { + $this->audience = $audience; + } + public function getAudience() { + return $this->audience; + } + public function setScope($scope) { + $this->scope = $scope; + } + public function getScope() { + return $this->scope; + } + public function setEmail($email) { + $this->email = $email; + } + public function getEmail() { + return $this->email; + } + public function setVerified_email($verified_email) { + $this->verified_email = $verified_email; + } + public function getVerified_email() { + return $this->verified_email; + } +} + +class Userinfo extends apiModel { + public $family_name; + public $name; + public $picture; + public $locale; + public $gender; + public $email; + public $birthday; + public $link; + public $given_name; + public $timezone; + public $id; + public $verified_email; + public function setFamily_name($family_name) { + $this->family_name = $family_name; + } + public function getFamily_name() { + return $this->family_name; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setPicture($picture) { + $this->picture = $picture; + } + public function getPicture() { + return $this->picture; + } + public function setLocale($locale) { + $this->locale = $locale; + } + public function getLocale() { + return $this->locale; + } + public function setGender($gender) { + $this->gender = $gender; + } + public function getGender() { + return $this->gender; + } + public function setEmail($email) { + $this->email = $email; + } + public function getEmail() { + return $this->email; + } + public function setBirthday($birthday) { + $this->birthday = $birthday; + } + public function getBirthday() { + return $this->birthday; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setGiven_name($given_name) { + $this->given_name = $given_name; + } + public function getGiven_name() { + return $this->given_name; + } + public function setTimezone($timezone) { + $this->timezone = $timezone; + } + public function getTimezone() { + return $this->timezone; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setVerified_email($verified_email) { + $this->verified_email = $verified_email; + } + public function getVerified_email() { + return $this->verified_email; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiOrkutService.php b/inc/vendors/social-login/Google/contrib/apiOrkutService.php new file mode 100755 index 00000000..200d893f --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiOrkutService.php @@ -0,0 +1,2474 @@ + + * $orkutService = new apiOrkutService(...); + * $communityMembers = $orkutService->communityMembers; + * + */ + class CommunityMembersServiceResource extends apiServiceResource { + + + /** + * Makes the user join a community. (communityMembers.insert) + * @param int $communityId ID of the community. + * @param string $userId ID of the user. + * @return CommunityMembers + */ + public function insert($communityId, $userId, $optParams = array()) { + $params = array('communityId' => $communityId, 'userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new CommunityMembers($data); + } else { + return $data; + } + } + /** + * Retrieves the relationship between a user and a community. (communityMembers.get) + * @param int $communityId ID of the community. + * @param string $userId ID of the user. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityMembers + */ + public function get($communityId, $userId, $optParams = array()) { + $params = array('communityId' => $communityId, 'userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new CommunityMembers($data); + } else { + return $data; + } + } + /** + * Lists members of a community. (communityMembers.list) + * @param int $communityId The ID of the community whose members will be listed. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token that allows pagination. + * @opt_param bool friendsOnly Whether to list only community members who are friends of the user. + * @opt_param string maxResults The maximum number of members to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityMembersList + */ + public function listCommunityMembers($communityId, $optParams = array()) { + $params = array('communityId' => $communityId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommunityMembersList($data); + } else { + return $data; + } + } + /** + * Makes the user leave a community. (communityMembers.delete) + * @param int $communityId ID of the community. + * @param string $userId ID of the user. + */ + public function delete($communityId, $userId, $optParams = array()) { + $params = array('communityId' => $communityId, 'userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "activities" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $activities = $orkutService->activities; + * + */ + class ActivitiesServiceResource extends apiServiceResource { + + + /** + * Retrieves a list of activities. (activities.list) + * @param string $userId The ID of the user whose activities will be listed. Can be me to refer to the viewer (i.e. the authenticated user). + * @param string $collection The collection of activities to list. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token that allows pagination. + * @opt_param string maxResults The maximum number of activities to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return ActivityList + */ + public function listActivities($userId, $collection, $optParams = array()) { + $params = array('userId' => $userId, 'collection' => $collection); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new ActivityList($data); + } else { + return $data; + } + } + /** + * Deletes an existing activity, if the access controls allow it. (activities.delete) + * @param string $activityId ID of the activity to remove. + */ + public function delete($activityId, $optParams = array()) { + $params = array('activityId' => $activityId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "communityPollComments" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communityPollComments = $orkutService->communityPollComments; + * + */ + class CommunityPollCommentsServiceResource extends apiServiceResource { + + + /** + * Adds a comment on a community poll. (communityPollComments.insert) + * @param int $communityId The ID of the community whose poll is being commented. + * @param string $pollId The ID of the poll being commented. + * @param CommunityPollComment $postBody + * @return CommunityPollComment + */ + public function insert($communityId, $pollId, CommunityPollComment $postBody, $optParams = array()) { + $params = array('communityId' => $communityId, 'pollId' => $pollId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new CommunityPollComment($data); + } else { + return $data; + } + } + /** + * Retrieves the comments of a community poll. (communityPollComments.list) + * @param int $communityId The ID of the community whose poll is having its comments listed. + * @param string $pollId The ID of the community whose polls will be listed. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token that allows pagination. + * @opt_param string maxResults The maximum number of comments to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityPollCommentList + */ + public function listCommunityPollComments($communityId, $pollId, $optParams = array()) { + $params = array('communityId' => $communityId, 'pollId' => $pollId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommunityPollCommentList($data); + } else { + return $data; + } + } + } + + /** + * The "communityPolls" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communityPolls = $orkutService->communityPolls; + * + */ + class CommunityPollsServiceResource extends apiServiceResource { + + + /** + * Retrieves the polls of a community. (communityPolls.list) + * @param string $communityId The ID of the community which polls will be listed. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token that allows pagination. + * @opt_param string maxResults The maximum number of polls to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityPollList + */ + public function listCommunityPolls($communityId, $optParams = array()) { + $params = array('communityId' => $communityId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommunityPollList($data); + } else { + return $data; + } + } + /** + * Retrieves one specific poll of a community. (communityPolls.get) + * @param int $communityId The ID of the community for whose poll will be retrieved. + * @param string $pollId The ID of the poll to get. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityPoll + */ + public function get($communityId, $pollId, $optParams = array()) { + $params = array('communityId' => $communityId, 'pollId' => $pollId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new CommunityPoll($data); + } else { + return $data; + } + } + } + + /** + * The "communityMessages" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communityMessages = $orkutService->communityMessages; + * + */ + class CommunityMessagesServiceResource extends apiServiceResource { + + + /** + * Adds a message to a given community topic. (communityMessages.insert) + * @param int $communityId The ID of the community the message should be added to. + * @param string $topicId The ID of the topic the message should be added to. + * @param CommunityMessage $postBody + * @return CommunityMessage + */ + public function insert($communityId, $topicId, CommunityMessage $postBody, $optParams = array()) { + $params = array('communityId' => $communityId, 'topicId' => $topicId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new CommunityMessage($data); + } else { + return $data; + } + } + /** + * Retrieves the messages of a topic of a community. (communityMessages.list) + * @param int $communityId The ID of the community which messages will be listed. + * @param string $topicId The ID of the topic which messages will be listed. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token that allows pagination. + * @opt_param string maxResults The maximum number of messages to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityMessageList + */ + public function listCommunityMessages($communityId, $topicId, $optParams = array()) { + $params = array('communityId' => $communityId, 'topicId' => $topicId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommunityMessageList($data); + } else { + return $data; + } + } + /** + * Moves a message of the community to the trash folder. (communityMessages.delete) + * @param int $communityId The ID of the community whose message will be moved to the trash folder. + * @param string $topicId The ID of the topic whose message will be moved to the trash folder. + * @param string $messageId The ID of the message to be moved to the trash folder. + */ + public function delete($communityId, $topicId, $messageId, $optParams = array()) { + $params = array('communityId' => $communityId, 'topicId' => $topicId, 'messageId' => $messageId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "communityTopics" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communityTopics = $orkutService->communityTopics; + * + */ + class CommunityTopicsServiceResource extends apiServiceResource { + + + /** + * Adds a topic to a given community. (communityTopics.insert) + * @param int $communityId The ID of the community the topic should be added to. + * @param CommunityTopic $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool isShout Whether this topic is a shout. + * @return CommunityTopic + */ + public function insert($communityId, CommunityTopic $postBody, $optParams = array()) { + $params = array('communityId' => $communityId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new CommunityTopic($data); + } else { + return $data; + } + } + /** + * Retrieves a topic of a community. (communityTopics.get) + * @param int $communityId The ID of the community whose topic will be retrieved. + * @param string $topicId The ID of the topic to get. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityTopic + */ + public function get($communityId, $topicId, $optParams = array()) { + $params = array('communityId' => $communityId, 'topicId' => $topicId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new CommunityTopic($data); + } else { + return $data; + } + } + /** + * Retrieves the topics of a community. (communityTopics.list) + * @param int $communityId The ID of the community which topics will be listed. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken A continuation token that allows pagination. + * @opt_param string maxResults The maximum number of topics to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityTopicList + */ + public function listCommunityTopics($communityId, $optParams = array()) { + $params = array('communityId' => $communityId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommunityTopicList($data); + } else { + return $data; + } + } + /** + * Moves a topic of the community to the trash folder. (communityTopics.delete) + * @param int $communityId The ID of the community whose topic will be moved to the trash folder. + * @param string $topicId The ID of the topic to be moved to the trash folder. + */ + public function delete($communityId, $topicId, $optParams = array()) { + $params = array('communityId' => $communityId, 'topicId' => $topicId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "comments" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $comments = $orkutService->comments; + * + */ + class CommentsServiceResource extends apiServiceResource { + + + /** + * Inserts a new comment to an activity. (comments.insert) + * @param string $activityId The ID of the activity to contain the new comment. + * @param Comment $postBody + * @return Comment + */ + public function insert($activityId, Comment $postBody, $optParams = array()) { + $params = array('activityId' => $activityId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Comment($data); + } else { + return $data; + } + } + /** + * Retrieves an existing comment. (comments.get) + * @param string $commentId ID of the comment to get. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return Comment + */ + public function get($commentId, $optParams = array()) { + $params = array('commentId' => $commentId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Comment($data); + } else { + return $data; + } + } + /** + * Retrieves a list of comments, possibly filtered. (comments.list) + * @param string $activityId The ID of the activity containing the comments. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string orderBy Sort search results. + * @opt_param string pageToken A continuation token that allows pagination. + * @opt_param string maxResults The maximum number of activities to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommentList + */ + public function listComments($activityId, $optParams = array()) { + $params = array('activityId' => $activityId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommentList($data); + } else { + return $data; + } + } + /** + * Deletes an existing comment. (comments.delete) + * @param string $commentId ID of the comment to remove. + */ + public function delete($commentId, $optParams = array()) { + $params = array('commentId' => $commentId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "acl" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $acl = $orkutService->acl; + * + */ + class AclServiceResource extends apiServiceResource { + + + /** + * Excludes an element from the ACL of the activity. (acl.delete) + * @param string $activityId ID of the activity. + * @param string $userId ID of the user to be removed from the activity. + */ + public function delete($activityId, $userId, $optParams = array()) { + $params = array('activityId' => $activityId, 'userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "communityRelated" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communityRelated = $orkutService->communityRelated; + * + */ + class CommunityRelatedServiceResource extends apiServiceResource { + + + /** + * Retrieves the communities related to another one. (communityRelated.list) + * @param int $communityId The ID of the community whose related communities will be listed. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityList + */ + public function listCommunityRelated($communityId, $optParams = array()) { + $params = array('communityId' => $communityId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommunityList($data); + } else { + return $data; + } + } + } + + /** + * The "scraps" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $scraps = $orkutService->scraps; + * + */ + class ScrapsServiceResource extends apiServiceResource { + + + /** + * Creates a new scrap. (scraps.insert) + * @param Activity $postBody + * @return Activity + */ + public function insert(Activity $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Activity($data); + } else { + return $data; + } + } + } + + /** + * The "communityPollVotes" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communityPollVotes = $orkutService->communityPollVotes; + * + */ + class CommunityPollVotesServiceResource extends apiServiceResource { + + + /** + * Votes on a community poll. (communityPollVotes.insert) + * @param int $communityId The ID of the community whose poll is being voted. + * @param string $pollId The ID of the poll being voted. + * @param CommunityPollVote $postBody + * @return CommunityPollVote + */ + public function insert($communityId, $pollId, CommunityPollVote $postBody, $optParams = array()) { + $params = array('communityId' => $communityId, 'pollId' => $pollId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new CommunityPollVote($data); + } else { + return $data; + } + } + } + + /** + * The "communities" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communities = $orkutService->communities; + * + */ + class CommunitiesServiceResource extends apiServiceResource { + + + /** + * Retrieves the communities an user is member of. (communities.list) + * @param string $userId The ID of the user whose communities will be listed. Can be me to refer to caller. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string orderBy How to order the communities by. + * @opt_param string maxResults The maximum number of communities to include in the response. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return CommunityList + */ + public function listCommunities($userId, $optParams = array()) { + $params = array('userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommunityList($data); + } else { + return $data; + } + } + /** + * Retrieves the profile of a community. (communities.get) + * @param int $communityId The ID of the community to get. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string hl Specifies the interface language (host language) of your user interface. + * @return Community + */ + public function get($communityId, $optParams = array()) { + $params = array('communityId' => $communityId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Community($data); + } else { + return $data; + } + } + } + + /** + * The "communityFollow" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $communityFollow = $orkutService->communityFollow; + * + */ + class CommunityFollowServiceResource extends apiServiceResource { + + + /** + * Adds an user as a follower of a community. (communityFollow.insert) + * @param int $communityId ID of the community. + * @param string $userId ID of the user. + * @return CommunityMembers + */ + public function insert($communityId, $userId, $optParams = array()) { + $params = array('communityId' => $communityId, 'userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new CommunityMembers($data); + } else { + return $data; + } + } + /** + * Removes an user from the followers of a community. (communityFollow.delete) + * @param int $communityId ID of the community. + * @param string $userId ID of the user. + */ + public function delete($communityId, $userId, $optParams = array()) { + $params = array('communityId' => $communityId, 'userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "activityVisibility" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $activityVisibility = $orkutService->activityVisibility; + * + */ + class ActivityVisibilityServiceResource extends apiServiceResource { + + + /** + * Updates the visibility of an existing activity. This method supports patch semantics. + * (activityVisibility.patch) + * @param string $activityId ID of the activity. + * @param Visibility $postBody + * @return Visibility + */ + public function patch($activityId, Visibility $postBody, $optParams = array()) { + $params = array('activityId' => $activityId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Visibility($data); + } else { + return $data; + } + } + /** + * Updates the visibility of an existing activity. (activityVisibility.update) + * @param string $activityId ID of the activity. + * @param Visibility $postBody + * @return Visibility + */ + public function update($activityId, Visibility $postBody, $optParams = array()) { + $params = array('activityId' => $activityId, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Visibility($data); + } else { + return $data; + } + } + /** + * Gets the visibility of an existing activity. (activityVisibility.get) + * @param string $activityId ID of the activity to get the visibility. + * @return Visibility + */ + public function get($activityId, $optParams = array()) { + $params = array('activityId' => $activityId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Visibility($data); + } else { + return $data; + } + } + } + + /** + * The "badges" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $badges = $orkutService->badges; + * + */ + class BadgesServiceResource extends apiServiceResource { + + + /** + * Retrieves the list of visible badges of a user. (badges.list) + * @param string $userId The id of the user whose badges will be listed. Can be me to refer to caller. + * @return BadgeList + */ + public function listBadges($userId, $optParams = array()) { + $params = array('userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new BadgeList($data); + } else { + return $data; + } + } + /** + * Retrieves a badge from a user. (badges.get) + * @param string $userId The ID of the user whose badges will be listed. Can be me to refer to caller. + * @param string $badgeId The ID of the badge that will be retrieved. + * @return Badge + */ + public function get($userId, $badgeId, $optParams = array()) { + $params = array('userId' => $userId, 'badgeId' => $badgeId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Badge($data); + } else { + return $data; + } + } + } + + /** + * The "counters" collection of methods. + * Typical usage is: + * + * $orkutService = new apiOrkutService(...); + * $counters = $orkutService->counters; + * + */ + class CountersServiceResource extends apiServiceResource { + + + /** + * Retrieves the counters of an user. (counters.list) + * @param string $userId The ID of the user whose counters will be listed. Can be me to refer to caller. + * @return Counters + */ + public function listCounters($userId, $optParams = array()) { + $params = array('userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Counters($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Orkut (v2). + *

            + * Lets you manage activities, comments and badges in Orkut. More stuff coming in time. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiOrkutService extends apiService { + public $communityMembers; + public $activities; + public $communityPollComments; + public $communityPolls; + public $communityMessages; + public $communityTopics; + public $comments; + public $acl; + public $communityRelated; + public $scraps; + public $communityPollVotes; + public $communities; + public $communityFollow; + public $activityVisibility; + public $badges; + public $counters; + /** + * Constructs the internal representation of the Orkut service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/orkut/v2/'; + $this->version = 'v2'; + $this->serviceName = 'orkut'; + + $apiClient->addService($this->serviceName, $this->version); + $this->communityMembers = new CommunityMembersServiceResource($this, $this->serviceName, 'communityMembers', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "userId": {"required": true, "type": "string", "location": "path"}}, "id": "orkut.communityMembers.insert", "httpMethod": "POST", "path": "communities/{communityId}/members/{userId}", "response": {"$ref": "CommunityMembers"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "userId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "communities/{communityId}/members/{userId}", "id": "orkut.communityMembers.delete"}, "list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "friendsOnly": {"type": "boolean", "location": "query"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "minimum": "1", "type": "integer", "location": "query"}}, "id": "orkut.communityMembers.list", "httpMethod": "GET", "path": "communities/{communityId}/members", "response": {"$ref": "CommunityMembersList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "userId": {"required": true, "type": "string", "location": "path"}, "hl": {"type": "string", "location": "query"}}, "id": "orkut.communityMembers.get", "httpMethod": "GET", "path": "communities/{communityId}/members/{userId}", "response": {"$ref": "CommunityMembers"}}}}', true)); + $this->activities = new ActivitiesServiceResource($this, $this->serviceName, 'activities', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"collection": {"required": true, "enum": ["all", "scraps", "stream"], "location": "path", "type": "string"}, "pageToken": {"type": "string", "location": "query"}, "userId": {"required": true, "type": "string", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "maximum": "100", "minimum": "1", "location": "query", "type": "integer"}}, "id": "orkut.activities.list", "httpMethod": "GET", "path": "people/{userId}/activities/{collection}", "response": {"$ref": "ActivityList"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"activityId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "activities/{activityId}", "id": "orkut.activities.delete"}}}', true)); + $this->communityPollComments = new CommunityPollCommentsServiceResource($this, $this->serviceName, 'communityPollComments', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "pollId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "CommunityPollComment"}, "id": "orkut.communityPollComments.insert", "httpMethod": "POST", "path": "communities/{communityId}/polls/{pollId}/comments", "response": {"$ref": "CommunityPollComment"}}, "list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "minimum": "1", "type": "integer", "location": "query"}, "pollId": {"required": true, "type": "string", "location": "path"}}, "id": "orkut.communityPollComments.list", "httpMethod": "GET", "path": "communities/{communityId}/polls/{pollId}/comments", "response": {"$ref": "CommunityPollCommentList"}}}}', true)); + $this->communityPolls = new CommunityPollsServiceResource($this, $this->serviceName, 'communityPolls', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "communityId": {"required": true, "type": "string", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "minimum": "1", "type": "integer", "location": "query"}}, "id": "orkut.communityPolls.list", "httpMethod": "GET", "path": "communities/{communityId}/polls", "response": {"$ref": "CommunityPollList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}, "pollId": {"required": true, "type": "string", "location": "path"}}, "id": "orkut.communityPolls.get", "httpMethod": "GET", "path": "communities/{communityId}/polls/{pollId}", "response": {"$ref": "CommunityPoll"}}}}', true)); + $this->communityMessages = new CommunityMessagesServiceResource($this, $this->serviceName, 'communityMessages', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"topicId": {"format": "uint64", "required": true, "type": "string", "location": "path"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "CommunityMessage"}, "id": "orkut.communityMessages.insert", "httpMethod": "POST", "path": "communities/{communityId}/topics/{topicId}/messages", "response": {"$ref": "CommunityMessage"}}, "list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "maximum": "100", "minimum": "1", "location": "query", "type": "integer"}, "topicId": {"format": "uint64", "required": true, "type": "string", "location": "path"}}, "id": "orkut.communityMessages.list", "httpMethod": "GET", "path": "communities/{communityId}/topics/{topicId}/messages", "response": {"$ref": "CommunityMessageList"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"topicId": {"format": "uint64", "required": true, "type": "string", "location": "path"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "messageId": {"format": "uint64", "required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "communities/{communityId}/topics/{topicId}/messages/{messageId}", "id": "orkut.communityMessages.delete"}}}', true)); + $this->communityTopics = new CommunityTopicsServiceResource($this, $this->serviceName, 'communityTopics', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"isShout": {"type": "boolean", "location": "query"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}}, "request": {"$ref": "CommunityTopic"}, "id": "orkut.communityTopics.insert", "httpMethod": "POST", "path": "communities/{communityId}/topics", "response": {"$ref": "CommunityTopic"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"topicId": {"format": "uint64", "required": true, "type": "string", "location": "path"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}}, "httpMethod": "DELETE", "path": "communities/{communityId}/topics/{topicId}", "id": "orkut.communityTopics.delete"}, "list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "maximum": "100", "minimum": "1", "location": "query", "type": "integer"}}, "id": "orkut.communityTopics.list", "httpMethod": "GET", "path": "communities/{communityId}/topics", "response": {"$ref": "CommunityTopicList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"topicId": {"format": "uint64", "required": true, "type": "string", "location": "path"}, "communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}}, "id": "orkut.communityTopics.get", "httpMethod": "GET", "path": "communities/{communityId}/topics/{topicId}", "response": {"$ref": "CommunityTopic"}}}}', true)); + $this->comments = new CommentsServiceResource($this, $this->serviceName, 'comments', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"activityId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Comment"}, "id": "orkut.comments.insert", "httpMethod": "POST", "path": "activities/{activityId}/comments", "response": {"$ref": "Comment"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"commentId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "comments/{commentId}", "id": "orkut.comments.delete"}, "list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"orderBy": {"default": "DESCENDING_SORT", "enum": ["ascending", "descending"], "location": "query", "type": "string"}, "pageToken": {"type": "string", "location": "query"}, "activityId": {"required": true, "type": "string", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "minimum": "1", "type": "integer", "location": "query"}}, "id": "orkut.comments.list", "httpMethod": "GET", "path": "activities/{activityId}/comments", "response": {"$ref": "CommentList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"commentId": {"required": true, "type": "string", "location": "path"}, "hl": {"type": "string", "location": "query"}}, "id": "orkut.comments.get", "httpMethod": "GET", "path": "comments/{commentId}", "response": {"$ref": "Comment"}}}}', true)); + $this->acl = new AclServiceResource($this, $this->serviceName, 'acl', json_decode('{"methods": {"delete": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"activityId": {"required": true, "type": "string", "location": "path"}, "userId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "activities/{activityId}/acl/{userId}", "id": "orkut.acl.delete"}}}', true)); + $this->communityRelated = new CommunityRelatedServiceResource($this, $this->serviceName, 'communityRelated', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}}, "id": "orkut.communityRelated.list", "httpMethod": "GET", "path": "communities/{communityId}/related", "response": {"$ref": "CommunityList"}}}}', true)); + $this->scraps = new ScrapsServiceResource($this, $this->serviceName, 'scraps', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "request": {"$ref": "Activity"}, "response": {"$ref": "Activity"}, "httpMethod": "POST", "path": "activities/scraps", "id": "orkut.scraps.insert"}}}', true)); + $this->communityPollVotes = new CommunityPollVotesServiceResource($this, $this->serviceName, 'communityPollVotes', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "pollId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "CommunityPollVote"}, "id": "orkut.communityPollVotes.insert", "httpMethod": "POST", "path": "communities/{communityId}/polls/{pollId}/votes", "response": {"$ref": "CommunityPollVote"}}}}', true)); + $this->communities = new CommunitiesServiceResource($this, $this->serviceName, 'communities', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"orderBy": {"enum": ["id", "ranked"], "type": "string", "location": "query"}, "userId": {"required": true, "type": "string", "location": "path"}, "hl": {"type": "string", "location": "query"}, "maxResults": {"format": "uint32", "minimum": "1", "type": "integer", "location": "query"}}, "id": "orkut.communities.list", "httpMethod": "GET", "path": "people/{userId}/communities", "response": {"$ref": "CommunityList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "hl": {"type": "string", "location": "query"}}, "id": "orkut.communities.get", "httpMethod": "GET", "path": "communities/{communityId}", "response": {"$ref": "Community"}}}}', true)); + $this->communityFollow = new CommunityFollowServiceResource($this, $this->serviceName, 'communityFollow', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "userId": {"required": true, "type": "string", "location": "path"}}, "id": "orkut.communityFollow.insert", "httpMethod": "POST", "path": "communities/{communityId}/followers/{userId}", "response": {"$ref": "CommunityMembers"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"communityId": {"format": "int32", "required": true, "type": "integer", "location": "path"}, "userId": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "communities/{communityId}/followers/{userId}", "id": "orkut.communityFollow.delete"}}}', true)); + $this->activityVisibility = new ActivityVisibilityServiceResource($this, $this->serviceName, 'activityVisibility', json_decode('{"methods": {"get": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"activityId": {"required": true, "type": "string", "location": "path"}}, "id": "orkut.activityVisibility.get", "httpMethod": "GET", "path": "activities/{activityId}/visibility", "response": {"$ref": "Visibility"}}, "update": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"activityId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Visibility"}, "id": "orkut.activityVisibility.update", "httpMethod": "PUT", "path": "activities/{activityId}/visibility", "response": {"$ref": "Visibility"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/orkut"], "parameters": {"activityId": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Visibility"}, "id": "orkut.activityVisibility.patch", "httpMethod": "PATCH", "path": "activities/{activityId}/visibility", "response": {"$ref": "Visibility"}}}}', true)); + $this->badges = new BadgesServiceResource($this, $this->serviceName, 'badges', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"userId": {"required": true, "type": "string", "location": "path"}}, "id": "orkut.badges.list", "httpMethod": "GET", "path": "people/{userId}/badges", "response": {"$ref": "BadgeList"}}, "get": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"userId": {"required": true, "type": "string", "location": "path"}, "badgeId": {"format": "int64", "required": true, "type": "string", "location": "path"}}, "id": "orkut.badges.get", "httpMethod": "GET", "path": "people/{userId}/badges/{badgeId}", "response": {"$ref": "Badge"}}}}', true)); + $this->counters = new CountersServiceResource($this, $this->serviceName, 'counters', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/orkut", "https://www.googleapis.com/auth/orkut.readonly"], "parameters": {"userId": {"required": true, "type": "string", "location": "path"}}, "id": "orkut.counters.list", "httpMethod": "GET", "path": "people/{userId}/counters", "response": {"$ref": "Counters"}}}}', true)); + } +} + +class Acl extends apiModel { + protected $__itemsType = 'AclItems'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $description; + public $totalParticipants; + public function setItems(/* array(AclItems) */ $items) { + $this->assertIsArray($items, 'AclItems', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setTotalParticipants($totalParticipants) { + $this->totalParticipants = $totalParticipants; + } + public function getTotalParticipants() { + return $this->totalParticipants; + } +} + +class AclItems extends apiModel { + public $type; + public $id; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class Activity extends apiModel { + public $kind; + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + public $title; + protected $__objectType = 'ActivityObject'; + protected $__objectDataType = ''; + public $object; + public $updated; + protected $__actorType = 'OrkutAuthorResource'; + protected $__actorDataType = ''; + public $actor; + protected $__accessType = 'Acl'; + protected $__accessDataType = ''; + public $access; + public $verb; + public $published; + public $id; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setObject(ActivityObject $object) { + $this->object = $object; + } + public function getObject() { + return $this->object; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setActor(OrkutAuthorResource $actor) { + $this->actor = $actor; + } + public function getActor() { + return $this->actor; + } + public function setAccess(Acl $access) { + $this->access = $access; + } + public function getAccess() { + return $this->access; + } + public function setVerb($verb) { + $this->verb = $verb; + } + public function getVerb() { + return $this->verb; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ActivityList extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Activity'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Activity) */ $items) { + $this->assertIsArray($items, 'Activity', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class ActivityObject extends apiModel { + public $content; + protected $__itemsType = 'OrkutActivityobjectsResource'; + protected $__itemsDataType = 'array'; + public $items; + protected $__repliesType = 'ActivityObjectReplies'; + protected $__repliesDataType = ''; + public $replies; + public $objectType; + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setItems(/* array(OrkutActivityobjectsResource) */ $items) { + $this->assertIsArray($items, 'OrkutActivityobjectsResource', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setReplies(ActivityObjectReplies $replies) { + $this->replies = $replies; + } + public function getReplies() { + return $this->replies; + } + public function setObjectType($objectType) { + $this->objectType = $objectType; + } + public function getObjectType() { + return $this->objectType; + } +} + +class ActivityObjectReplies extends apiModel { + public $totalItems; + protected $__itemsType = 'Comment'; + protected $__itemsDataType = 'array'; + public $items; + public $url; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setItems(/* array(Comment) */ $items) { + $this->assertIsArray($items, 'Comment', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class Badge extends apiModel { + public $badgeSmallLogo; + public $kind; + public $description; + public $sponsorLogo; + public $sponsorName; + public $badgeLargeLogo; + public $caption; + public $sponsorUrl; + public $id; + public function setBadgeSmallLogo($badgeSmallLogo) { + $this->badgeSmallLogo = $badgeSmallLogo; + } + public function getBadgeSmallLogo() { + return $this->badgeSmallLogo; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setSponsorLogo($sponsorLogo) { + $this->sponsorLogo = $sponsorLogo; + } + public function getSponsorLogo() { + return $this->sponsorLogo; + } + public function setSponsorName($sponsorName) { + $this->sponsorName = $sponsorName; + } + public function getSponsorName() { + return $this->sponsorName; + } + public function setBadgeLargeLogo($badgeLargeLogo) { + $this->badgeLargeLogo = $badgeLargeLogo; + } + public function getBadgeLargeLogo() { + return $this->badgeLargeLogo; + } + public function setCaption($caption) { + $this->caption = $caption; + } + public function getCaption() { + return $this->caption; + } + public function setSponsorUrl($sponsorUrl) { + $this->sponsorUrl = $sponsorUrl; + } + public function getSponsorUrl() { + return $this->sponsorUrl; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class BadgeList extends apiModel { + protected $__itemsType = 'Badge'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Badge) */ $items) { + $this->assertIsArray($items, 'Badge', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class Comment extends apiModel { + protected $__inReplyToType = 'CommentInReplyTo'; + protected $__inReplyToDataType = ''; + public $inReplyTo; + public $kind; + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + protected $__actorType = 'OrkutAuthorResource'; + protected $__actorDataType = ''; + public $actor; + public $content; + public $published; + public $id; + public function setInReplyTo(CommentInReplyTo $inReplyTo) { + $this->inReplyTo = $inReplyTo; + } + public function getInReplyTo() { + return $this->inReplyTo; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setActor(OrkutAuthorResource $actor) { + $this->actor = $actor; + } + public function getActor() { + return $this->actor; + } + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CommentInReplyTo extends apiModel { + public $type; + public $href; + public $ref; + public $rel; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setRef($ref) { + $this->ref = $ref; + } + public function getRef() { + return $this->ref; + } + public function setRel($rel) { + $this->rel = $rel; + } + public function getRel() { + return $this->rel; + } +} + +class CommentList extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Comment'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $previousPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Comment) */ $items) { + $this->assertIsArray($items, 'Comment', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setPreviousPageToken($previousPageToken) { + $this->previousPageToken = $previousPageToken; + } + public function getPreviousPageToken() { + return $this->previousPageToken; + } +} + +class Community extends apiModel { + public $category; + public $kind; + public $member_count; + public $description; + public $language; + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + public $creation_date; + protected $__ownerType = 'OrkutAuthorResource'; + protected $__ownerDataType = ''; + public $owner; + protected $__moderatorsType = 'OrkutAuthorResource'; + protected $__moderatorsDataType = 'array'; + public $moderators; + public $location; + protected $__co_ownersType = 'OrkutAuthorResource'; + protected $__co_ownersDataType = 'array'; + public $co_owners; + public $photo_url; + public $id; + public $name; + public function setCategory($category) { + $this->category = $category; + } + public function getCategory() { + return $this->category; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setMember_count($member_count) { + $this->member_count = $member_count; + } + public function getMember_count() { + return $this->member_count; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setCreation_date($creation_date) { + $this->creation_date = $creation_date; + } + public function getCreation_date() { + return $this->creation_date; + } + public function setOwner(OrkutAuthorResource $owner) { + $this->owner = $owner; + } + public function getOwner() { + return $this->owner; + } + public function setModerators(/* array(OrkutAuthorResource) */ $moderators) { + $this->assertIsArray($moderators, 'OrkutAuthorResource', __METHOD__); + $this->moderators = $moderators; + } + public function getModerators() { + return $this->moderators; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setCo_owners(/* array(OrkutAuthorResource) */ $co_owners) { + $this->assertIsArray($co_owners, 'OrkutAuthorResource', __METHOD__); + $this->co_owners = $co_owners; + } + public function getCo_owners() { + return $this->co_owners; + } + public function setPhoto_url($photo_url) { + $this->photo_url = $photo_url; + } + public function getPhoto_url() { + return $this->photo_url; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class CommunityList extends apiModel { + protected $__itemsType = 'Community'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Community) */ $items) { + $this->assertIsArray($items, 'Community', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class CommunityMembers extends apiModel { + protected $__communityMembershipStatusType = 'CommunityMembershipStatus'; + protected $__communityMembershipStatusDataType = ''; + public $communityMembershipStatus; + protected $__personType = 'OrkutActivitypersonResource'; + protected $__personDataType = ''; + public $person; + public $kind; + public function setCommunityMembershipStatus(CommunityMembershipStatus $communityMembershipStatus) { + $this->communityMembershipStatus = $communityMembershipStatus; + } + public function getCommunityMembershipStatus() { + return $this->communityMembershipStatus; + } + public function setPerson(OrkutActivitypersonResource $person) { + $this->person = $person; + } + public function getPerson() { + return $this->person; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class CommunityMembersList extends apiModel { + public $nextPageToken; + public $kind; + protected $__itemsType = 'CommunityMembers'; + protected $__itemsDataType = 'array'; + public $items; + public $prevPageToken; + public $lastPageToken; + public $firstPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(CommunityMembers) */ $items) { + $this->assertIsArray($items, 'CommunityMembers', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setPrevPageToken($prevPageToken) { + $this->prevPageToken = $prevPageToken; + } + public function getPrevPageToken() { + return $this->prevPageToken; + } + public function setLastPageToken($lastPageToken) { + $this->lastPageToken = $lastPageToken; + } + public function getLastPageToken() { + return $this->lastPageToken; + } + public function setFirstPageToken($firstPageToken) { + $this->firstPageToken = $firstPageToken; + } + public function getFirstPageToken() { + return $this->firstPageToken; + } +} + +class CommunityMembershipStatus extends apiModel { + public $status; + public $isFollowing; + public $isRestoreAvailable; + public $isModerator; + public $kind; + public $isCoOwner; + public $canCreatePoll; + public $canShout; + public $isOwner; + public $canCreateTopic; + public $isTakebackAvailable; + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setIsFollowing($isFollowing) { + $this->isFollowing = $isFollowing; + } + public function getIsFollowing() { + return $this->isFollowing; + } + public function setIsRestoreAvailable($isRestoreAvailable) { + $this->isRestoreAvailable = $isRestoreAvailable; + } + public function getIsRestoreAvailable() { + return $this->isRestoreAvailable; + } + public function setIsModerator($isModerator) { + $this->isModerator = $isModerator; + } + public function getIsModerator() { + return $this->isModerator; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setIsCoOwner($isCoOwner) { + $this->isCoOwner = $isCoOwner; + } + public function getIsCoOwner() { + return $this->isCoOwner; + } + public function setCanCreatePoll($canCreatePoll) { + $this->canCreatePoll = $canCreatePoll; + } + public function getCanCreatePoll() { + return $this->canCreatePoll; + } + public function setCanShout($canShout) { + $this->canShout = $canShout; + } + public function getCanShout() { + return $this->canShout; + } + public function setIsOwner($isOwner) { + $this->isOwner = $isOwner; + } + public function getIsOwner() { + return $this->isOwner; + } + public function setCanCreateTopic($canCreateTopic) { + $this->canCreateTopic = $canCreateTopic; + } + public function getCanCreateTopic() { + return $this->canCreateTopic; + } + public function setIsTakebackAvailable($isTakebackAvailable) { + $this->isTakebackAvailable = $isTakebackAvailable; + } + public function getIsTakebackAvailable() { + return $this->isTakebackAvailable; + } +} + +class CommunityMessage extends apiModel { + public $body; + public $kind; + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + protected $__authorType = 'OrkutAuthorResource'; + protected $__authorDataType = ''; + public $author; + public $id; + public $addedDate; + public $isSpam; + public $subject; + public function setBody($body) { + $this->body = $body; + } + public function getBody() { + return $this->body; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setAuthor(OrkutAuthorResource $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setAddedDate($addedDate) { + $this->addedDate = $addedDate; + } + public function getAddedDate() { + return $this->addedDate; + } + public function setIsSpam($isSpam) { + $this->isSpam = $isSpam; + } + public function getIsSpam() { + return $this->isSpam; + } + public function setSubject($subject) { + $this->subject = $subject; + } + public function getSubject() { + return $this->subject; + } +} + +class CommunityMessageList extends apiModel { + public $nextPageToken; + public $kind; + protected $__itemsType = 'CommunityMessage'; + protected $__itemsDataType = 'array'; + public $items; + public $prevPageToken; + public $lastPageToken; + public $firstPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(CommunityMessage) */ $items) { + $this->assertIsArray($items, 'CommunityMessage', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setPrevPageToken($prevPageToken) { + $this->prevPageToken = $prevPageToken; + } + public function getPrevPageToken() { + return $this->prevPageToken; + } + public function setLastPageToken($lastPageToken) { + $this->lastPageToken = $lastPageToken; + } + public function getLastPageToken() { + return $this->lastPageToken; + } + public function setFirstPageToken($firstPageToken) { + $this->firstPageToken = $firstPageToken; + } + public function getFirstPageToken() { + return $this->firstPageToken; + } +} + +class CommunityPoll extends apiModel { + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + public $isMultipleAnswers; + protected $__imageType = 'CommunityPollImage'; + protected $__imageDataType = ''; + public $image; + public $endingTime; + public $isVotingAllowedForNonMembers; + public $isSpam; + public $totalNumberOfVotes; + protected $__authorType = 'OrkutAuthorResource'; + protected $__authorDataType = ''; + public $author; + public $question; + public $id; + public $isRestricted; + public $communityId; + public $isUsersVotePublic; + public $lastUpdate; + public $description; + public $votedOptions; + public $isOpenForVoting; + public $isClosed; + public $hasVoted; + public $kind; + public $creationTime; + protected $__optionsType = 'OrkutCommunitypolloptionResource'; + protected $__optionsDataType = 'array'; + public $options; + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setIsMultipleAnswers($isMultipleAnswers) { + $this->isMultipleAnswers = $isMultipleAnswers; + } + public function getIsMultipleAnswers() { + return $this->isMultipleAnswers; + } + public function setImage(CommunityPollImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setEndingTime($endingTime) { + $this->endingTime = $endingTime; + } + public function getEndingTime() { + return $this->endingTime; + } + public function setIsVotingAllowedForNonMembers($isVotingAllowedForNonMembers) { + $this->isVotingAllowedForNonMembers = $isVotingAllowedForNonMembers; + } + public function getIsVotingAllowedForNonMembers() { + return $this->isVotingAllowedForNonMembers; + } + public function setIsSpam($isSpam) { + $this->isSpam = $isSpam; + } + public function getIsSpam() { + return $this->isSpam; + } + public function setTotalNumberOfVotes($totalNumberOfVotes) { + $this->totalNumberOfVotes = $totalNumberOfVotes; + } + public function getTotalNumberOfVotes() { + return $this->totalNumberOfVotes; + } + public function setAuthor(OrkutAuthorResource $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setQuestion($question) { + $this->question = $question; + } + public function getQuestion() { + return $this->question; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setIsRestricted($isRestricted) { + $this->isRestricted = $isRestricted; + } + public function getIsRestricted() { + return $this->isRestricted; + } + public function setCommunityId($communityId) { + $this->communityId = $communityId; + } + public function getCommunityId() { + return $this->communityId; + } + public function setIsUsersVotePublic($isUsersVotePublic) { + $this->isUsersVotePublic = $isUsersVotePublic; + } + public function getIsUsersVotePublic() { + return $this->isUsersVotePublic; + } + public function setLastUpdate($lastUpdate) { + $this->lastUpdate = $lastUpdate; + } + public function getLastUpdate() { + return $this->lastUpdate; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setVotedOptions(/* array(int) */ $votedOptions) { + $this->assertIsArray($votedOptions, 'int', __METHOD__); + $this->votedOptions = $votedOptions; + } + public function getVotedOptions() { + return $this->votedOptions; + } + public function setIsOpenForVoting($isOpenForVoting) { + $this->isOpenForVoting = $isOpenForVoting; + } + public function getIsOpenForVoting() { + return $this->isOpenForVoting; + } + public function setIsClosed($isClosed) { + $this->isClosed = $isClosed; + } + public function getIsClosed() { + return $this->isClosed; + } + public function setHasVoted($hasVoted) { + $this->hasVoted = $hasVoted; + } + public function getHasVoted() { + return $this->hasVoted; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setCreationTime($creationTime) { + $this->creationTime = $creationTime; + } + public function getCreationTime() { + return $this->creationTime; + } + public function setOptions(/* array(OrkutCommunitypolloptionResource) */ $options) { + $this->assertIsArray($options, 'OrkutCommunitypolloptionResource', __METHOD__); + $this->options = $options; + } + public function getOptions() { + return $this->options; + } +} + +class CommunityPollComment extends apiModel { + public $body; + public $kind; + public $addedDate; + public $id; + protected $__authorType = 'OrkutAuthorResource'; + protected $__authorDataType = ''; + public $author; + public function setBody($body) { + $this->body = $body; + } + public function getBody() { + return $this->body; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setAddedDate($addedDate) { + $this->addedDate = $addedDate; + } + public function getAddedDate() { + return $this->addedDate; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setAuthor(OrkutAuthorResource $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } +} + +class CommunityPollCommentList extends apiModel { + public $nextPageToken; + public $kind; + protected $__itemsType = 'CommunityPollComment'; + protected $__itemsDataType = 'array'; + public $items; + public $prevPageToken; + public $lastPageToken; + public $firstPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(CommunityPollComment) */ $items) { + $this->assertIsArray($items, 'CommunityPollComment', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setPrevPageToken($prevPageToken) { + $this->prevPageToken = $prevPageToken; + } + public function getPrevPageToken() { + return $this->prevPageToken; + } + public function setLastPageToken($lastPageToken) { + $this->lastPageToken = $lastPageToken; + } + public function getLastPageToken() { + return $this->lastPageToken; + } + public function setFirstPageToken($firstPageToken) { + $this->firstPageToken = $firstPageToken; + } + public function getFirstPageToken() { + return $this->firstPageToken; + } +} + +class CommunityPollImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class CommunityPollList extends apiModel { + public $nextPageToken; + public $kind; + protected $__itemsType = 'CommunityPoll'; + protected $__itemsDataType = 'array'; + public $items; + public $prevPageToken; + public $lastPageToken; + public $firstPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(CommunityPoll) */ $items) { + $this->assertIsArray($items, 'CommunityPoll', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setPrevPageToken($prevPageToken) { + $this->prevPageToken = $prevPageToken; + } + public function getPrevPageToken() { + return $this->prevPageToken; + } + public function setLastPageToken($lastPageToken) { + $this->lastPageToken = $lastPageToken; + } + public function getLastPageToken() { + return $this->lastPageToken; + } + public function setFirstPageToken($firstPageToken) { + $this->firstPageToken = $firstPageToken; + } + public function getFirstPageToken() { + return $this->firstPageToken; + } +} + +class CommunityPollVote extends apiModel { + public $kind; + public $optionIds; + public $isVotevisible; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setOptionIds(/* array(int) */ $optionIds) { + $this->assertIsArray($optionIds, 'int', __METHOD__); + $this->optionIds = $optionIds; + } + public function getOptionIds() { + return $this->optionIds; + } + public function setIsVotevisible($isVotevisible) { + $this->isVotevisible = $isVotevisible; + } + public function getIsVotevisible() { + return $this->isVotevisible; + } +} + +class CommunityTopic extends apiModel { + public $body; + public $lastUpdate; + public $kind; + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + protected $__authorType = 'OrkutAuthorResource'; + protected $__authorDataType = ''; + public $author; + public $title; + protected $__messagesType = 'CommunityMessage'; + protected $__messagesDataType = 'array'; + public $messages; + public $latestMessageSnippet; + public $isClosed; + public $numberOfReplies; + public $id; + public function setBody($body) { + $this->body = $body; + } + public function getBody() { + return $this->body; + } + public function setLastUpdate($lastUpdate) { + $this->lastUpdate = $lastUpdate; + } + public function getLastUpdate() { + return $this->lastUpdate; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setAuthor(OrkutAuthorResource $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setMessages(/* array(CommunityMessage) */ $messages) { + $this->assertIsArray($messages, 'CommunityMessage', __METHOD__); + $this->messages = $messages; + } + public function getMessages() { + return $this->messages; + } + public function setLatestMessageSnippet($latestMessageSnippet) { + $this->latestMessageSnippet = $latestMessageSnippet; + } + public function getLatestMessageSnippet() { + return $this->latestMessageSnippet; + } + public function setIsClosed($isClosed) { + $this->isClosed = $isClosed; + } + public function getIsClosed() { + return $this->isClosed; + } + public function setNumberOfReplies($numberOfReplies) { + $this->numberOfReplies = $numberOfReplies; + } + public function getNumberOfReplies() { + return $this->numberOfReplies; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CommunityTopicList extends apiModel { + public $nextPageToken; + public $kind; + protected $__itemsType = 'CommunityTopic'; + protected $__itemsDataType = 'array'; + public $items; + public $prevPageToken; + public $lastPageToken; + public $firstPageToken; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItems(/* array(CommunityTopic) */ $items) { + $this->assertIsArray($items, 'CommunityTopic', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setPrevPageToken($prevPageToken) { + $this->prevPageToken = $prevPageToken; + } + public function getPrevPageToken() { + return $this->prevPageToken; + } + public function setLastPageToken($lastPageToken) { + $this->lastPageToken = $lastPageToken; + } + public function getLastPageToken() { + return $this->lastPageToken; + } + public function setFirstPageToken($firstPageToken) { + $this->firstPageToken = $firstPageToken; + } + public function getFirstPageToken() { + return $this->firstPageToken; + } +} + +class Counters extends apiModel { + protected $__itemsType = 'OrkutCounterResource'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(OrkutCounterResource) */ $items) { + $this->assertIsArray($items, 'OrkutCounterResource', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} + +class OrkutActivityobjectsResource extends apiModel { + public $displayName; + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + public $content; + protected $__personType = 'OrkutActivitypersonResource'; + protected $__personDataType = ''; + public $person; + public $id; + public $objectType; + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setPerson(OrkutActivitypersonResource $person) { + $this->person = $person; + } + public function getPerson() { + return $this->person; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setObjectType($objectType) { + $this->objectType = $objectType; + } + public function getObjectType() { + return $this->objectType; + } +} + +class OrkutActivitypersonResource extends apiModel { + protected $__nameType = 'OrkutActivitypersonResourceName'; + protected $__nameDataType = ''; + public $name; + public $url; + public $gender; + protected $__imageType = 'OrkutActivitypersonResourceImage'; + protected $__imageDataType = ''; + public $image; + public $birthday; + public $id; + public function setName(OrkutActivitypersonResourceName $name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setGender($gender) { + $this->gender = $gender; + } + public function getGender() { + return $this->gender; + } + public function setImage(OrkutActivitypersonResourceImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setBirthday($birthday) { + $this->birthday = $birthday; + } + public function getBirthday() { + return $this->birthday; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class OrkutActivitypersonResourceImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class OrkutActivitypersonResourceName extends apiModel { + public $givenName; + public $familyName; + public function setGivenName($givenName) { + $this->givenName = $givenName; + } + public function getGivenName() { + return $this->givenName; + } + public function setFamilyName($familyName) { + $this->familyName = $familyName; + } + public function getFamilyName() { + return $this->familyName; + } +} + +class OrkutAuthorResource extends apiModel { + public $url; + protected $__imageType = 'OrkutAuthorResourceImage'; + protected $__imageDataType = ''; + public $image; + public $displayName; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(OrkutAuthorResourceImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class OrkutAuthorResourceImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class OrkutCommunitypolloptionResource extends apiModel { + protected $__imageType = 'OrkutCommunitypolloptionResourceImage'; + protected $__imageDataType = ''; + public $image; + public $optionId; + public $description; + public $numberOfVotes; + public function setImage(OrkutCommunitypolloptionResourceImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setOptionId($optionId) { + $this->optionId = $optionId; + } + public function getOptionId() { + return $this->optionId; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setNumberOfVotes($numberOfVotes) { + $this->numberOfVotes = $numberOfVotes; + } + public function getNumberOfVotes() { + return $this->numberOfVotes; + } +} + +class OrkutCommunitypolloptionResourceImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class OrkutCounterResource extends apiModel { + public $total; + protected $__linkType = 'OrkutLinkResource'; + protected $__linkDataType = ''; + public $link; + public $name; + public function setTotal($total) { + $this->total = $total; + } + public function getTotal() { + return $this->total; + } + public function setLink(OrkutLinkResource $link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class OrkutLinkResource extends apiModel { + public $href; + public $type; + public $rel; + public $title; + public function setHref($href) { + $this->href = $href; + } + public function getHref() { + return $this->href; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setRel($rel) { + $this->rel = $rel; + } + public function getRel() { + return $this->rel; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } +} + +class Visibility extends apiModel { + public $kind; + public $visibility; + protected $__linksType = 'OrkutLinkResource'; + protected $__linksDataType = 'array'; + public $links; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setVisibility($visibility) { + $this->visibility = $visibility; + } + public function getVisibility() { + return $this->visibility; + } + public function setLinks(/* array(OrkutLinkResource) */ $links) { + $this->assertIsArray($links, 'OrkutLinkResource', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiPagespeedonlineService.php b/inc/vendors/social-login/Google/contrib/apiPagespeedonlineService.php new file mode 100755 index 00000000..f0ba9122 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiPagespeedonlineService.php @@ -0,0 +1,473 @@ + + * $pagespeedonlineService = new apiPagespeedonlineService(...); + * $pagespeedapi = $pagespeedonlineService->pagespeedapi; + * + */ + class PagespeedapiServiceResource extends apiServiceResource { + + + /** + * Runs Page Speed analysis on the page at the specified URL, and returns a Page Speed score, a list + * of suggestions to make that page faster, and other information. (pagespeedapi.runpagespeed) + * @param string $url The URL to fetch and analyze + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string locale The locale used to localize formatted results + * @opt_param string rule A Page Speed rule to run; if none are given, all rules are run + * @opt_param string strategy The analysis strategy to use + * @return Result + */ + public function runpagespeed($url, $optParams = array()) { + $params = array('url' => $url); + $params = array_merge($params, $optParams); + $data = $this->__call('runpagespeed', array($params)); + if ($this->useObjects()) { + return new Result($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Pagespeedonline (v1). + *

            + * Lets you analyze the performance of a web page and get tailored suggestions to make that page faster. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiPagespeedonlineService extends apiService { + public $pagespeedapi; + /** + * Constructs the internal representation of the Pagespeedonline service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/pagespeedonline/v1/'; + $this->version = 'v1'; + $this->serviceName = 'pagespeedonline'; + + $apiClient->addService($this->serviceName, $this->version); + $this->pagespeedapi = new PagespeedapiServiceResource($this, $this->serviceName, 'pagespeedapi', json_decode('{"methods": {"runpagespeed": {"parameters": {"locale": {"type": "string", "location": "query"}, "url": {"required": true, "type": "string", "location": "query"}, "rule": {"repeated": true, "type": "string", "location": "query"}, "strategy": {"enum": ["desktop", "mobile"], "type": "string", "location": "query"}}, "id": "pagespeedonline.pagespeedapi.runpagespeed", "httpMethod": "GET", "path": "runPagespeed", "response": {"$ref": "Result"}}}}', true)); + } +} + +class Result extends apiModel { + public $kind; + protected $__formattedResultsType = 'ResultFormattedResults'; + protected $__formattedResultsDataType = ''; + public $formattedResults; + public $title; + protected $__versionType = 'ResultVersion'; + protected $__versionDataType = ''; + public $version; + public $score; + public $responseCode; + public $invalidRules; + protected $__pageStatsType = 'ResultPageStats'; + protected $__pageStatsDataType = ''; + public $pageStats; + public $id; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setFormattedResults(ResultFormattedResults $formattedResults) { + $this->formattedResults = $formattedResults; + } + public function getFormattedResults() { + return $this->formattedResults; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setVersion(ResultVersion $version) { + $this->version = $version; + } + public function getVersion() { + return $this->version; + } + public function setScore($score) { + $this->score = $score; + } + public function getScore() { + return $this->score; + } + public function setResponseCode($responseCode) { + $this->responseCode = $responseCode; + } + public function getResponseCode() { + return $this->responseCode; + } + public function setInvalidRules(/* array(string) */ $invalidRules) { + $this->assertIsArray($invalidRules, 'string', __METHOD__); + $this->invalidRules = $invalidRules; + } + public function getInvalidRules() { + return $this->invalidRules; + } + public function setPageStats(ResultPageStats $pageStats) { + $this->pageStats = $pageStats; + } + public function getPageStats() { + return $this->pageStats; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ResultFormattedResults extends apiModel { + public $locale; + protected $__ruleResultsType = 'ResultFormattedResultsRuleResults'; + protected $__ruleResultsDataType = 'map'; + public $ruleResults; + public function setLocale($locale) { + $this->locale = $locale; + } + public function getLocale() { + return $this->locale; + } + public function setRuleResults(ResultFormattedResultsRuleResults $ruleResults) { + $this->ruleResults = $ruleResults; + } + public function getRuleResults() { + return $this->ruleResults; + } +} + +class ResultFormattedResultsRuleResults extends apiModel { + public $localizedRuleName; + protected $__urlBlocksType = 'ResultFormattedResultsRuleResultsUrlBlocks'; + protected $__urlBlocksDataType = 'array'; + public $urlBlocks; + public $ruleScore; + public $ruleImpact; + public function setLocalizedRuleName($localizedRuleName) { + $this->localizedRuleName = $localizedRuleName; + } + public function getLocalizedRuleName() { + return $this->localizedRuleName; + } + public function setUrlBlocks(/* array(ResultFormattedResultsRuleResultsUrlBlocks) */ $urlBlocks) { + $this->assertIsArray($urlBlocks, 'ResultFormattedResultsRuleResultsUrlBlocks', __METHOD__); + $this->urlBlocks = $urlBlocks; + } + public function getUrlBlocks() { + return $this->urlBlocks; + } + public function setRuleScore($ruleScore) { + $this->ruleScore = $ruleScore; + } + public function getRuleScore() { + return $this->ruleScore; + } + public function setRuleImpact($ruleImpact) { + $this->ruleImpact = $ruleImpact; + } + public function getRuleImpact() { + return $this->ruleImpact; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocks extends apiModel { + protected $__headerType = 'ResultFormattedResultsRuleResultsUrlBlocksHeader'; + protected $__headerDataType = ''; + public $header; + protected $__urlsType = 'ResultFormattedResultsRuleResultsUrlBlocksUrls'; + protected $__urlsDataType = 'array'; + public $urls; + public function setHeader(ResultFormattedResultsRuleResultsUrlBlocksHeader $header) { + $this->header = $header; + } + public function getHeader() { + return $this->header; + } + public function setUrls(/* array(ResultFormattedResultsRuleResultsUrlBlocksUrls) */ $urls) { + $this->assertIsArray($urls, 'ResultFormattedResultsRuleResultsUrlBlocksUrls', __METHOD__); + $this->urls = $urls; + } + public function getUrls() { + return $this->urls; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocksHeader extends apiModel { + protected $__argsType = 'ResultFormattedResultsRuleResultsUrlBlocksHeaderArgs'; + protected $__argsDataType = 'array'; + public $args; + public $format; + public function setArgs(/* array(ResultFormattedResultsRuleResultsUrlBlocksHeaderArgs) */ $args) { + $this->assertIsArray($args, 'ResultFormattedResultsRuleResultsUrlBlocksHeaderArgs', __METHOD__); + $this->args = $args; + } + public function getArgs() { + return $this->args; + } + public function setFormat($format) { + $this->format = $format; + } + public function getFormat() { + return $this->format; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocksHeaderArgs extends apiModel { + public $type; + public $value; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocksUrls extends apiModel { + protected $__detailsType = 'ResultFormattedResultsRuleResultsUrlBlocksUrlsDetails'; + protected $__detailsDataType = 'array'; + public $details; + protected $__resultType = 'ResultFormattedResultsRuleResultsUrlBlocksUrlsResult'; + protected $__resultDataType = ''; + public $result; + public function setDetails(/* array(ResultFormattedResultsRuleResultsUrlBlocksUrlsDetails) */ $details) { + $this->assertIsArray($details, 'ResultFormattedResultsRuleResultsUrlBlocksUrlsDetails', __METHOD__); + $this->details = $details; + } + public function getDetails() { + return $this->details; + } + public function setResult(ResultFormattedResultsRuleResultsUrlBlocksUrlsResult $result) { + $this->result = $result; + } + public function getResult() { + return $this->result; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocksUrlsDetails extends apiModel { + protected $__argsType = 'ResultFormattedResultsRuleResultsUrlBlocksUrlsDetailsArgs'; + protected $__argsDataType = 'array'; + public $args; + public $format; + public function setArgs(/* array(ResultFormattedResultsRuleResultsUrlBlocksUrlsDetailsArgs) */ $args) { + $this->assertIsArray($args, 'ResultFormattedResultsRuleResultsUrlBlocksUrlsDetailsArgs', __METHOD__); + $this->args = $args; + } + public function getArgs() { + return $this->args; + } + public function setFormat($format) { + $this->format = $format; + } + public function getFormat() { + return $this->format; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocksUrlsDetailsArgs extends apiModel { + public $type; + public $value; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocksUrlsResult extends apiModel { + protected $__argsType = 'ResultFormattedResultsRuleResultsUrlBlocksUrlsResultArgs'; + protected $__argsDataType = 'array'; + public $args; + public $format; + public function setArgs(/* array(ResultFormattedResultsRuleResultsUrlBlocksUrlsResultArgs) */ $args) { + $this->assertIsArray($args, 'ResultFormattedResultsRuleResultsUrlBlocksUrlsResultArgs', __METHOD__); + $this->args = $args; + } + public function getArgs() { + return $this->args; + } + public function setFormat($format) { + $this->format = $format; + } + public function getFormat() { + return $this->format; + } +} + +class ResultFormattedResultsRuleResultsUrlBlocksUrlsResultArgs extends apiModel { + public $type; + public $value; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class ResultPageStats extends apiModel { + public $otherResponseBytes; + public $flashResponseBytes; + public $totalRequestBytes; + public $numberCssResources; + public $numberResources; + public $cssResponseBytes; + public $javascriptResponseBytes; + public $imageResponseBytes; + public $numberHosts; + public $numberStaticResources; + public $htmlResponseBytes; + public $numberJsResources; + public $textResponseBytes; + public function setOtherResponseBytes($otherResponseBytes) { + $this->otherResponseBytes = $otherResponseBytes; + } + public function getOtherResponseBytes() { + return $this->otherResponseBytes; + } + public function setFlashResponseBytes($flashResponseBytes) { + $this->flashResponseBytes = $flashResponseBytes; + } + public function getFlashResponseBytes() { + return $this->flashResponseBytes; + } + public function setTotalRequestBytes($totalRequestBytes) { + $this->totalRequestBytes = $totalRequestBytes; + } + public function getTotalRequestBytes() { + return $this->totalRequestBytes; + } + public function setNumberCssResources($numberCssResources) { + $this->numberCssResources = $numberCssResources; + } + public function getNumberCssResources() { + return $this->numberCssResources; + } + public function setNumberResources($numberResources) { + $this->numberResources = $numberResources; + } + public function getNumberResources() { + return $this->numberResources; + } + public function setCssResponseBytes($cssResponseBytes) { + $this->cssResponseBytes = $cssResponseBytes; + } + public function getCssResponseBytes() { + return $this->cssResponseBytes; + } + public function setJavascriptResponseBytes($javascriptResponseBytes) { + $this->javascriptResponseBytes = $javascriptResponseBytes; + } + public function getJavascriptResponseBytes() { + return $this->javascriptResponseBytes; + } + public function setImageResponseBytes($imageResponseBytes) { + $this->imageResponseBytes = $imageResponseBytes; + } + public function getImageResponseBytes() { + return $this->imageResponseBytes; + } + public function setNumberHosts($numberHosts) { + $this->numberHosts = $numberHosts; + } + public function getNumberHosts() { + return $this->numberHosts; + } + public function setNumberStaticResources($numberStaticResources) { + $this->numberStaticResources = $numberStaticResources; + } + public function getNumberStaticResources() { + return $this->numberStaticResources; + } + public function setHtmlResponseBytes($htmlResponseBytes) { + $this->htmlResponseBytes = $htmlResponseBytes; + } + public function getHtmlResponseBytes() { + return $this->htmlResponseBytes; + } + public function setNumberJsResources($numberJsResources) { + $this->numberJsResources = $numberJsResources; + } + public function getNumberJsResources() { + return $this->numberJsResources; + } + public function setTextResponseBytes($textResponseBytes) { + $this->textResponseBytes = $textResponseBytes; + } + public function getTextResponseBytes() { + return $this->textResponseBytes; + } +} + +class ResultVersion extends apiModel { + public $major; + public $minor; + public function setMajor($major) { + $this->major = $major; + } + public function getMajor() { + return $this->major; + } + public function setMinor($minor) { + $this->minor = $minor; + } + public function getMinor() { + return $this->minor; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiPlusService.php b/inc/vendors/social-login/Google/contrib/apiPlusService.php new file mode 100755 index 00000000..a1690fc4 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiPlusService.php @@ -0,0 +1,1505 @@ + + * $plusService = new apiPlusService(...); + * $activities = $plusService->activities; + * + */ + class ActivitiesServiceResource extends apiServiceResource { + + + /** + * Search public activities. (activities.search) + * @param string $query Full-text search query string. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string orderBy Specifies how to order search results. + * @opt_param string pageToken The continuation token, used to page through large result sets. To get the next page of results, set this parameter to the value of "nextPageToken" from the previous response. This token may be of any length. + * @opt_param string maxResults The maximum number of activities to include in the response, used for paging. For any response, the actual number returned may be less than the specified maxResults. + * @opt_param string language Specify the preferred language to search with. See search language codes for available values. + * @return ActivityFeed + */ + public function search($query, $optParams = array()) { + $params = array('query' => $query); + $params = array_merge($params, $optParams); + $data = $this->__call('search', array($params)); + if ($this->useObjects()) { + return new ActivityFeed($data); + } else { + return $data; + } + } + /** + * List all of the activities in the specified collection for a particular user. (activities.list) + * @param string $userId The ID of the user to get activities for. The special value "me" can be used to indicate the authenticated user. + * @param string $collection The collection of activities to list. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken The continuation token, used to page through large result sets. To get the next page of results, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param string maxResults The maximum number of activities to include in the response, used for paging. For any response, the actual number returned may be less than the specified maxResults. + * @return ActivityFeed + */ + public function listActivities($userId, $collection, $optParams = array()) { + $params = array('userId' => $userId, 'collection' => $collection); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new ActivityFeed($data); + } else { + return $data; + } + } + /** + * Get an activity. (activities.get) + * @param string $activityId The ID of the activity to get. + * @return Activity + */ + public function get($activityId, $optParams = array()) { + $params = array('activityId' => $activityId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Activity($data); + } else { + return $data; + } + } + } + + /** + * The "comments" collection of methods. + * Typical usage is: + * + * $plusService = new apiPlusService(...); + * $comments = $plusService->comments; + * + */ + class CommentsServiceResource extends apiServiceResource { + + + /** + * List all of the comments for an activity. (comments.list) + * @param string $activityId The ID of the activity to get comments for. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken The continuation token, used to page through large result sets. To get the next page of results, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param string maxResults The maximum number of comments to include in the response, used for paging. For any response, the actual number returned may be less than the specified maxResults. + * @return CommentFeed + */ + public function listComments($activityId, $optParams = array()) { + $params = array('activityId' => $activityId); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new CommentFeed($data); + } else { + return $data; + } + } + /** + * Get a comment. (comments.get) + * @param string $commentId The ID of the comment to get. + * @return Comment + */ + public function get($commentId, $optParams = array()) { + $params = array('commentId' => $commentId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Comment($data); + } else { + return $data; + } + } + } + + /** + * The "people" collection of methods. + * Typical usage is: + * + * $plusService = new apiPlusService(...); + * $people = $plusService->people; + * + */ + class PeopleServiceResource extends apiServiceResource { + + + /** + * List all of the people in the specified collection for a particular activity. + * (people.listByActivity) + * @param string $activityId The ID of the activity to get the list of people for. + * @param string $collection The collection of people to list. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken The continuation token, used to page through large result sets. To get the next page of results, set this parameter to the value of "nextPageToken" from the previous response. + * @opt_param string maxResults The maximum number of people to include in the response, used for paging. For any response, the actual number returned may be less than the specified maxResults. + * @return PeopleFeed + */ + public function listByActivity($activityId, $collection, $optParams = array()) { + $params = array('activityId' => $activityId, 'collection' => $collection); + $params = array_merge($params, $optParams); + $data = $this->__call('listByActivity', array($params)); + if ($this->useObjects()) { + return new PeopleFeed($data); + } else { + return $data; + } + } + /** + * Search all public profiles. (people.search) + * @param string $query Full-text search query string. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken The continuation token, used to page through large result sets. To get the next page of results, set this parameter to the value of "nextPageToken" from the previous response. This token may be of any length. + * @opt_param string maxResults The maximum number of people to include in the response, used for paging. For any response, the actual number returned may be less than the specified maxResults. + * @opt_param string language Specify the preferred language to search with. See search language codes for available values. + * @return PeopleFeed + */ + public function search($query, $optParams = array()) { + $params = array('query' => $query); + $params = array_merge($params, $optParams); + $data = $this->__call('search', array($params)); + if ($this->useObjects()) { + return new PeopleFeed($data); + } else { + return $data; + } + } + /** + * Get a person's profile. (people.get) + * @param string $userId The ID of the person to get the profile for. The special value "me" can be used to indicate the authenticated user. + * @return Person + */ + public function get($userId, $optParams = array()) { + $params = array('userId' => $userId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Person($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Plus (v1). + *

            + * The Google+ API enables developers to build on top of the Google+ platform. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiPlusService extends apiService { + public $activities; + public $comments; + public $people; + /** + * Constructs the internal representation of the Plus service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/plus/v1/'; + $this->version = 'v1'; + $this->serviceName = 'plus'; + + $apiClient->addService($this->serviceName, $this->version); + $this->activities = new ActivitiesServiceResource($this, $this->serviceName, 'activities', json_decode('{"methods": {"search": {"scopes": ["https://www.googleapis.com/auth/plus.me"], "parameters": {"orderBy": {"default": "recent", "enum": ["best", "recent"], "location": "query", "type": "string"}, "pageToken": {"type": "string", "location": "query"}, "language": {"default": "", "type": "string", "location": "query"}, "maxResults": {"format": "uint32", "default": "10", "maximum": "20", "minimum": "1", "location": "query", "type": "integer"}, "query": {"required": true, "type": "string", "location": "query"}}, "id": "plus.activities.search", "httpMethod": "GET", "path": "activities", "response": {"$ref": "ActivityFeed"}}, "list": {"scopes": ["https://www.googleapis.com/auth/plus.me"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "alt": {"default": "json", "enum": ["json"], "location": "query", "type": "string"}, "userId": {"required": true, "type": "string", "location": "path"}, "collection": {"required": true, "enum": ["public"], "location": "path", "type": "string"}, "maxResults": {"format": "uint32", "default": "20", "maximum": "100", "minimum": "1", "location": "query", "type": "integer"}}, "id": "plus.activities.list", "httpMethod": "GET", "path": "people/{userId}/activities/{collection}", "response": {"$ref": "ActivityFeed"}}, "get": {"scopes": ["https://www.googleapis.com/auth/plus.me"], "parameters": {"activityId": {"required": true, "type": "string", "location": "path"}, "alt": {"default": "json", "enum": ["json"], "location": "query", "type": "string"}}, "id": "plus.activities.get", "httpMethod": "GET", "path": "activities/{activityId}", "response": {"$ref": "Activity"}}}}', true)); + $this->comments = new CommentsServiceResource($this, $this->serviceName, 'comments', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/plus.me"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "activityId": {"required": true, "type": "string", "location": "path"}, "alt": {"default": "json", "enum": ["json"], "location": "query", "type": "string"}, "maxResults": {"format": "uint32", "default": "20", "maximum": "100", "minimum": "0", "location": "query", "type": "integer"}}, "id": "plus.comments.list", "httpMethod": "GET", "path": "activities/{activityId}/comments", "response": {"$ref": "CommentFeed"}}, "get": {"scopes": ["https://www.googleapis.com/auth/plus.me"], "parameters": {"commentId": {"required": true, "type": "string", "location": "path"}}, "id": "plus.comments.get", "httpMethod": "GET", "path": "comments/{commentId}", "response": {"$ref": "Comment"}}}}', true)); + $this->people = new PeopleServiceResource($this, $this->serviceName, 'people', json_decode('{"methods": {"listByActivity": {"scopes": ["https://www.googleapis.com/auth/plus.me"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "activityId": {"required": true, "type": "string", "location": "path"}, "collection": {"required": true, "enum": ["plusoners", "resharers"], "location": "path", "type": "string"}, "maxResults": {"format": "uint32", "default": "20", "maximum": "100", "minimum": "1", "location": "query", "type": "integer"}}, "id": "plus.people.listByActivity", "httpMethod": "GET", "path": "activities/{activityId}/people/{collection}", "response": {"$ref": "PeopleFeed"}}, "search": {"scopes": ["https://www.googleapis.com/auth/plus.me"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "language": {"default": "", "type": "string", "location": "query"}, "maxResults": {"format": "uint32", "default": "10", "maximum": "20", "minimum": "1", "location": "query", "type": "integer"}, "query": {"required": true, "type": "string", "location": "query"}}, "id": "plus.people.search", "httpMethod": "GET", "path": "people", "response": {"$ref": "PeopleFeed"}}, "get": {"scopes": ["https://www.googleapis.com/auth/plus.me", "https://www.googleapis.com/auth/userinfo.email"], "parameters": {"userId": {"required": true, "type": "string", "location": "path"}}, "id": "plus.people.get", "httpMethod": "GET", "path": "people/{userId}", "response": {"$ref": "Person"}}}}', true)); + } +} + +class Acl extends apiModel { + protected $__itemsType = 'PlusAclentryResource'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $description; + public function setItems(/* array(PlusAclentryResource) */ $items) { + $this->assertIsArray($items, 'PlusAclentryResource', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } +} + +class Activity extends apiModel { + public $placeName; + public $kind; + public $updated; + protected $__providerType = 'ActivityProvider'; + protected $__providerDataType = ''; + public $provider; + public $title; + public $url; + public $geocode; + protected $__objectType = 'ActivityObject'; + protected $__objectDataType = ''; + public $object; + public $placeId; + protected $__actorType = 'ActivityActor'; + protected $__actorDataType = ''; + public $actor; + public $id; + protected $__accessType = 'Acl'; + protected $__accessDataType = ''; + public $access; + public $verb; + public $etag; + public $radius; + public $address; + public $crosspostSource; + public $placeholder; + public $annotation; + public $published; + public function setPlaceName($placeName) { + $this->placeName = $placeName; + } + public function getPlaceName() { + return $this->placeName; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setProvider(ActivityProvider $provider) { + $this->provider = $provider; + } + public function getProvider() { + return $this->provider; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setGeocode($geocode) { + $this->geocode = $geocode; + } + public function getGeocode() { + return $this->geocode; + } + public function setObject(ActivityObject $object) { + $this->object = $object; + } + public function getObject() { + return $this->object; + } + public function setPlaceId($placeId) { + $this->placeId = $placeId; + } + public function getPlaceId() { + return $this->placeId; + } + public function setActor(ActivityActor $actor) { + $this->actor = $actor; + } + public function getActor() { + return $this->actor; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setAccess(Acl $access) { + $this->access = $access; + } + public function getAccess() { + return $this->access; + } + public function setVerb($verb) { + $this->verb = $verb; + } + public function getVerb() { + return $this->verb; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setRadius($radius) { + $this->radius = $radius; + } + public function getRadius() { + return $this->radius; + } + public function setAddress($address) { + $this->address = $address; + } + public function getAddress() { + return $this->address; + } + public function setCrosspostSource($crosspostSource) { + $this->crosspostSource = $crosspostSource; + } + public function getCrosspostSource() { + return $this->crosspostSource; + } + public function setPlaceholder($placeholder) { + $this->placeholder = $placeholder; + } + public function getPlaceholder() { + return $this->placeholder; + } + public function setAnnotation($annotation) { + $this->annotation = $annotation; + } + public function getAnnotation() { + return $this->annotation; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } +} + +class ActivityActor extends apiModel { + public $displayName; + public $url; + protected $__imageType = 'ActivityActorImage'; + protected $__imageDataType = ''; + public $image; + public $familyName; + public $givenName; + public $id; + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(ActivityActorImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setFamilyName($familyName) { + $this->familyName = $familyName; + } + public function getFamilyName() { + return $this->familyName; + } + public function setGivenName($givenName) { + $this->givenName = $givenName; + } + public function getGivenName() { + return $this->givenName; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ActivityActorImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class ActivityFeed extends apiModel { + public $nextPageToken; + public $kind; + public $title; + protected $__itemsType = 'Activity'; + protected $__itemsDataType = 'array'; + public $items; + public $updated; + public $nextLink; + public $etag; + public $id; + public $selfLink; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setItems(/* array(Activity) */ $items) { + $this->assertIsArray($items, 'Activity', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class ActivityObject extends apiModel { + protected $__resharersType = 'ActivityObjectResharers'; + protected $__resharersDataType = ''; + public $resharers; + protected $__attachmentsType = 'ActivityObjectAttachments'; + protected $__attachmentsDataType = 'array'; + public $attachments; + public $originalContent; + protected $__plusonersType = 'ActivityObjectPlusoners'; + protected $__plusonersDataType = ''; + public $plusoners; + protected $__actorType = 'ActivityObjectActor'; + protected $__actorDataType = ''; + public $actor; + public $content; + public $url; + protected $__repliesType = 'ActivityObjectReplies'; + protected $__repliesDataType = ''; + public $replies; + public $id; + public $objectType; + public function setResharers(ActivityObjectResharers $resharers) { + $this->resharers = $resharers; + } + public function getResharers() { + return $this->resharers; + } + public function setAttachments(/* array(ActivityObjectAttachments) */ $attachments) { + $this->assertIsArray($attachments, 'ActivityObjectAttachments', __METHOD__); + $this->attachments = $attachments; + } + public function getAttachments() { + return $this->attachments; + } + public function setOriginalContent($originalContent) { + $this->originalContent = $originalContent; + } + public function getOriginalContent() { + return $this->originalContent; + } + public function setPlusoners(ActivityObjectPlusoners $plusoners) { + $this->plusoners = $plusoners; + } + public function getPlusoners() { + return $this->plusoners; + } + public function setActor(ActivityObjectActor $actor) { + $this->actor = $actor; + } + public function getActor() { + return $this->actor; + } + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setReplies(ActivityObjectReplies $replies) { + $this->replies = $replies; + } + public function getReplies() { + return $this->replies; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setObjectType($objectType) { + $this->objectType = $objectType; + } + public function getObjectType() { + return $this->objectType; + } +} + +class ActivityObjectActor extends apiModel { + public $url; + protected $__imageType = 'ActivityObjectActorImage'; + protected $__imageDataType = ''; + public $image; + public $displayName; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(ActivityObjectActorImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ActivityObjectActorImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class ActivityObjectAttachments extends apiModel { + public $displayName; + protected $__fullImageType = 'ActivityObjectAttachmentsFullImage'; + protected $__fullImageDataType = ''; + public $fullImage; + public $url; + protected $__imageType = 'ActivityObjectAttachmentsImage'; + protected $__imageDataType = ''; + public $image; + public $content; + protected $__embedType = 'ActivityObjectAttachmentsEmbed'; + protected $__embedDataType = ''; + public $embed; + public $id; + public $objectType; + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setFullImage(ActivityObjectAttachmentsFullImage $fullImage) { + $this->fullImage = $fullImage; + } + public function getFullImage() { + return $this->fullImage; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(ActivityObjectAttachmentsImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setEmbed(ActivityObjectAttachmentsEmbed $embed) { + $this->embed = $embed; + } + public function getEmbed() { + return $this->embed; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setObjectType($objectType) { + $this->objectType = $objectType; + } + public function getObjectType() { + return $this->objectType; + } +} + +class ActivityObjectAttachmentsEmbed extends apiModel { + public $url; + public $type; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class ActivityObjectAttachmentsFullImage extends apiModel { + public $url; + public $width; + public $type; + public $height; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setWidth($width) { + $this->width = $width; + } + public function getWidth() { + return $this->width; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setHeight($height) { + $this->height = $height; + } + public function getHeight() { + return $this->height; + } +} + +class ActivityObjectAttachmentsImage extends apiModel { + public $url; + public $width; + public $type; + public $height; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setWidth($width) { + $this->width = $width; + } + public function getWidth() { + return $this->width; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setHeight($height) { + $this->height = $height; + } + public function getHeight() { + return $this->height; + } +} + +class ActivityObjectPlusoners extends apiModel { + public $totalItems; + public $selfLink; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class ActivityObjectReplies extends apiModel { + public $totalItems; + public $selfLink; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class ActivityObjectResharers extends apiModel { + public $totalItems; + public $selfLink; + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class ActivityProvider extends apiModel { + public $title; + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } +} + +class Comment extends apiModel { + protected $__inReplyToType = 'CommentInReplyTo'; + protected $__inReplyToDataType = 'array'; + public $inReplyTo; + public $kind; + protected $__objectType = 'CommentObject'; + protected $__objectDataType = ''; + public $object; + public $updated; + protected $__actorType = 'CommentActor'; + protected $__actorDataType = ''; + public $actor; + public $verb; + public $etag; + public $published; + public $id; + public $selfLink; + public function setInReplyTo(/* array(CommentInReplyTo) */ $inReplyTo) { + $this->assertIsArray($inReplyTo, 'CommentInReplyTo', __METHOD__); + $this->inReplyTo = $inReplyTo; + } + public function getInReplyTo() { + return $this->inReplyTo; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setObject(CommentObject $object) { + $this->object = $object; + } + public function getObject() { + return $this->object; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setActor(CommentActor $actor) { + $this->actor = $actor; + } + public function getActor() { + return $this->actor; + } + public function setVerb($verb) { + $this->verb = $verb; + } + public function getVerb() { + return $this->verb; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setPublished($published) { + $this->published = $published; + } + public function getPublished() { + return $this->published; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class CommentActor extends apiModel { + public $url; + protected $__imageType = 'CommentActorImage'; + protected $__imageDataType = ''; + public $image; + public $displayName; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setImage(CommentActorImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CommentActorImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class CommentFeed extends apiModel { + public $nextPageToken; + public $kind; + public $title; + protected $__itemsType = 'Comment'; + protected $__itemsDataType = 'array'; + public $items; + public $updated; + public $nextLink; + public $etag; + public $id; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setItems(/* array(Comment) */ $items) { + $this->assertIsArray($items, 'Comment', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CommentInReplyTo extends apiModel { + public $url; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class CommentObject extends apiModel { + public $content; + public $objectType; + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setObjectType($objectType) { + $this->objectType = $objectType; + } + public function getObjectType() { + return $this->objectType; + } +} + +class PeopleFeed extends apiModel { + public $nextPageToken; + public $kind; + public $title; + protected $__itemsType = 'Person'; + protected $__itemsDataType = 'array'; + public $items; + public $etag; + public $selfLink; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setItems(/* array(Person) */ $items) { + $this->assertIsArray($items, 'Person', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class Person extends apiModel { + public $relationshipStatus; + protected $__organizationsType = 'PersonOrganizations'; + protected $__organizationsDataType = 'array'; + public $organizations; + public $kind; + public $displayName; + protected $__nameType = 'PersonName'; + protected $__nameDataType = ''; + public $name; + public $url; + public $gender; + public $aboutMe; + public $tagline; + protected $__urlsType = 'PersonUrls'; + protected $__urlsDataType = 'array'; + public $urls; + protected $__placesLivedType = 'PersonPlacesLived'; + protected $__placesLivedDataType = 'array'; + public $placesLived; + protected $__emailsType = 'PersonEmails'; + protected $__emailsDataType = 'array'; + public $emails; + public $nickname; + public $birthday; + public $etag; + protected $__imageType = 'PersonImage'; + protected $__imageDataType = ''; + public $image; + public $hasApp; + public $id; + public $languagesSpoken; + public $currentLocation; + public $objectType; + public function setRelationshipStatus($relationshipStatus) { + $this->relationshipStatus = $relationshipStatus; + } + public function getRelationshipStatus() { + return $this->relationshipStatus; + } + public function setOrganizations(/* array(PersonOrganizations) */ $organizations) { + $this->assertIsArray($organizations, 'PersonOrganizations', __METHOD__); + $this->organizations = $organizations; + } + public function getOrganizations() { + return $this->organizations; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setName(PersonName $name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setGender($gender) { + $this->gender = $gender; + } + public function getGender() { + return $this->gender; + } + public function setAboutMe($aboutMe) { + $this->aboutMe = $aboutMe; + } + public function getAboutMe() { + return $this->aboutMe; + } + public function setTagline($tagline) { + $this->tagline = $tagline; + } + public function getTagline() { + return $this->tagline; + } + public function setUrls(/* array(PersonUrls) */ $urls) { + $this->assertIsArray($urls, 'PersonUrls', __METHOD__); + $this->urls = $urls; + } + public function getUrls() { + return $this->urls; + } + public function setPlacesLived(/* array(PersonPlacesLived) */ $placesLived) { + $this->assertIsArray($placesLived, 'PersonPlacesLived', __METHOD__); + $this->placesLived = $placesLived; + } + public function getPlacesLived() { + return $this->placesLived; + } + public function setEmails(/* array(PersonEmails) */ $emails) { + $this->assertIsArray($emails, 'PersonEmails', __METHOD__); + $this->emails = $emails; + } + public function getEmails() { + return $this->emails; + } + public function setNickname($nickname) { + $this->nickname = $nickname; + } + public function getNickname() { + return $this->nickname; + } + public function setBirthday($birthday) { + $this->birthday = $birthday; + } + public function getBirthday() { + return $this->birthday; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setImage(PersonImage $image) { + $this->image = $image; + } + public function getImage() { + return $this->image; + } + public function setHasApp($hasApp) { + $this->hasApp = $hasApp; + } + public function getHasApp() { + return $this->hasApp; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setLanguagesSpoken(/* array(string) */ $languagesSpoken) { + $this->assertIsArray($languagesSpoken, 'string', __METHOD__); + $this->languagesSpoken = $languagesSpoken; + } + public function getLanguagesSpoken() { + return $this->languagesSpoken; + } + public function setCurrentLocation($currentLocation) { + $this->currentLocation = $currentLocation; + } + public function getCurrentLocation() { + return $this->currentLocation; + } + public function setObjectType($objectType) { + $this->objectType = $objectType; + } + public function getObjectType() { + return $this->objectType; + } +} + +class PersonEmails extends apiModel { + public $type; + public $primary; + public $value; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setPrimary($primary) { + $this->primary = $primary; + } + public function getPrimary() { + return $this->primary; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class PersonImage extends apiModel { + public $url; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } +} + +class PersonName extends apiModel { + public $honorificPrefix; + public $middleName; + public $familyName; + public $formatted; + public $givenName; + public $honorificSuffix; + public function setHonorificPrefix($honorificPrefix) { + $this->honorificPrefix = $honorificPrefix; + } + public function getHonorificPrefix() { + return $this->honorificPrefix; + } + public function setMiddleName($middleName) { + $this->middleName = $middleName; + } + public function getMiddleName() { + return $this->middleName; + } + public function setFamilyName($familyName) { + $this->familyName = $familyName; + } + public function getFamilyName() { + return $this->familyName; + } + public function setFormatted($formatted) { + $this->formatted = $formatted; + } + public function getFormatted() { + return $this->formatted; + } + public function setGivenName($givenName) { + $this->givenName = $givenName; + } + public function getGivenName() { + return $this->givenName; + } + public function setHonorificSuffix($honorificSuffix) { + $this->honorificSuffix = $honorificSuffix; + } + public function getHonorificSuffix() { + return $this->honorificSuffix; + } +} + +class PersonOrganizations extends apiModel { + public $startDate; + public $endDate; + public $description; + public $title; + public $primary; + public $location; + public $department; + public $type; + public $name; + public function setStartDate($startDate) { + $this->startDate = $startDate; + } + public function getStartDate() { + return $this->startDate; + } + public function setEndDate($endDate) { + $this->endDate = $endDate; + } + public function getEndDate() { + return $this->endDate; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setPrimary($primary) { + $this->primary = $primary; + } + public function getPrimary() { + return $this->primary; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setDepartment($department) { + $this->department = $department; + } + public function getDepartment() { + return $this->department; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class PersonPlacesLived extends apiModel { + public $primary; + public $value; + public function setPrimary($primary) { + $this->primary = $primary; + } + public function getPrimary() { + return $this->primary; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class PersonUrls extends apiModel { + public $type; + public $primary; + public $value; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setPrimary($primary) { + $this->primary = $primary; + } + public function getPrimary() { + return $this->primary; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class PlusAclentryResource extends apiModel { + public $type; + public $id; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiPredictionService.php b/inc/vendors/social-login/Google/contrib/apiPredictionService.php new file mode 100755 index 00000000..b4937b90 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiPredictionService.php @@ -0,0 +1,418 @@ + + * $predictionService = new apiPredictionService(...); + * $trainedmodels = $predictionService->trainedmodels; + * + */ + class TrainedmodelsServiceResource extends apiServiceResource { + + + /** + * Submit model id and request a prediction (trainedmodels.predict) + * @param string $id The unique name for the predictive model. + * @param Input $postBody + * @return Output + */ + public function predict($id, Input $postBody, $optParams = array()) { + $params = array('id' => $id, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('predict', array($params)); + if ($this->useObjects()) { + return new Output($data); + } else { + return $data; + } + } + /** + * Begin training your model. (trainedmodels.insert) + * @param Training $postBody + * @return Training + */ + public function insert(Training $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Training($data); + } else { + return $data; + } + } + /** + * Check training status of your model. (trainedmodels.get) + * @param string $id The unique name for the predictive model. + * @return Training + */ + public function get($id, $optParams = array()) { + $params = array('id' => $id); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Training($data); + } else { + return $data; + } + } + /** + * Add new data to a trained model. (trainedmodels.update) + * @param string $id The unique name for the predictive model. + * @param Update $postBody + * @return Training + */ + public function update($id, Update $postBody, $optParams = array()) { + $params = array('id' => $id, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Training($data); + } else { + return $data; + } + } + /** + * Delete a trained model. (trainedmodels.delete) + * @param string $id The unique name for the predictive model. + */ + public function delete($id, $optParams = array()) { + $params = array('id' => $id); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "hostedmodels" collection of methods. + * Typical usage is: + * + * $predictionService = new apiPredictionService(...); + * $hostedmodels = $predictionService->hostedmodels; + * + */ + class HostedmodelsServiceResource extends apiServiceResource { + + + /** + * Submit input and request an output against a hosted model. (hostedmodels.predict) + * @param string $hostedModelName The name of a hosted model. + * @param Input $postBody + * @return Output + */ + public function predict($hostedModelName, Input $postBody, $optParams = array()) { + $params = array('hostedModelName' => $hostedModelName, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('predict', array($params)); + if ($this->useObjects()) { + return new Output($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Prediction (v1.4). + *

            + * Lets you access a cloud hosted machine learning service that makes it easy to build smart apps + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiPredictionService extends apiService { + public $trainedmodels; + public $hostedmodels; + /** + * Constructs the internal representation of the Prediction service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/prediction/v1.4/'; + $this->version = 'v1.4'; + $this->serviceName = 'prediction'; + + $apiClient->addService($this->serviceName, $this->version); + $this->trainedmodels = new TrainedmodelsServiceResource($this, $this->serviceName, 'trainedmodels', json_decode('{"methods": {"predict": {"scopes": ["https://www.googleapis.com/auth/prediction"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Input"}, "id": "prediction.trainedmodels.predict", "httpMethod": "POST", "path": "trainedmodels/{id}/predict", "response": {"$ref": "Output"}}, "insert": {"scopes": ["https://www.googleapis.com/auth/prediction"], "request": {"$ref": "Training"}, "response": {"$ref": "Training"}, "httpMethod": "POST", "path": "trainedmodels", "id": "prediction.trainedmodels.insert"}, "delete": {"scopes": ["https://www.googleapis.com/auth/prediction"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "trainedmodels/{id}", "id": "prediction.trainedmodels.delete"}, "update": {"scopes": ["https://www.googleapis.com/auth/prediction"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Update"}, "id": "prediction.trainedmodels.update", "httpMethod": "PUT", "path": "trainedmodels/{id}", "response": {"$ref": "Training"}}, "get": {"scopes": ["https://www.googleapis.com/auth/prediction"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "id": "prediction.trainedmodels.get", "httpMethod": "GET", "path": "trainedmodels/{id}", "response": {"$ref": "Training"}}}}', true)); + $this->hostedmodels = new HostedmodelsServiceResource($this, $this->serviceName, 'hostedmodels', json_decode('{"methods": {"predict": {"scopes": ["https://www.googleapis.com/auth/prediction"], "parameters": {"hostedModelName": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Input"}, "id": "prediction.hostedmodels.predict", "httpMethod": "POST", "path": "hostedmodels/{hostedModelName}/predict", "response": {"$ref": "Output"}}}}', true)); + } +} + +class Input extends apiModel { + protected $__inputType = 'InputInput'; + protected $__inputDataType = ''; + public $input; + public function setInput(InputInput $input) { + $this->input = $input; + } + public function getInput() { + return $this->input; + } +} + +class InputInput extends apiModel { + public $csvInstance; + public function setCsvInstance(/* array(object) */ $csvInstance) { + $this->assertIsArray($csvInstance, 'object', __METHOD__); + $this->csvInstance = $csvInstance; + } + public function getCsvInstance() { + return $this->csvInstance; + } +} + +class Output extends apiModel { + public $kind; + public $outputLabel; + public $id; + protected $__outputMultiType = 'OutputOutputMulti'; + protected $__outputMultiDataType = 'array'; + public $outputMulti; + public $outputValue; + public $selfLink; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setOutputLabel($outputLabel) { + $this->outputLabel = $outputLabel; + } + public function getOutputLabel() { + return $this->outputLabel; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setOutputMulti(/* array(OutputOutputMulti) */ $outputMulti) { + $this->assertIsArray($outputMulti, 'OutputOutputMulti', __METHOD__); + $this->outputMulti = $outputMulti; + } + public function getOutputMulti() { + return $this->outputMulti; + } + public function setOutputValue($outputValue) { + $this->outputValue = $outputValue; + } + public function getOutputValue() { + return $this->outputValue; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class OutputOutputMulti extends apiModel { + public $score; + public $label; + public function setScore($score) { + $this->score = $score; + } + public function getScore() { + return $this->score; + } + public function setLabel($label) { + $this->label = $label; + } + public function getLabel() { + return $this->label; + } +} + +class Training extends apiModel { + public $kind; + public $storageDataLocation; + public $storagePMMLModelLocation; + protected $__dataAnalysisType = 'TrainingDataAnalysis'; + protected $__dataAnalysisDataType = ''; + public $dataAnalysis; + public $trainingStatus; + protected $__modelInfoType = 'TrainingModelInfo'; + protected $__modelInfoDataType = ''; + public $modelInfo; + public $storagePMMLLocation; + public $id; + public $selfLink; + public $utility; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setStorageDataLocation($storageDataLocation) { + $this->storageDataLocation = $storageDataLocation; + } + public function getStorageDataLocation() { + return $this->storageDataLocation; + } + public function setStoragePMMLModelLocation($storagePMMLModelLocation) { + $this->storagePMMLModelLocation = $storagePMMLModelLocation; + } + public function getStoragePMMLModelLocation() { + return $this->storagePMMLModelLocation; + } + public function setDataAnalysis(TrainingDataAnalysis $dataAnalysis) { + $this->dataAnalysis = $dataAnalysis; + } + public function getDataAnalysis() { + return $this->dataAnalysis; + } + public function setTrainingStatus($trainingStatus) { + $this->trainingStatus = $trainingStatus; + } + public function getTrainingStatus() { + return $this->trainingStatus; + } + public function setModelInfo(TrainingModelInfo $modelInfo) { + $this->modelInfo = $modelInfo; + } + public function getModelInfo() { + return $this->modelInfo; + } + public function setStoragePMMLLocation($storagePMMLLocation) { + $this->storagePMMLLocation = $storagePMMLLocation; + } + public function getStoragePMMLLocation() { + return $this->storagePMMLLocation; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setUtility(/* array(double) */ $utility) { + $this->assertIsArray($utility, 'double', __METHOD__); + $this->utility = $utility; + } + public function getUtility() { + return $this->utility; + } +} + +class TrainingDataAnalysis extends apiModel { + public $warnings; + public function setWarnings(/* array(string) */ $warnings) { + $this->assertIsArray($warnings, 'string', __METHOD__); + $this->warnings = $warnings; + } + public function getWarnings() { + return $this->warnings; + } +} + +class TrainingModelInfo extends apiModel { + public $confusionMatrixRowTotals; + public $numberLabels; + public $confusionMatrix; + public $meanSquaredError; + public $modelType; + public $numberInstances; + public $classWeightedAccuracy; + public $classificationAccuracy; + public function setConfusionMatrixRowTotals($confusionMatrixRowTotals) { + $this->confusionMatrixRowTotals = $confusionMatrixRowTotals; + } + public function getConfusionMatrixRowTotals() { + return $this->confusionMatrixRowTotals; + } + public function setNumberLabels($numberLabels) { + $this->numberLabels = $numberLabels; + } + public function getNumberLabels() { + return $this->numberLabels; + } + public function setConfusionMatrix($confusionMatrix) { + $this->confusionMatrix = $confusionMatrix; + } + public function getConfusionMatrix() { + return $this->confusionMatrix; + } + public function setMeanSquaredError($meanSquaredError) { + $this->meanSquaredError = $meanSquaredError; + } + public function getMeanSquaredError() { + return $this->meanSquaredError; + } + public function setModelType($modelType) { + $this->modelType = $modelType; + } + public function getModelType() { + return $this->modelType; + } + public function setNumberInstances($numberInstances) { + $this->numberInstances = $numberInstances; + } + public function getNumberInstances() { + return $this->numberInstances; + } + public function setClassWeightedAccuracy($classWeightedAccuracy) { + $this->classWeightedAccuracy = $classWeightedAccuracy; + } + public function getClassWeightedAccuracy() { + return $this->classWeightedAccuracy; + } + public function setClassificationAccuracy($classificationAccuracy) { + $this->classificationAccuracy = $classificationAccuracy; + } + public function getClassificationAccuracy() { + return $this->classificationAccuracy; + } +} + +class Update extends apiModel { + public $csvInstance; + public $label; + public function setCsvInstance(/* array(object) */ $csvInstance) { + $this->assertIsArray($csvInstance, 'object', __METHOD__); + $this->csvInstance = $csvInstance; + } + public function getCsvInstance() { + return $this->csvInstance; + } + public function setLabel($label) { + $this->label = $label; + } + public function getLabel() { + return $this->label; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiShoppingService.php b/inc/vendors/social-login/Google/contrib/apiShoppingService.php new file mode 100755 index 00000000..29eb1ac9 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiShoppingService.php @@ -0,0 +1,1249 @@ + + * $shoppingService = new apiShoppingService(...); + * $products = $shoppingService->products; + * + */ + class ProductsServiceResource extends apiServiceResource { + + + /** + * Returns a list of products and content modules (products.list) + * @param string $source Query source + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param bool sayt.useGcsConfig Google Internal + * @opt_param string rankBy Ranking specification + * @opt_param bool debug.enableLogging Google Internal + * @opt_param bool facets.enabled Whether to return facet information + * @opt_param bool relatedQueries.useGcsConfig This parameter is currently ignored + * @opt_param bool promotions.enabled Whether to return promotion information + * @opt_param bool debug.enabled Google Internal + * @opt_param string facets.include Facets to include (applies when useGcsConfig == false) + * @opt_param string productFields Google Internal + * @opt_param string channels Channels specification + * @opt_param string currency Currency restriction (ISO 4217) + * @opt_param string startIndex Index (1-based) of first product to return + * @opt_param string facets.discover Facets to discover + * @opt_param bool debug.searchResponse Google Internal + * @opt_param string crowdBy Crowding specification + * @opt_param bool spelling.enabled Whether to return spelling suggestions + * @opt_param string taxonomy Taxonomy name + * @opt_param bool debug.geocodeRequest Google Internal + * @opt_param bool spelling.useGcsConfig This parameter is currently ignored + * @opt_param string useCase One of CommerceSearchUseCase, ShoppingApiUseCase + * @opt_param string location Location used to determine tax and shipping + * @opt_param string maxVariants Maximum number of variant results to return per result + * @opt_param bool debug.rdcRequest Google Internal + * @opt_param string categories.include Category specification + * @opt_param string boostBy Boosting specification + * @opt_param bool redirects.useGcsConfig Whether to return redirect information as configured in the GCS account + * @opt_param bool safe Whether safe search is enabled. Default: true + * @opt_param bool categories.useGcsConfig This parameter is currently ignored + * @opt_param string maxResults Maximum number of results to return + * @opt_param bool facets.useGcsConfig Whether to return facet information as configured in the GCS account + * @opt_param bool categories.enabled Whether to return category information + * @opt_param string attributeFilter Comma separated list of attributes to return + * @opt_param bool sayt.enabled Google Internal + * @opt_param bool promotions.useGcsConfig Whether to return promotion information as configured in the GCS account + * @opt_param string thumbnails Image thumbnails specification + * @opt_param string language Language restriction (BCP 47) + * @opt_param string country Country restriction (ISO 3166) + * @opt_param bool debug.geocodeResponse Google Internal + * @opt_param string restrictBy Restriction specification + * @opt_param bool debug.rdcResponse Google Internal + * @opt_param string q Search query + * @opt_param bool redirects.enabled Whether to return redirect information + * @opt_param bool debug.searchRequest Google Internal + * @opt_param bool relatedQueries.enabled Whether to return related queries + * @opt_param string minAvailability + * @opt_param string plusOne +1 rendering specification. + * @return Products + */ + public function listProducts($source, $optParams = array()) { + $params = array('source' => $source); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Products($data); + } else { + return $data; + } + } + /** + * Returns a single product (products.get) + * @param string $source Query source + * @param string $accountId Merchant center account id + * @param string $productIdType Type of productId + * @param string $productId Id of product + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string categories.include Category specification + * @opt_param bool recommendations.enabled Whether to return recommendation information + * @opt_param bool debug.enableLogging Google Internal + * @opt_param string taxonomy Merchant taxonomy + * @opt_param bool categories.useGcsConfig This parameter is currently ignored + * @opt_param bool debug.searchResponse Google Internal + * @opt_param bool debug.enabled Google Internal + * @opt_param string recommendations.include Recommendation specification + * @opt_param bool categories.enabled Whether to return category information + * @opt_param string productFields Google Internal + * @opt_param string location Location used to determine tax and shipping + * @opt_param bool debug.searchRequest Google Internal + * @opt_param string attributeFilter Comma separated list of attributes to return + * @opt_param bool recommendations.useGcsConfig This parameter is currently ignored + * @opt_param string plusOne +1 rendering specification. + * @opt_param string thumbnails Thumbnail specification + * @return Product + */ + public function get($source, $accountId, $productIdType, $productId, $optParams = array()) { + $params = array('source' => $source, 'accountId' => $accountId, 'productIdType' => $productIdType, 'productId' => $productId); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Product($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Shopping (v1). + *

            + * Lets you search over product data + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiShoppingService extends apiService { + public $products; + /** + * Constructs the internal representation of the Shopping service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/shopping/search/v1/'; + $this->version = 'v1'; + $this->serviceName = 'shopping'; + + $apiClient->addService($this->serviceName, $this->version); + $this->products = new ProductsServiceResource($this, $this->serviceName, 'products', json_decode('{"methods": {"list": {"parameters": {"sayt.useGcsConfig": {"type": "boolean", "location": "query"}, "debug.geocodeResponse": {"type": "boolean", "location": "query"}, "debug.enableLogging": {"type": "boolean", "location": "query"}, "facets.enabled": {"type": "boolean", "location": "query"}, "relatedQueries.useGcsConfig": {"type": "boolean", "location": "query"}, "promotions.enabled": {"type": "boolean", "location": "query"}, "debug.enabled": {"type": "boolean", "location": "query"}, "facets.include": {"type": "string", "location": "query"}, "productFields": {"type": "string", "location": "query"}, "channels": {"type": "string", "location": "query"}, "currency": {"type": "string", "location": "query"}, "startIndex": {"format": "uint32", "type": "integer", "location": "query"}, "facets.discover": {"type": "string", "location": "query"}, "debug.searchResponse": {"type": "boolean", "location": "query"}, "crowdBy": {"type": "string", "location": "query"}, "spelling.enabled": {"type": "boolean", "location": "query"}, "debug.geocodeRequest": {"type": "boolean", "location": "query"}, "source": {"required": true, "type": "string", "location": "path"}, "spelling.useGcsConfig": {"type": "boolean", "location": "query"}, "useCase": {"type": "string", "location": "query"}, "location": {"type": "string", "location": "query"}, "taxonomy": {"type": "string", "location": "query"}, "debug.rdcRequest": {"type": "boolean", "location": "query"}, "categories.include": {"type": "string", "location": "query"}, "debug.searchRequest": {"type": "boolean", "location": "query"}, "safe": {"type": "boolean", "location": "query"}, "boostBy": {"type": "string", "location": "query"}, "maxVariants": {"format": "uint32", "type": "integer", "location": "query"}, "categories.useGcsConfig": {"type": "boolean", "location": "query"}, "maxResults": {"format": "uint32", "type": "integer", "location": "query"}, "facets.useGcsConfig": {"type": "boolean", "location": "query"}, "categories.enabled": {"type": "boolean", "location": "query"}, "attributeFilter": {"type": "string", "location": "query"}, "sayt.enabled": {"type": "boolean", "location": "query"}, "plusOne": {"type": "string", "location": "query"}, "thumbnails": {"type": "string", "location": "query"}, "language": {"type": "string", "location": "query"}, "redirects.useGcsConfig": {"type": "boolean", "location": "query"}, "rankBy": {"type": "string", "location": "query"}, "restrictBy": {"type": "string", "location": "query"}, "debug.rdcResponse": {"type": "boolean", "location": "query"}, "q": {"type": "string", "location": "query"}, "redirects.enabled": {"type": "boolean", "location": "query"}, "country": {"type": "string", "location": "query"}, "relatedQueries.enabled": {"type": "boolean", "location": "query"}, "minAvailability": {"enum": ["inStock", "limited", "outOfStock", "unknown"], "type": "string", "location": "query"}, "promotions.useGcsConfig": {"type": "boolean", "location": "query"}}, "id": "shopping.products.list", "httpMethod": "GET", "path": "{source}/products", "response": {"$ref": "Products"}}, "get": {"parameters": {"categories.include": {"type": "string", "location": "query"}, "recommendations.enabled": {"type": "boolean", "location": "query"}, "plusOne": {"type": "string", "location": "query"}, "debug.enableLogging": {"type": "boolean", "location": "query"}, "thumbnails": {"type": "string", "location": "query"}, "recommendations.include": {"type": "string", "location": "query"}, "taxonomy": {"type": "string", "location": "query"}, "productIdType": {"required": true, "type": "string", "location": "path"}, "categories.useGcsConfig": {"type": "boolean", "location": "query"}, "attributeFilter": {"type": "string", "location": "query"}, "debug.enabled": {"type": "boolean", "location": "query"}, "source": {"required": true, "type": "string", "location": "path"}, "categories.enabled": {"type": "boolean", "location": "query"}, "location": {"type": "string", "location": "query"}, "debug.searchRequest": {"type": "boolean", "location": "query"}, "debug.searchResponse": {"type": "boolean", "location": "query"}, "recommendations.useGcsConfig": {"type": "boolean", "location": "query"}, "productFields": {"type": "string", "location": "query"}, "accountId": {"format": "uint32", "required": true, "type": "integer", "location": "path"}, "productId": {"required": true, "type": "string", "location": "path"}}, "id": "shopping.products.get", "httpMethod": "GET", "path": "{source}/products/{accountId}/{productIdType}/{productId}", "response": {"$ref": "Product"}}}}', true)); + } +} + +class Product extends apiModel { + public $selfLink; + public $kind; + protected $__productType = 'ShoppingModelProductJsonV1'; + protected $__productDataType = ''; + public $product; + public $requestId; + protected $__recommendationsType = 'ProductRecommendations'; + protected $__recommendationsDataType = 'array'; + public $recommendations; + protected $__debugType = 'ShoppingModelDebugJsonV1'; + protected $__debugDataType = ''; + public $debug; + public $id; + protected $__categoriesType = 'ShoppingModelCategoryJsonV1'; + protected $__categoriesDataType = 'array'; + public $categories; + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setProduct(ShoppingModelProductJsonV1 $product) { + $this->product = $product; + } + public function getProduct() { + return $this->product; + } + public function setRequestId($requestId) { + $this->requestId = $requestId; + } + public function getRequestId() { + return $this->requestId; + } + public function setRecommendations(/* array(ProductRecommendations) */ $recommendations) { + $this->assertIsArray($recommendations, 'ProductRecommendations', __METHOD__); + $this->recommendations = $recommendations; + } + public function getRecommendations() { + return $this->recommendations; + } + public function setDebug(ShoppingModelDebugJsonV1 $debug) { + $this->debug = $debug; + } + public function getDebug() { + return $this->debug; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setCategories(/* array(ShoppingModelCategoryJsonV1) */ $categories) { + $this->assertIsArray($categories, 'ShoppingModelCategoryJsonV1', __METHOD__); + $this->categories = $categories; + } + public function getCategories() { + return $this->categories; + } +} + +class ProductRecommendations extends apiModel { + protected $__recommendationListType = 'ProductRecommendationsRecommendationList'; + protected $__recommendationListDataType = 'array'; + public $recommendationList; + public $type; + public function setRecommendationList(/* array(ProductRecommendationsRecommendationList) */ $recommendationList) { + $this->assertIsArray($recommendationList, 'ProductRecommendationsRecommendationList', __METHOD__); + $this->recommendationList = $recommendationList; + } + public function getRecommendationList() { + return $this->recommendationList; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class ProductRecommendationsRecommendationList extends apiModel { + protected $__productType = 'ShoppingModelProductJsonV1'; + protected $__productDataType = ''; + public $product; + public function setProduct(ShoppingModelProductJsonV1 $product) { + $this->product = $product; + } + public function getProduct() { + return $this->product; + } +} + +class Products extends apiModel { + protected $__promotionsType = 'ProductsPromotions'; + protected $__promotionsDataType = 'array'; + public $promotions; + public $selfLink; + public $kind; + protected $__storesType = 'ProductsStores'; + protected $__storesDataType = 'array'; + public $stores; + public $currentItemCount; + protected $__itemsType = 'Product'; + protected $__itemsDataType = 'array'; + public $items; + protected $__facetsType = 'ProductsFacets'; + protected $__facetsDataType = 'array'; + public $facets; + public $itemsPerPage; + public $redirects; + public $nextLink; + protected $__shelfSpaceAdsType = 'ProductsShelfSpaceAds'; + protected $__shelfSpaceAdsDataType = 'array'; + public $shelfSpaceAds; + public $startIndex; + public $etag; + public $requestId; + public $relatedQueries; + protected $__debugType = 'ShoppingModelDebugJsonV1'; + protected $__debugDataType = ''; + public $debug; + protected $__spellingType = 'ProductsSpelling'; + protected $__spellingDataType = ''; + public $spelling; + public $previousLink; + public $totalItems; + public $id; + protected $__categoriesType = 'ShoppingModelCategoryJsonV1'; + protected $__categoriesDataType = 'array'; + public $categories; + public function setPromotions(/* array(ProductsPromotions) */ $promotions) { + $this->assertIsArray($promotions, 'ProductsPromotions', __METHOD__); + $this->promotions = $promotions; + } + public function getPromotions() { + return $this->promotions; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setStores(/* array(ProductsStores) */ $stores) { + $this->assertIsArray($stores, 'ProductsStores', __METHOD__); + $this->stores = $stores; + } + public function getStores() { + return $this->stores; + } + public function setCurrentItemCount($currentItemCount) { + $this->currentItemCount = $currentItemCount; + } + public function getCurrentItemCount() { + return $this->currentItemCount; + } + public function setItems(/* array(Product) */ $items) { + $this->assertIsArray($items, 'Product', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setFacets(/* array(ProductsFacets) */ $facets) { + $this->assertIsArray($facets, 'ProductsFacets', __METHOD__); + $this->facets = $facets; + } + public function getFacets() { + return $this->facets; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setRedirects(/* array(string) */ $redirects) { + $this->assertIsArray($redirects, 'string', __METHOD__); + $this->redirects = $redirects; + } + public function getRedirects() { + return $this->redirects; + } + public function setNextLink($nextLink) { + $this->nextLink = $nextLink; + } + public function getNextLink() { + return $this->nextLink; + } + public function setShelfSpaceAds(/* array(ProductsShelfSpaceAds) */ $shelfSpaceAds) { + $this->assertIsArray($shelfSpaceAds, 'ProductsShelfSpaceAds', __METHOD__); + $this->shelfSpaceAds = $shelfSpaceAds; + } + public function getShelfSpaceAds() { + return $this->shelfSpaceAds; + } + public function setStartIndex($startIndex) { + $this->startIndex = $startIndex; + } + public function getStartIndex() { + return $this->startIndex; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setRequestId($requestId) { + $this->requestId = $requestId; + } + public function getRequestId() { + return $this->requestId; + } + public function setRelatedQueries(/* array(string) */ $relatedQueries) { + $this->assertIsArray($relatedQueries, 'string', __METHOD__); + $this->relatedQueries = $relatedQueries; + } + public function getRelatedQueries() { + return $this->relatedQueries; + } + public function setDebug(ShoppingModelDebugJsonV1 $debug) { + $this->debug = $debug; + } + public function getDebug() { + return $this->debug; + } + public function setSpelling(ProductsSpelling $spelling) { + $this->spelling = $spelling; + } + public function getSpelling() { + return $this->spelling; + } + public function setPreviousLink($previousLink) { + $this->previousLink = $previousLink; + } + public function getPreviousLink() { + return $this->previousLink; + } + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setCategories(/* array(ShoppingModelCategoryJsonV1) */ $categories) { + $this->assertIsArray($categories, 'ShoppingModelCategoryJsonV1', __METHOD__); + $this->categories = $categories; + } + public function getCategories() { + return $this->categories; + } +} + +class ProductsFacets extends apiModel { + public $count; + public $displayName; + public $name; + protected $__bucketsType = 'ProductsFacetsBuckets'; + protected $__bucketsDataType = 'array'; + public $buckets; + public $property; + public $type; + public $unit; + public function setCount($count) { + $this->count = $count; + } + public function getCount() { + return $this->count; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setBuckets(/* array(ProductsFacetsBuckets) */ $buckets) { + $this->assertIsArray($buckets, 'ProductsFacetsBuckets', __METHOD__); + $this->buckets = $buckets; + } + public function getBuckets() { + return $this->buckets; + } + public function setProperty($property) { + $this->property = $property; + } + public function getProperty() { + return $this->property; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setUnit($unit) { + $this->unit = $unit; + } + public function getUnit() { + return $this->unit; + } +} + +class ProductsFacetsBuckets extends apiModel { + public $count; + public $minExclusive; + public $min; + public $max; + public $value; + public $maxExclusive; + public function setCount($count) { + $this->count = $count; + } + public function getCount() { + return $this->count; + } + public function setMinExclusive($minExclusive) { + $this->minExclusive = $minExclusive; + } + public function getMinExclusive() { + return $this->minExclusive; + } + public function setMin($min) { + $this->min = $min; + } + public function getMin() { + return $this->min; + } + public function setMax($max) { + $this->max = $max; + } + public function getMax() { + return $this->max; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } + public function setMaxExclusive($maxExclusive) { + $this->maxExclusive = $maxExclusive; + } + public function getMaxExclusive() { + return $this->maxExclusive; + } +} + +class ProductsPromotions extends apiModel { + protected $__productType = 'ShoppingModelProductJsonV1'; + protected $__productDataType = ''; + public $product; + public $description; + public $imageLink; + public $destLink; + public $customHtml; + public $link; + protected $__customFieldsType = 'ProductsPromotionsCustomFields'; + protected $__customFieldsDataType = 'array'; + public $customFields; + public $type; + public $name; + public function setProduct(ShoppingModelProductJsonV1 $product) { + $this->product = $product; + } + public function getProduct() { + return $this->product; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setImageLink($imageLink) { + $this->imageLink = $imageLink; + } + public function getImageLink() { + return $this->imageLink; + } + public function setDestLink($destLink) { + $this->destLink = $destLink; + } + public function getDestLink() { + return $this->destLink; + } + public function setCustomHtml($customHtml) { + $this->customHtml = $customHtml; + } + public function getCustomHtml() { + return $this->customHtml; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setCustomFields(/* array(ProductsPromotionsCustomFields) */ $customFields) { + $this->assertIsArray($customFields, 'ProductsPromotionsCustomFields', __METHOD__); + $this->customFields = $customFields; + } + public function getCustomFields() { + return $this->customFields; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } +} + +class ProductsPromotionsCustomFields extends apiModel { + public $name; + public $value; + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } +} + +class ProductsShelfSpaceAds extends apiModel { + protected $__productType = 'ShoppingModelProductJsonV1'; + protected $__productDataType = ''; + public $product; + public function setProduct(ShoppingModelProductJsonV1 $product) { + $this->product = $product; + } + public function getProduct() { + return $this->product; + } +} + +class ProductsSpelling extends apiModel { + public $suggestion; + public function setSuggestion($suggestion) { + $this->suggestion = $suggestion; + } + public function getSuggestion() { + return $this->suggestion; + } +} + +class ProductsStores extends apiModel { + public $storeCode; + public $name; + public $storeId; + public $telephone; + public $location; + public $address; + public function setStoreCode($storeCode) { + $this->storeCode = $storeCode; + } + public function getStoreCode() { + return $this->storeCode; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setStoreId($storeId) { + $this->storeId = $storeId; + } + public function getStoreId() { + return $this->storeId; + } + public function setTelephone($telephone) { + $this->telephone = $telephone; + } + public function getTelephone() { + return $this->telephone; + } + public function setLocation($location) { + $this->location = $location; + } + public function getLocation() { + return $this->location; + } + public function setAddress($address) { + $this->address = $address; + } + public function getAddress() { + return $this->address; + } +} + +class ShoppingModelCategoryJsonV1 extends apiModel { + public $url; + public $shortName; + public $parents; + public $id; + public function setUrl($url) { + $this->url = $url; + } + public function getUrl() { + return $this->url; + } + public function setShortName($shortName) { + $this->shortName = $shortName; + } + public function getShortName() { + return $this->shortName; + } + public function setParents(/* array(string) */ $parents) { + $this->assertIsArray($parents, 'string', __METHOD__); + $this->parents = $parents; + } + public function getParents() { + return $this->parents; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class ShoppingModelDebugJsonV1 extends apiModel { + public $searchResponse; + public $searchRequest; + public $rdcResponse; + protected $__backendTimesType = 'ShoppingModelDebugJsonV1BackendTimes'; + protected $__backendTimesDataType = 'array'; + public $backendTimes; + public $elapsedMillis; + public function setSearchResponse($searchResponse) { + $this->searchResponse = $searchResponse; + } + public function getSearchResponse() { + return $this->searchResponse; + } + public function setSearchRequest($searchRequest) { + $this->searchRequest = $searchRequest; + } + public function getSearchRequest() { + return $this->searchRequest; + } + public function setRdcResponse($rdcResponse) { + $this->rdcResponse = $rdcResponse; + } + public function getRdcResponse() { + return $this->rdcResponse; + } + public function setBackendTimes(/* array(ShoppingModelDebugJsonV1BackendTimes) */ $backendTimes) { + $this->assertIsArray($backendTimes, 'ShoppingModelDebugJsonV1BackendTimes', __METHOD__); + $this->backendTimes = $backendTimes; + } + public function getBackendTimes() { + return $this->backendTimes; + } + public function setElapsedMillis($elapsedMillis) { + $this->elapsedMillis = $elapsedMillis; + } + public function getElapsedMillis() { + return $this->elapsedMillis; + } +} + +class ShoppingModelDebugJsonV1BackendTimes extends apiModel { + public $serverMillis; + public $hostName; + public $name; + public $elapsedMillis; + public function setServerMillis($serverMillis) { + $this->serverMillis = $serverMillis; + } + public function getServerMillis() { + return $this->serverMillis; + } + public function setHostName($hostName) { + $this->hostName = $hostName; + } + public function getHostName() { + return $this->hostName; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setElapsedMillis($elapsedMillis) { + $this->elapsedMillis = $elapsedMillis; + } + public function getElapsedMillis() { + return $this->elapsedMillis; + } +} + +class ShoppingModelProductJsonV1 extends apiModel { + public $queryMatched; + public $gtin; + protected $__imagesType = 'ShoppingModelProductJsonV1Images'; + protected $__imagesDataType = 'array'; + public $images; + protected $__inventoriesType = 'ShoppingModelProductJsonV1Inventories'; + protected $__inventoriesDataType = 'array'; + public $inventories; + protected $__authorType = 'ShoppingModelProductJsonV1Author'; + protected $__authorDataType = ''; + public $author; + public $condition; + public $providedId; + public $internal8; + public $description; + public $gtins; + public $internal1; + public $brand; + public $internal3; + protected $__internal4Type = 'ShoppingModelProductJsonV1Internal4'; + protected $__internal4DataType = 'array'; + public $internal4; + public $internal6; + public $internal7; + public $link; + protected $__attributesType = 'ShoppingModelProductJsonV1Attributes'; + protected $__attributesDataType = 'array'; + public $attributes; + public $totalMatchingVariants; + protected $__variantsType = 'ShoppingModelProductJsonV1Variants'; + protected $__variantsDataType = 'array'; + public $variants; + public $modificationTime; + public $categories; + public $language; + public $country; + public $title; + public $creationTime; + public $internal14; + public $internal12; + public $internal13; + public $internal10; + public $plusOne; + public $googleId; + public $internal15; + public function setQueryMatched($queryMatched) { + $this->queryMatched = $queryMatched; + } + public function getQueryMatched() { + return $this->queryMatched; + } + public function setGtin($gtin) { + $this->gtin = $gtin; + } + public function getGtin() { + return $this->gtin; + } + public function setImages(/* array(ShoppingModelProductJsonV1Images) */ $images) { + $this->assertIsArray($images, 'ShoppingModelProductJsonV1Images', __METHOD__); + $this->images = $images; + } + public function getImages() { + return $this->images; + } + public function setInventories(/* array(ShoppingModelProductJsonV1Inventories) */ $inventories) { + $this->assertIsArray($inventories, 'ShoppingModelProductJsonV1Inventories', __METHOD__); + $this->inventories = $inventories; + } + public function getInventories() { + return $this->inventories; + } + public function setAuthor(ShoppingModelProductJsonV1Author $author) { + $this->author = $author; + } + public function getAuthor() { + return $this->author; + } + public function setCondition($condition) { + $this->condition = $condition; + } + public function getCondition() { + return $this->condition; + } + public function setProvidedId($providedId) { + $this->providedId = $providedId; + } + public function getProvidedId() { + return $this->providedId; + } + public function setInternal8(/* array(string) */ $internal8) { + $this->assertIsArray($internal8, 'string', __METHOD__); + $this->internal8 = $internal8; + } + public function getInternal8() { + return $this->internal8; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } + public function setGtins(/* array(string) */ $gtins) { + $this->assertIsArray($gtins, 'string', __METHOD__); + $this->gtins = $gtins; + } + public function getGtins() { + return $this->gtins; + } + public function setInternal1(/* array(string) */ $internal1) { + $this->assertIsArray($internal1, 'string', __METHOD__); + $this->internal1 = $internal1; + } + public function getInternal1() { + return $this->internal1; + } + public function setBrand($brand) { + $this->brand = $brand; + } + public function getBrand() { + return $this->brand; + } + public function setInternal3($internal3) { + $this->internal3 = $internal3; + } + public function getInternal3() { + return $this->internal3; + } + public function setInternal4(/* array(ShoppingModelProductJsonV1Internal4) */ $internal4) { + $this->assertIsArray($internal4, 'ShoppingModelProductJsonV1Internal4', __METHOD__); + $this->internal4 = $internal4; + } + public function getInternal4() { + return $this->internal4; + } + public function setInternal6($internal6) { + $this->internal6 = $internal6; + } + public function getInternal6() { + return $this->internal6; + } + public function setInternal7($internal7) { + $this->internal7 = $internal7; + } + public function getInternal7() { + return $this->internal7; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setAttributes(/* array(ShoppingModelProductJsonV1Attributes) */ $attributes) { + $this->assertIsArray($attributes, 'ShoppingModelProductJsonV1Attributes', __METHOD__); + $this->attributes = $attributes; + } + public function getAttributes() { + return $this->attributes; + } + public function setTotalMatchingVariants($totalMatchingVariants) { + $this->totalMatchingVariants = $totalMatchingVariants; + } + public function getTotalMatchingVariants() { + return $this->totalMatchingVariants; + } + public function setVariants(/* array(ShoppingModelProductJsonV1Variants) */ $variants) { + $this->assertIsArray($variants, 'ShoppingModelProductJsonV1Variants', __METHOD__); + $this->variants = $variants; + } + public function getVariants() { + return $this->variants; + } + public function setModificationTime($modificationTime) { + $this->modificationTime = $modificationTime; + } + public function getModificationTime() { + return $this->modificationTime; + } + public function setCategories(/* array(string) */ $categories) { + $this->assertIsArray($categories, 'string', __METHOD__); + $this->categories = $categories; + } + public function getCategories() { + return $this->categories; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } + public function setCountry($country) { + $this->country = $country; + } + public function getCountry() { + return $this->country; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setCreationTime($creationTime) { + $this->creationTime = $creationTime; + } + public function getCreationTime() { + return $this->creationTime; + } + public function setInternal14($internal14) { + $this->internal14 = $internal14; + } + public function getInternal14() { + return $this->internal14; + } + public function setInternal12($internal12) { + $this->internal12 = $internal12; + } + public function getInternal12() { + return $this->internal12; + } + public function setInternal13($internal13) { + $this->internal13 = $internal13; + } + public function getInternal13() { + return $this->internal13; + } + public function setInternal10(/* array(string) */ $internal10) { + $this->assertIsArray($internal10, 'string', __METHOD__); + $this->internal10 = $internal10; + } + public function getInternal10() { + return $this->internal10; + } + public function setPlusOne($plusOne) { + $this->plusOne = $plusOne; + } + public function getPlusOne() { + return $this->plusOne; + } + public function setGoogleId($googleId) { + $this->googleId = $googleId; + } + public function getGoogleId() { + return $this->googleId; + } + public function setInternal15($internal15) { + $this->internal15 = $internal15; + } + public function getInternal15() { + return $this->internal15; + } +} + +class ShoppingModelProductJsonV1Attributes extends apiModel { + public $type; + public $value; + public $displayName; + public $name; + public $unit; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setValue($value) { + $this->value = $value; + } + public function getValue() { + return $this->value; + } + public function setDisplayName($displayName) { + $this->displayName = $displayName; + } + public function getDisplayName() { + return $this->displayName; + } + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setUnit($unit) { + $this->unit = $unit; + } + public function getUnit() { + return $this->unit; + } +} + +class ShoppingModelProductJsonV1Author extends apiModel { + public $name; + public $accountId; + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setAccountId($accountId) { + $this->accountId = $accountId; + } + public function getAccountId() { + return $this->accountId; + } +} + +class ShoppingModelProductJsonV1Images extends apiModel { + public $link; + protected $__thumbnailsType = 'ShoppingModelProductJsonV1ImagesThumbnails'; + protected $__thumbnailsDataType = 'array'; + public $thumbnails; + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setThumbnails(/* array(ShoppingModelProductJsonV1ImagesThumbnails) */ $thumbnails) { + $this->assertIsArray($thumbnails, 'ShoppingModelProductJsonV1ImagesThumbnails', __METHOD__); + $this->thumbnails = $thumbnails; + } + public function getThumbnails() { + return $this->thumbnails; + } +} + +class ShoppingModelProductJsonV1ImagesThumbnails extends apiModel { + public $content; + public $width; + public $link; + public $height; + public function setContent($content) { + $this->content = $content; + } + public function getContent() { + return $this->content; + } + public function setWidth($width) { + $this->width = $width; + } + public function getWidth() { + return $this->width; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setHeight($height) { + $this->height = $height; + } + public function getHeight() { + return $this->height; + } +} + +class ShoppingModelProductJsonV1Internal4 extends apiModel { + public $node; + public $confidence; + public function setNode($node) { + $this->node = $node; + } + public function getNode() { + return $this->node; + } + public function setConfidence($confidence) { + $this->confidence = $confidence; + } + public function getConfidence() { + return $this->confidence; + } +} + +class ShoppingModelProductJsonV1Inventories extends apiModel { + public $distance; + public $price; + public $storeId; + public $tax; + public $shipping; + public $currency; + public $distanceUnit; + public $availability; + public $channel; + public function setDistance($distance) { + $this->distance = $distance; + } + public function getDistance() { + return $this->distance; + } + public function setPrice($price) { + $this->price = $price; + } + public function getPrice() { + return $this->price; + } + public function setStoreId($storeId) { + $this->storeId = $storeId; + } + public function getStoreId() { + return $this->storeId; + } + public function setTax($tax) { + $this->tax = $tax; + } + public function getTax() { + return $this->tax; + } + public function setShipping($shipping) { + $this->shipping = $shipping; + } + public function getShipping() { + return $this->shipping; + } + public function setCurrency($currency) { + $this->currency = $currency; + } + public function getCurrency() { + return $this->currency; + } + public function setDistanceUnit($distanceUnit) { + $this->distanceUnit = $distanceUnit; + } + public function getDistanceUnit() { + return $this->distanceUnit; + } + public function setAvailability($availability) { + $this->availability = $availability; + } + public function getAvailability() { + return $this->availability; + } + public function setChannel($channel) { + $this->channel = $channel; + } + public function getChannel() { + return $this->channel; + } +} + +class ShoppingModelProductJsonV1Variants extends apiModel { + protected $__variantType = 'ShoppingModelProductJsonV1'; + protected $__variantDataType = ''; + public $variant; + public function setVariant(ShoppingModelProductJsonV1 $variant) { + $this->variant = $variant; + } + public function getVariant() { + return $this->variant; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiSiteVerificationService.php b/inc/vendors/social-login/Google/contrib/apiSiteVerificationService.php new file mode 100755 index 00000000..198c9add --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiSiteVerificationService.php @@ -0,0 +1,277 @@ + + * $siteVerificationService = new apiSiteVerificationService(...); + * $webResource = $siteVerificationService->webResource; + * + */ + class WebResourceServiceResource extends apiServiceResource { + + + /** + * Attempt verification of a website or domain. (webResource.insert) + * @param string $verificationMethod The method to use for verifying a site or domain. + * @param SiteVerificationWebResourceResource $postBody + * @return SiteVerificationWebResourceResource + */ + public function insert($verificationMethod, SiteVerificationWebResourceResource $postBody, $optParams = array()) { + $params = array('verificationMethod' => $verificationMethod, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new SiteVerificationWebResourceResource($data); + } else { + return $data; + } + } + /** + * Get the most current data for a website or domain. (webResource.get) + * @param string $id The id of a verified site or domain. + * @return SiteVerificationWebResourceResource + */ + public function get($id, $optParams = array()) { + $params = array('id' => $id); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new SiteVerificationWebResourceResource($data); + } else { + return $data; + } + } + /** + * Get the list of your verified websites and domains. (webResource.list) + * @return SiteVerificationWebResourceListResponse + */ + public function listWebResource($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new SiteVerificationWebResourceListResponse($data); + } else { + return $data; + } + } + /** + * Modify the list of owners for your website or domain. (webResource.update) + * @param string $id The id of a verified site or domain. + * @param SiteVerificationWebResourceResource $postBody + * @return SiteVerificationWebResourceResource + */ + public function update($id, SiteVerificationWebResourceResource $postBody, $optParams = array()) { + $params = array('id' => $id, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new SiteVerificationWebResourceResource($data); + } else { + return $data; + } + } + /** + * Modify the list of owners for your website or domain. This method supports patch semantics. + * (webResource.patch) + * @param string $id The id of a verified site or domain. + * @param SiteVerificationWebResourceResource $postBody + * @return SiteVerificationWebResourceResource + */ + public function patch($id, SiteVerificationWebResourceResource $postBody, $optParams = array()) { + $params = array('id' => $id, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new SiteVerificationWebResourceResource($data); + } else { + return $data; + } + } + /** + * Get a verification token for placing on a website or domain. (webResource.getToken) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string verificationMethod The method to use for verifying a site or domain. + * @opt_param string identifier The URL or domain to verify. + * @opt_param string type Type of resource to verify. Can be 'site' (URL) or 'inet_domain' (domain name). + * @return SiteVerificationWebResourceGettokenResponse + */ + public function getToken($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('getToken', array($params)); + if ($this->useObjects()) { + return new SiteVerificationWebResourceGettokenResponse($data); + } else { + return $data; + } + } + /** + * Relinquish ownership of a website or domain. (webResource.delete) + * @param string $id The id of a verified site or domain. + */ + public function delete($id, $optParams = array()) { + $params = array('id' => $id); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + + +/** + * Service definition for SiteVerification (v1). + *

            + * Lets you programatically verify ownership of websites or domains with Google. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiSiteVerificationService extends apiService { + public $webResource; + /** + * Constructs the internal representation of the SiteVerification service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/siteVerification/v1/'; + $this->version = 'v1'; + $this->serviceName = 'siteVerification'; + + $apiClient->addService($this->serviceName, $this->version); + $this->webResource = new WebResourceServiceResource($this, $this->serviceName, 'webResource', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/siteverification"], "parameters": {"verificationMethod": {"required": true, "type": "string", "location": "query"}}, "request": {"$ref": "SiteVerificationWebResourceResource"}, "id": "siteVerification.webResource.insert", "httpMethod": "POST", "path": "webResource", "response": {"$ref": "SiteVerificationWebResourceResource"}}, "get": {"scopes": ["https://www.googleapis.com/auth/siteverification"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "id": "siteVerification.webResource.get", "httpMethod": "GET", "path": "webResource/{id}", "response": {"$ref": "SiteVerificationWebResourceResource"}}, "list": {"scopes": ["https://www.googleapis.com/auth/siteverification"], "id": "siteVerification.webResource.list", "httpMethod": "GET", "path": "webResource", "response": {"$ref": "SiteVerificationWebResourceListResponse"}}, "update": {"scopes": ["https://www.googleapis.com/auth/siteverification"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "SiteVerificationWebResourceResource"}, "id": "siteVerification.webResource.update", "httpMethod": "PUT", "path": "webResource/{id}", "response": {"$ref": "SiteVerificationWebResourceResource"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/siteverification"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "SiteVerificationWebResourceResource"}, "id": "siteVerification.webResource.patch", "httpMethod": "PATCH", "path": "webResource/{id}", "response": {"$ref": "SiteVerificationWebResourceResource"}}, "getToken": {"scopes": ["https://www.googleapis.com/auth/siteverification"], "parameters": {"type": {"type": "string", "location": "query"}, "identifier": {"type": "string", "location": "query"}, "verificationMethod": {"type": "string", "location": "query"}}, "response": {"$ref": "SiteVerificationWebResourceGettokenResponse"}, "httpMethod": "GET", "path": "token", "id": "siteVerification.webResource.getToken"}, "delete": {"scopes": ["https://www.googleapis.com/auth/siteverification"], "parameters": {"id": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "webResource/{id}", "id": "siteVerification.webResource.delete"}}}', true)); + } +} + +class SiteVerificationWebResourceGettokenRequest extends apiModel { + public $verificationMethod; + protected $__siteType = 'SiteVerificationWebResourceGettokenRequestSite'; + protected $__siteDataType = ''; + public $site; + public function setVerificationMethod($verificationMethod) { + $this->verificationMethod = $verificationMethod; + } + public function getVerificationMethod() { + return $this->verificationMethod; + } + public function setSite(SiteVerificationWebResourceGettokenRequestSite $site) { + $this->site = $site; + } + public function getSite() { + return $this->site; + } +} + +class SiteVerificationWebResourceGettokenRequestSite extends apiModel { + public $identifier; + public $type; + public function setIdentifier($identifier) { + $this->identifier = $identifier; + } + public function getIdentifier() { + return $this->identifier; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} + +class SiteVerificationWebResourceGettokenResponse extends apiModel { + public $token; + public $method; + public function setToken($token) { + $this->token = $token; + } + public function getToken() { + return $this->token; + } + public function setMethod($method) { + $this->method = $method; + } + public function getMethod() { + return $this->method; + } +} + +class SiteVerificationWebResourceListResponse extends apiModel { + protected $__itemsType = 'SiteVerificationWebResourceResource'; + protected $__itemsDataType = 'array'; + public $items; + public function setItems(/* array(SiteVerificationWebResourceResource) */ $items) { + $this->assertIsArray($items, 'SiteVerificationWebResourceResource', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } +} + +class SiteVerificationWebResourceResource extends apiModel { + public $owners; + public $id; + protected $__siteType = 'SiteVerificationWebResourceResourceSite'; + protected $__siteDataType = ''; + public $site; + public function setOwners(/* array(string) */ $owners) { + $this->assertIsArray($owners, 'string', __METHOD__); + $this->owners = $owners; + } + public function getOwners() { + return $this->owners; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSite(SiteVerificationWebResourceResourceSite $site) { + $this->site = $site; + } + public function getSite() { + return $this->site; + } +} + +class SiteVerificationWebResourceResourceSite extends apiModel { + public $identifier; + public $type; + public function setIdentifier($identifier) { + $this->identifier = $identifier; + } + public function getIdentifier() { + return $this->identifier; + } + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiTasksService.php b/inc/vendors/social-login/Google/contrib/apiTasksService.php new file mode 100755 index 00000000..4e20fb00 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiTasksService.php @@ -0,0 +1,546 @@ + + * $tasksService = new apiTasksService(...); + * $tasks = $tasksService->tasks; + * + */ + class TasksServiceResource extends apiServiceResource { + + + /** + * Creates a new task on the specified task list. (tasks.insert) + * @param string $tasklist Task list identifier. + * @param Task $postBody + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string parent Parent task identifier. If the task is created at the top level, this parameter is omitted. Optional. + * @opt_param string previous Previous sibling task identifier. If the task is created at the first position among its siblings, this parameter is omitted. Optional. + * @return Task + */ + public function insert($tasklist, Task $postBody, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Task($data); + } else { + return $data; + } + } + /** + * Returns the specified task. (tasks.get) + * @param string $tasklist Task list identifier. + * @param string $task Task identifier. + * @return Task + */ + public function get($tasklist, $task, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'task' => $task); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Task($data); + } else { + return $data; + } + } + /** + * Clears all completed tasks from the specified task list. The affected tasks will be marked as + * 'hidden' and no longer be returned by default when retrieving all tasks for a task list. + * (tasks.clear) + * @param string $tasklist Task list identifier. + */ + public function clear($tasklist, $optParams = array()) { + $params = array('tasklist' => $tasklist); + $params = array_merge($params, $optParams); + $data = $this->__call('clear', array($params)); + return $data; + } + /** + * Moves the specified task to another position in the task list. This can include putting it as a + * child task under a new parent and/or move it to a different position among its sibling tasks. + * (tasks.move) + * @param string $tasklist Task list identifier. + * @param string $task Task identifier. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string parent New parent task identifier. If the task is moved to the top level, this parameter is omitted. Optional. + * @opt_param string previous New previous sibling task identifier. If the task is moved to the first position among its siblings, this parameter is omitted. Optional. + * @return Task + */ + public function move($tasklist, $task, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'task' => $task); + $params = array_merge($params, $optParams); + $data = $this->__call('move', array($params)); + if ($this->useObjects()) { + return new Task($data); + } else { + return $data; + } + } + /** + * Returns all tasks in the specified task list. (tasks.list) + * @param string $tasklist Task list identifier. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string dueMax Upper bound for a task's due date (as a RFC 3339 timestamp) to filter by. Optional. The default is not to filter by due date. + * @opt_param bool showDeleted Flag indicating whether deleted tasks are returned in the result. Optional. The default is False. + * @opt_param string updatedMin Lower bound for a task's last modification time (as a RFC 3339 timestamp) to filter by. Optional. The default is not to filter by last modification time. + * @opt_param string completedMin Lower bound for a task's completion date (as a RFC 3339 timestamp) to filter by. Optional. The default is not to filter by completion date. + * @opt_param string maxResults Maximum number of task lists returned on one page. Optional. The default is 100. + * @opt_param bool showCompleted Flag indicating whether completed tasks are returned in the result. Optional. The default is True. + * @opt_param string pageToken Token specifying the result page to return. Optional. + * @opt_param string completedMax Upper bound for a task's completion date (as a RFC 3339 timestamp) to filter by. Optional. The default is not to filter by completion date. + * @opt_param bool showHidden Flag indicating whether hidden tasks are returned in the result. Optional. The default is False. + * @opt_param string dueMin Lower bound for a task's due date (as a RFC 3339 timestamp) to filter by. Optional. The default is not to filter by due date. + * @return Tasks + */ + public function listTasks($tasklist, $optParams = array()) { + $params = array('tasklist' => $tasklist); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new Tasks($data); + } else { + return $data; + } + } + /** + * Updates the specified task. (tasks.update) + * @param string $tasklist Task list identifier. + * @param string $task Task identifier. + * @param Task $postBody + * @return Task + */ + public function update($tasklist, $task, Task $postBody, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'task' => $task, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new Task($data); + } else { + return $data; + } + } + /** + * Updates the specified task. This method supports patch semantics. (tasks.patch) + * @param string $tasklist Task list identifier. + * @param string $task Task identifier. + * @param Task $postBody + * @return Task + */ + public function patch($tasklist, $task, Task $postBody, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'task' => $task, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new Task($data); + } else { + return $data; + } + } + /** + * Deletes the specified task from the task list. (tasks.delete) + * @param string $tasklist Task list identifier. + * @param string $task Task identifier. + */ + public function delete($tasklist, $task, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'task' => $task); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + /** + * The "tasklists" collection of methods. + * Typical usage is: + * + * $tasksService = new apiTasksService(...); + * $tasklists = $tasksService->tasklists; + * + */ + class TasklistsServiceResource extends apiServiceResource { + + + /** + * Creates a new task list and adds it to the authenticated user's task lists. (tasklists.insert) + * @param TaskList $postBody + * @return TaskList + */ + public function insert(TaskList $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new TaskList($data); + } else { + return $data; + } + } + /** + * Returns the authenticated user's specified task list. (tasklists.get) + * @param string $tasklist Task list identifier. + * @return TaskList + */ + public function get($tasklist, $optParams = array()) { + $params = array('tasklist' => $tasklist); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new TaskList($data); + } else { + return $data; + } + } + /** + * Returns all the authenticated user's task lists. (tasklists.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string pageToken Token specifying the result page to return. Optional. + * @opt_param string maxResults Maximum number of task lists returned on one page. Optional. The default is 100. + * @return TaskLists + */ + public function listTasklists($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new TaskLists($data); + } else { + return $data; + } + } + /** + * Updates the authenticated user's specified task list. (tasklists.update) + * @param string $tasklist Task list identifier. + * @param TaskList $postBody + * @return TaskList + */ + public function update($tasklist, TaskList $postBody, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('update', array($params)); + if ($this->useObjects()) { + return new TaskList($data); + } else { + return $data; + } + } + /** + * Updates the authenticated user's specified task list. This method supports patch semantics. + * (tasklists.patch) + * @param string $tasklist Task list identifier. + * @param TaskList $postBody + * @return TaskList + */ + public function patch($tasklist, TaskList $postBody, $optParams = array()) { + $params = array('tasklist' => $tasklist, 'postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('patch', array($params)); + if ($this->useObjects()) { + return new TaskList($data); + } else { + return $data; + } + } + /** + * Deletes the authenticated user's specified task list. (tasklists.delete) + * @param string $tasklist Task list identifier. + */ + public function delete($tasklist, $optParams = array()) { + $params = array('tasklist' => $tasklist); + $params = array_merge($params, $optParams); + $data = $this->__call('delete', array($params)); + return $data; + } + } + + + +/** + * Service definition for Tasks (v1). + *

            + * Lets you manage your tasks and task lists. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiTasksService extends apiService { + public $tasks; + public $tasklists; + /** + * Constructs the internal representation of the Tasks service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/tasks/v1/'; + $this->version = 'v1'; + $this->serviceName = 'tasks'; + + $apiClient->addService($this->serviceName, $this->version); + $this->tasks = new TasksServiceResource($this, $this->serviceName, 'tasks', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}, "parent": {"type": "string", "location": "query"}, "previous": {"type": "string", "location": "query"}}, "request": {"$ref": "Task"}, "id": "tasks.tasks.insert", "httpMethod": "POST", "path": "lists/{tasklist}/tasks", "response": {"$ref": "Task"}}, "get": {"scopes": ["https://www.googleapis.com/auth/tasks", "https://www.googleapis.com/auth/tasks.readonly"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}, "task": {"required": true, "type": "string", "location": "path"}}, "id": "tasks.tasks.get", "httpMethod": "GET", "path": "lists/{tasklist}/tasks/{task}", "response": {"$ref": "Task"}}, "clear": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "POST", "path": "lists/{tasklist}/clear", "id": "tasks.tasks.clear"}, "move": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"previous": {"type": "string", "location": "query"}, "tasklist": {"required": true, "type": "string", "location": "path"}, "parent": {"type": "string", "location": "query"}, "task": {"required": true, "type": "string", "location": "path"}}, "id": "tasks.tasks.move", "httpMethod": "POST", "path": "lists/{tasklist}/tasks/{task}/move", "response": {"$ref": "Task"}}, "list": {"scopes": ["https://www.googleapis.com/auth/tasks", "https://www.googleapis.com/auth/tasks.readonly"], "parameters": {"dueMax": {"type": "string", "location": "query"}, "tasklist": {"required": true, "type": "string", "location": "path"}, "pageToken": {"type": "string", "location": "query"}, "updatedMin": {"type": "string", "location": "query"}, "completedMin": {"type": "string", "location": "query"}, "maxResults": {"format": "int64", "type": "string", "location": "query"}, "showCompleted": {"type": "boolean", "location": "query"}, "showDeleted": {"type": "boolean", "location": "query"}, "completedMax": {"type": "string", "location": "query"}, "showHidden": {"type": "boolean", "location": "query"}, "dueMin": {"type": "string", "location": "query"}}, "id": "tasks.tasks.list", "httpMethod": "GET", "path": "lists/{tasklist}/tasks", "response": {"$ref": "Tasks"}}, "update": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}, "task": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Task"}, "id": "tasks.tasks.update", "httpMethod": "PUT", "path": "lists/{tasklist}/tasks/{task}", "response": {"$ref": "Task"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}, "task": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "Task"}, "id": "tasks.tasks.patch", "httpMethod": "PATCH", "path": "lists/{tasklist}/tasks/{task}", "response": {"$ref": "Task"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}, "task": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "lists/{tasklist}/tasks/{task}", "id": "tasks.tasks.delete"}}}', true)); + $this->tasklists = new TasklistsServiceResource($this, $this->serviceName, 'tasklists', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/tasks"], "request": {"$ref": "TaskList"}, "response": {"$ref": "TaskList"}, "httpMethod": "POST", "path": "users/@me/lists", "id": "tasks.tasklists.insert"}, "get": {"scopes": ["https://www.googleapis.com/auth/tasks", "https://www.googleapis.com/auth/tasks.readonly"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}}, "id": "tasks.tasklists.get", "httpMethod": "GET", "path": "users/@me/lists/{tasklist}", "response": {"$ref": "TaskList"}}, "list": {"scopes": ["https://www.googleapis.com/auth/tasks", "https://www.googleapis.com/auth/tasks.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"format": "int64", "type": "string", "location": "query"}}, "response": {"$ref": "TaskLists"}, "httpMethod": "GET", "path": "users/@me/lists", "id": "tasks.tasklists.list"}, "update": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "TaskList"}, "id": "tasks.tasklists.update", "httpMethod": "PUT", "path": "users/@me/lists/{tasklist}", "response": {"$ref": "TaskList"}}, "patch": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}}, "request": {"$ref": "TaskList"}, "id": "tasks.tasklists.patch", "httpMethod": "PATCH", "path": "users/@me/lists/{tasklist}", "response": {"$ref": "TaskList"}}, "delete": {"scopes": ["https://www.googleapis.com/auth/tasks"], "parameters": {"tasklist": {"required": true, "type": "string", "location": "path"}}, "httpMethod": "DELETE", "path": "users/@me/lists/{tasklist}", "id": "tasks.tasklists.delete"}}}', true)); + } +} + +class Task extends apiModel { + public $status; + public $kind; + public $updated; + public $parent; + protected $__linksType = 'TaskLinks'; + protected $__linksDataType = 'array'; + public $links; + public $title; + public $deleted; + public $completed; + public $due; + public $etag; + public $notes; + public $position; + public $hidden; + public $id; + public $selfLink; + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setUpdated($updated) { + $this->updated = $updated; + } + public function getUpdated() { + return $this->updated; + } + public function setParent($parent) { + $this->parent = $parent; + } + public function getParent() { + return $this->parent; + } + public function setLinks(/* array(TaskLinks) */ $links) { + $this->assertIsArray($links, 'TaskLinks', __METHOD__); + $this->links = $links; + } + public function getLinks() { + return $this->links; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } + public function setDeleted($deleted) { + $this->deleted = $deleted; + } + public function getDeleted() { + return $this->deleted; + } + public function setCompleted($completed) { + $this->completed = $completed; + } + public function getCompleted() { + return $this->completed; + } + public function setDue($due) { + $this->due = $due; + } + public function getDue() { + return $this->due; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setNotes($notes) { + $this->notes = $notes; + } + public function getNotes() { + return $this->notes; + } + public function setPosition($position) { + $this->position = $position; + } + public function getPosition() { + return $this->position; + } + public function setHidden($hidden) { + $this->hidden = $hidden; + } + public function getHidden() { + return $this->hidden; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } +} + +class TaskLinks extends apiModel { + public $type; + public $link; + public $description; + public function setType($type) { + $this->type = $type; + } + public function getType() { + return $this->type; + } + public function setLink($link) { + $this->link = $link; + } + public function getLink() { + return $this->link; + } + public function setDescription($description) { + $this->description = $description; + } + public function getDescription() { + return $this->description; + } +} + +class TaskList extends apiModel { + public $kind; + public $etag; + public $id; + public $selfLink; + public $title; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } + public function setSelfLink($selfLink) { + $this->selfLink = $selfLink; + } + public function getSelfLink() { + return $this->selfLink; + } + public function setTitle($title) { + $this->title = $title; + } + public function getTitle() { + return $this->title; + } +} + +class TaskLists extends apiModel { + public $nextPageToken; + protected $__itemsType = 'TaskList'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(TaskList) */ $items) { + $this->assertIsArray($items, 'TaskList', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} + +class Tasks extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Task'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $etag; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Task) */ $items) { + $this->assertIsArray($items, 'Task', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setEtag($etag) { + $this->etag = $etag; + } + public function getEtag() { + return $this->etag; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiTranslateService.php b/inc/vendors/social-login/Google/contrib/apiTranslateService.php new file mode 100755 index 00000000..d3816466 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiTranslateService.php @@ -0,0 +1,242 @@ + + * $translateService = new apiTranslateService(...); + * $languages = $translateService->languages; + * + */ + class LanguagesServiceResource extends apiServiceResource { + + + /** + * List the source/target languages supported by the API (languages.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string target the language and collation in which the localized results should be returned + * @return LanguagesListResponse + */ + public function listLanguages($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new LanguagesListResponse($data); + } else { + return $data; + } + } + } + + /** + * The "detections" collection of methods. + * Typical usage is: + * + * $translateService = new apiTranslateService(...); + * $detections = $translateService->detections; + * + */ + class DetectionsServiceResource extends apiServiceResource { + + + /** + * Detect the language of text. (detections.list) + * @param string $q The text to detect + * @return DetectionsListResponse + */ + public function listDetections($q, $optParams = array()) { + $params = array('q' => $q); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new DetectionsListResponse($data); + } else { + return $data; + } + } + } + + /** + * The "translations" collection of methods. + * Typical usage is: + * + * $translateService = new apiTranslateService(...); + * $translations = $translateService->translations; + * + */ + class TranslationsServiceResource extends apiServiceResource { + + + /** + * Returns text translations from one language to another. (translations.list) + * @param string $q The text to translate + * @param string $target The target language into which the text should be translated + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string source The source language of the text + * @opt_param string format The format of the text + * @opt_param string cid The customization id for translate + * @return TranslationsListResponse + */ + public function listTranslations($q, $target, $optParams = array()) { + $params = array('q' => $q, 'target' => $target); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new TranslationsListResponse($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Translate (v2). + *

            + * Lets you translate text from one language to another + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiTranslateService extends apiService { + public $languages; + public $detections; + public $translations; + /** + * Constructs the internal representation of the Translate service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/language/translate/'; + $this->version = 'v2'; + $this->serviceName = 'translate'; + + $apiClient->addService($this->serviceName, $this->version); + $this->languages = new LanguagesServiceResource($this, $this->serviceName, 'languages', json_decode('{"methods": {"list": {"parameters": {"target": {"type": "string", "location": "query"}}, "id": "language.languages.list", "httpMethod": "GET", "path": "v2/languages", "response": {"$ref": "LanguagesListResponse"}}}}', true)); + $this->detections = new DetectionsServiceResource($this, $this->serviceName, 'detections', json_decode('{"methods": {"list": {"parameters": {"q": {"repeated": true, "required": true, "type": "string", "location": "query"}}, "id": "language.detections.list", "httpMethod": "GET", "path": "v2/detect", "response": {"$ref": "DetectionsListResponse"}}}}', true)); + $this->translations = new TranslationsServiceResource($this, $this->serviceName, 'translations', json_decode('{"methods": {"list": {"parameters": {"q": {"repeated": true, "required": true, "type": "string", "location": "query"}, "source": {"type": "string", "location": "query"}, "cid": {"repeated": true, "type": "string", "location": "query"}, "target": {"required": true, "type": "string", "location": "query"}, "format": {"enum": ["html", "text"], "type": "string", "location": "query"}}, "id": "language.translations.list", "httpMethod": "GET", "path": "v2", "response": {"$ref": "TranslationsListResponse"}}}}', true)); + } +} + +class DetectionsListResponse extends apiModel { + protected $__detectionsType = 'DetectionsResourceItems'; + protected $__detectionsDataType = 'array'; + public $detections; + public function setDetections(/* array(DetectionsResourceItems) */ $detections) { + $this->assertIsArray($detections, 'DetectionsResourceItems', __METHOD__); + $this->detections = $detections; + } + public function getDetections() { + return $this->detections; + } +} + +class DetectionsResource extends apiModel { +} + +class DetectionsResourceItems extends apiModel { + public $isReliable; + public $confidence; + public $language; + public function setIsReliable($isReliable) { + $this->isReliable = $isReliable; + } + public function getIsReliable() { + return $this->isReliable; + } + public function setConfidence($confidence) { + $this->confidence = $confidence; + } + public function getConfidence() { + return $this->confidence; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } +} + +class LanguagesListResponse extends apiModel { + protected $__languagesType = 'LanguagesResource'; + protected $__languagesDataType = 'array'; + public $languages; + public function setLanguages(/* array(LanguagesResource) */ $languages) { + $this->assertIsArray($languages, 'LanguagesResource', __METHOD__); + $this->languages = $languages; + } + public function getLanguages() { + return $this->languages; + } +} + +class LanguagesResource extends apiModel { + public $name; + public $language; + public function setName($name) { + $this->name = $name; + } + public function getName() { + return $this->name; + } + public function setLanguage($language) { + $this->language = $language; + } + public function getLanguage() { + return $this->language; + } +} + +class TranslationsListResponse extends apiModel { + protected $__translationsType = 'TranslationsResource'; + protected $__translationsDataType = 'array'; + public $translations; + public function setTranslations(/* array(TranslationsResource) */ $translations) { + $this->assertIsArray($translations, 'TranslationsResource', __METHOD__); + $this->translations = $translations; + } + public function getTranslations() { + return $this->translations; + } +} + +class TranslationsResource extends apiModel { + public $detectedSourceLanguage; + public $translatedText; + public function setDetectedSourceLanguage($detectedSourceLanguage) { + $this->detectedSourceLanguage = $detectedSourceLanguage; + } + public function getDetectedSourceLanguage() { + return $this->detectedSourceLanguage; + } + public function setTranslatedText($translatedText) { + $this->translatedText = $translatedText; + } + public function getTranslatedText() { + return $this->translatedText; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiUrlshortenerService.php b/inc/vendors/social-login/Google/contrib/apiUrlshortenerService.php new file mode 100755 index 00000000..dfbb7a57 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiUrlshortenerService.php @@ -0,0 +1,320 @@ + + * $urlshortenerService = new apiUrlshortenerService(...); + * $url = $urlshortenerService->url; + * + */ + class UrlServiceResource extends apiServiceResource { + + + /** + * Creates a new short URL. (url.insert) + * @param Url $postBody + * @return Url + */ + public function insert(Url $postBody, $optParams = array()) { + $params = array('postBody' => $postBody); + $params = array_merge($params, $optParams); + $data = $this->__call('insert', array($params)); + if ($this->useObjects()) { + return new Url($data); + } else { + return $data; + } + } + /** + * Retrieves a list of URLs shortened by a user. (url.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string start-token Token for requesting successive pages of results. + * @opt_param string projection Additional information to return. + * @return UrlHistory + */ + public function listUrl($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new UrlHistory($data); + } else { + return $data; + } + } + /** + * Expands a short URL or gets creation time and analytics. (url.get) + * @param string $shortUrl The short URL, including the protocol. + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string projection Additional information to return. + * @return Url + */ + public function get($shortUrl, $optParams = array()) { + $params = array('shortUrl' => $shortUrl); + $params = array_merge($params, $optParams); + $data = $this->__call('get', array($params)); + if ($this->useObjects()) { + return new Url($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Urlshortener (v1). + *

            + * Lets you create, inspect, and manage goo.gl short URLs + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiUrlshortenerService extends apiService { + public $url; + /** + * Constructs the internal representation of the Urlshortener service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/urlshortener/v1/'; + $this->version = 'v1'; + $this->serviceName = 'urlshortener'; + + $apiClient->addService($this->serviceName, $this->version); + $this->url = new UrlServiceResource($this, $this->serviceName, 'url', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/urlshortener"], "request": {"$ref": "Url"}, "response": {"$ref": "Url"}, "httpMethod": "POST", "path": "url", "id": "urlshortener.url.insert"}, "list": {"scopes": ["https://www.googleapis.com/auth/urlshortener"], "parameters": {"start-token": {"type": "string", "location": "query"}, "projection": {"enum": ["ANALYTICS_CLICKS", "FULL"], "type": "string", "location": "query"}}, "response": {"$ref": "UrlHistory"}, "httpMethod": "GET", "path": "url/history", "id": "urlshortener.url.list"}, "get": {"parameters": {"shortUrl": {"required": true, "type": "string", "location": "query"}, "projection": {"enum": ["ANALYTICS_CLICKS", "ANALYTICS_TOP_STRINGS", "FULL"], "type": "string", "location": "query"}}, "id": "urlshortener.url.get", "httpMethod": "GET", "path": "url", "response": {"$ref": "Url"}}}}', true)); + } +} + +class AnalyticsSnapshot extends apiModel { + public $shortUrlClicks; + protected $__countriesType = 'StringCount'; + protected $__countriesDataType = 'array'; + public $countries; + protected $__platformsType = 'StringCount'; + protected $__platformsDataType = 'array'; + public $platforms; + protected $__browsersType = 'StringCount'; + protected $__browsersDataType = 'array'; + public $browsers; + protected $__referrersType = 'StringCount'; + protected $__referrersDataType = 'array'; + public $referrers; + public $longUrlClicks; + public function setShortUrlClicks($shortUrlClicks) { + $this->shortUrlClicks = $shortUrlClicks; + } + public function getShortUrlClicks() { + return $this->shortUrlClicks; + } + public function setCountries(/* array(StringCount) */ $countries) { + $this->assertIsArray($countries, 'StringCount', __METHOD__); + $this->countries = $countries; + } + public function getCountries() { + return $this->countries; + } + public function setPlatforms(/* array(StringCount) */ $platforms) { + $this->assertIsArray($platforms, 'StringCount', __METHOD__); + $this->platforms = $platforms; + } + public function getPlatforms() { + return $this->platforms; + } + public function setBrowsers(/* array(StringCount) */ $browsers) { + $this->assertIsArray($browsers, 'StringCount', __METHOD__); + $this->browsers = $browsers; + } + public function getBrowsers() { + return $this->browsers; + } + public function setReferrers(/* array(StringCount) */ $referrers) { + $this->assertIsArray($referrers, 'StringCount', __METHOD__); + $this->referrers = $referrers; + } + public function getReferrers() { + return $this->referrers; + } + public function setLongUrlClicks($longUrlClicks) { + $this->longUrlClicks = $longUrlClicks; + } + public function getLongUrlClicks() { + return $this->longUrlClicks; + } +} + +class AnalyticsSummary extends apiModel { + protected $__weekType = 'AnalyticsSnapshot'; + protected $__weekDataType = ''; + public $week; + protected $__allTimeType = 'AnalyticsSnapshot'; + protected $__allTimeDataType = ''; + public $allTime; + protected $__twoHoursType = 'AnalyticsSnapshot'; + protected $__twoHoursDataType = ''; + public $twoHours; + protected $__dayType = 'AnalyticsSnapshot'; + protected $__dayDataType = ''; + public $day; + protected $__monthType = 'AnalyticsSnapshot'; + protected $__monthDataType = ''; + public $month; + public function setWeek(AnalyticsSnapshot $week) { + $this->week = $week; + } + public function getWeek() { + return $this->week; + } + public function setAllTime(AnalyticsSnapshot $allTime) { + $this->allTime = $allTime; + } + public function getAllTime() { + return $this->allTime; + } + public function setTwoHours(AnalyticsSnapshot $twoHours) { + $this->twoHours = $twoHours; + } + public function getTwoHours() { + return $this->twoHours; + } + public function setDay(AnalyticsSnapshot $day) { + $this->day = $day; + } + public function getDay() { + return $this->day; + } + public function setMonth(AnalyticsSnapshot $month) { + $this->month = $month; + } + public function getMonth() { + return $this->month; + } +} + +class StringCount extends apiModel { + public $count; + public $id; + public function setCount($count) { + $this->count = $count; + } + public function getCount() { + return $this->count; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class Url extends apiModel { + public $status; + public $kind; + public $created; + protected $__analyticsType = 'AnalyticsSummary'; + protected $__analyticsDataType = ''; + public $analytics; + public $longUrl; + public $id; + public function setStatus($status) { + $this->status = $status; + } + public function getStatus() { + return $this->status; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setCreated($created) { + $this->created = $created; + } + public function getCreated() { + return $this->created; + } + public function setAnalytics(AnalyticsSummary $analytics) { + $this->analytics = $analytics; + } + public function getAnalytics() { + return $this->analytics; + } + public function setLongUrl($longUrl) { + $this->longUrl = $longUrl; + } + public function getLongUrl() { + return $this->longUrl; + } + public function setId($id) { + $this->id = $id; + } + public function getId() { + return $this->id; + } +} + +class UrlHistory extends apiModel { + public $nextPageToken; + protected $__itemsType = 'Url'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public $itemsPerPage; + public $totalItems; + public function setNextPageToken($nextPageToken) { + $this->nextPageToken = $nextPageToken; + } + public function getNextPageToken() { + return $this->nextPageToken; + } + public function setItems(/* array(Url) */ $items) { + $this->assertIsArray($items, 'Url', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setItemsPerPage($itemsPerPage) { + $this->itemsPerPage = $itemsPerPage; + } + public function getItemsPerPage() { + return $this->itemsPerPage; + } + public function setTotalItems($totalItems) { + $this->totalItems = $totalItems; + } + public function getTotalItems() { + return $this->totalItems; + } +} diff --git a/inc/vendors/social-login/Google/contrib/apiWebfontsService.php b/inc/vendors/social-login/Google/contrib/apiWebfontsService.php new file mode 100755 index 00000000..bd89de02 --- /dev/null +++ b/inc/vendors/social-login/Google/contrib/apiWebfontsService.php @@ -0,0 +1,129 @@ + + * $webfontsService = new apiWebfontsService(...); + * $webfonts = $webfontsService->webfonts; + * + */ + class WebfontsServiceResource extends apiServiceResource { + + + /** + * Retrieves the list of fonts currently served by the Google Web Fonts Developer API + * (webfonts.list) + * @param array $optParams Optional parameters. Valid optional parameters are listed below. + * @opt_param string sort Enables sorting of the list + * @return WebfontList + */ + public function listWebfonts($optParams = array()) { + $params = array(); + $params = array_merge($params, $optParams); + $data = $this->__call('list', array($params)); + if ($this->useObjects()) { + return new WebfontList($data); + } else { + return $data; + } + } + } + + + +/** + * Service definition for Webfonts (v1). + *

            + * The Google Web Fonts Developer API. + *

            + *

            + * For more information about this service, see the + * API Documentation + *

            + * @author Google, Inc. + */ +class apiWebfontsService extends apiService { + public $webfonts; + /** + * Constructs the internal representation of the Webfonts service. + * @param apiClient apiClient + */ + public function __construct(apiClient $apiClient) { + $this->rpcPath = '/rpc'; + $this->restBasePath = '/webfonts/v1/'; + $this->version = 'v1'; + $this->serviceName = 'webfonts'; + + $apiClient->addService($this->serviceName, $this->version); + $this->webfonts = new WebfontsServiceResource($this, $this->serviceName, 'webfonts', json_decode('{"methods": {"list": {"parameters": {"sort": {"enum": ["alpha", "date", "popularity", "style", "trending"], "type": "string", "location": "query"}}, "id": "webfonts.webfonts.list", "httpMethod": "GET", "path": "webfonts", "response": {"$ref": "WebfontList"}}}}', true)); + } +} + +class Webfont extends apiModel { + public $kind; + public $variants; + public $subsets; + public $family; + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } + public function setVariants($variants) { + $this->variants = $variants; + } + public function getVariants() { + return $this->variants; + } + public function setSubsets($subsets) { + $this->subsets = $subsets; + } + public function getSubsets() { + return $this->subsets; + } + public function setFamily($family) { + $this->family = $family; + } + public function getFamily() { + return $this->family; + } +} + +class WebfontList extends apiModel { + protected $__itemsType = 'Webfont'; + protected $__itemsDataType = 'array'; + public $items; + public $kind; + public function setItems(/* array(Webfont) */ $items) { + $this->assertIsArray($items, 'Webfont', __METHOD__); + $this->items = $items; + } + public function getItems() { + return $this->items; + } + public function setKind($kind) { + $this->kind = $kind; + } + public function getKind() { + return $this->kind; + } +} diff --git a/inc/vendors/social-login/Google/external/OAuth.php b/inc/vendors/social-login/Google/external/OAuth.php new file mode 100755 index 00000000..08e6f9fe --- /dev/null +++ b/inc/vendors/social-login/Google/external/OAuth.php @@ -0,0 +1,482 @@ +key = $key; + $this->secret = $secret; + $this->callback_url = $callback_url; + } +} + +class apiClientOAuthToken { + // access tokens and request tokens + public $key; + public $secret; + + /** + * key = the token + * secret = the token secret + */ + function __construct($key, $secret) { + $this->key = $key; + $this->secret = $secret; + } + + /** + * generates the basic string serialization of a token that a server + * would respond to request_token and access_token calls with + */ + function to_string() { + return "oauth_token=" . apiClientOAuthUtil::urlencodeRFC3986($this->key) . + "&oauth_token_secret=" . apiClientOAuthUtil::urlencodeRFC3986($this->secret); + } + + function __toString() { + return $this->to_string(); + } +} + +class apiClientOAuthSignatureMethod { + public function check_signature(&$request, $consumer, $token, $signature) { + $built = $this->build_signature($request, $consumer, $token); + return $built == $signature; + } +} + +class apiClientOAuthSignatureMethod_HMAC_SHA1 extends apiClientOAuthSignatureMethod { + function get_name() { + return "HMAC-SHA1"; + } + + public function build_signature($request, $consumer, $token, $privKey=NULL) { + $base_string = $request->get_signature_base_string(); + $request->base_string = $base_string; + + $key_parts = array( + $consumer->secret, + ($token) ? $token->secret : "" + ); + + $key_parts = array_map(array('apiClientOAuthUtil','urlencodeRFC3986'), $key_parts); + $key = implode('&', $key_parts); + + return base64_encode( hash_hmac('sha1', $base_string, $key, true)); + } +} + +class apiClientOAuthSignatureMethod_RSA_SHA1 extends apiClientOAuthSignatureMethod { + public function get_name() { + return "RSA-SHA1"; + } + + protected function fetch_public_cert(&$request) { + // not implemented yet, ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // (2) fetch via http using a url provided by the requester + // (3) some sort of specific discovery code based on request + // + // either way should return a string representation of the certificate + throw Exception("fetch_public_cert not implemented"); + } + + protected function fetch_private_cert($privKey) {//&$request) { + // not implemented yet, ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // + // either way should return a string representation of the certificate + throw Exception("fetch_private_cert not implemented"); + } + + public function build_signature(&$request, $consumer, $token, $privKey) { + $base_string = $request->get_signature_base_string(); + + // Fetch the private key cert based on the request + //$cert = $this->fetch_private_cert($consumer->privKey); + + //Pull the private key ID from the certificate + //$privatekeyid = openssl_get_privatekey($cert); + + // hacked in + if ($privKey == '') { + $fp = fopen($GLOBALS['PRIV_KEY_FILE'], "r"); + $privKey = fread($fp, 8192); + fclose($fp); + } + $privatekeyid = openssl_get_privatekey($privKey); + + //Check the computer signature against the one passed in the query + $ok = openssl_sign($base_string, $signature, $privatekeyid); + + //Release the key resource + openssl_free_key($privatekeyid); + + return base64_encode($signature); + } + + public function check_signature(&$request, $consumer, $token, $signature) { + $decoded_sig = base64_decode($signature); + + $base_string = $request->get_signature_base_string(); + + // Fetch the public key cert based on the request + $cert = $this->fetch_public_cert($request); + + //Pull the public key ID from the certificate + $publickeyid = openssl_get_publickey($cert); + + //Check the computer signature against the one passed in the query + $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); + + //Release the key resource + openssl_free_key($publickeyid); + + return $ok == 1; + } +} + +class apiClientOAuthRequest { + private $parameters; + private $http_method; + private $http_url; + // for debug purposes + public $base_string; + public static $version = '1.0'; + + function __construct($http_method, $http_url, $parameters=NULL) { + @$parameters or $parameters = array(); + $this->parameters = $parameters; + $this->http_method = $http_method; + $this->http_url = $http_url; + } + + + /** + * attempt to build up a request from what was passed to the server + */ + public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { + $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") ? 'http' : 'https'; + @$http_url or $http_url = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + @$http_method or $http_method = $_SERVER['REQUEST_METHOD']; + + $request_headers = apiClientOAuthRequest::get_headers(); + + // let the library user override things however they'd like, if they know + // which parameters to use then go for it, for example XMLRPC might want to + // do this + if ($parameters) { + $req = new apiClientOAuthRequest($http_method, $http_url, $parameters); + } + // next check for the auth header, we need to do some extra stuff + // if that is the case, namely suck in the parameters from GET or POST + // so that we can include them in the signature + else if (@substr($request_headers['Authorization'], 0, 5) == "OAuth") { + $header_parameters = apiClientOAuthRequest::split_header($request_headers['Authorization']); + if ($http_method == "GET") { + $req_parameters = $_GET; + } + else if ($http_method = "POST") { + $req_parameters = $_POST; + } + $parameters = array_merge($header_parameters, $req_parameters); + $req = new apiClientOAuthRequest($http_method, $http_url, $parameters); + } + else if ($http_method == "GET") { + $req = new apiClientOAuthRequest($http_method, $http_url, $_GET); + } + else if ($http_method == "POST") { + $req = new apiClientOAuthRequest($http_method, $http_url, $_POST); + } + return $req; + } + + /** + * pretty much a helper function to set up the request + */ + public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { + @$parameters or $parameters = array(); + $defaults = array("oauth_version" => apiClientOAuthRequest::$version, + "oauth_nonce" => apiClientOAuthRequest::generate_nonce(), + "oauth_timestamp" => apiClientOAuthRequest::generate_timestamp(), + "oauth_consumer_key" => $consumer->key); + $parameters = array_merge($defaults, $parameters); + + if ($token) { + $parameters['oauth_token'] = $token->key; + } + + // oauth v1.0a + /*if (isset($_REQUEST['oauth_verifier'])) { + $parameters['oauth_verifier'] = $_REQUEST['oauth_verifier']; + }*/ + + + return new apiClientOAuthRequest($http_method, $http_url, $parameters); + } + + public function set_parameter($name, $value) { + $this->parameters[$name] = $value; + } + + public function get_parameter($name) { + return $this->parameters[$name]; + } + + public function get_parameters() { + return $this->parameters; + } + + /** + * Returns the normalized parameters of the request + * This will be all (except oauth_signature) parameters, + * sorted first by key, and if duplicate keys, then by + * value. + * The returned string will be all the key=value pairs + * concated by &. + * @return string + */ + public function get_signable_parameters() { + // Grab all parameters + $params = $this->parameters; + + // Remove oauth_signature if present + if (isset($params['oauth_signature'])) { + unset($params['oauth_signature']); + } + + // Urlencode both keys and values + $keys = array_map(array('apiClientOAuthUtil', 'urlencodeRFC3986'), array_keys($params)); + $values = array_map(array('apiClientOAuthUtil', 'urlencodeRFC3986'), array_values($params)); + $params = array_combine($keys, $values); + + // Sort by keys (natsort) + uksort($params, 'strnatcmp'); + +if(isset($params['title']) && isset($params['title-exact'])) { + $temp = $params['title-exact']; + $title = $params['title']; + + unset($params['title']); + unset($params['title-exact']); + + $params['title-exact'] = $temp; + $params['title'] = $title; +} + + // Generate key=value pairs + $pairs = array(); + foreach ($params as $key=>$value ) { + if (is_array($value)) { + // If the value is an array, it's because there are multiple + // with the same key, sort them, then add all the pairs + natsort($value); + foreach ($value as $v2) { + $pairs[] = $key . '=' . $v2; + } + } else { + $pairs[] = $key . '=' . $value; + } + } + + // Return the pairs, concated with & + return implode('&', $pairs); + } + + /** + * Returns the base string of this request + * The base string defined as the method, the url + * and the parameters (normalized), each urlencoded + * and the concated with &. + */ + public function get_signature_base_string() { + $parts = array( + $this->get_normalized_http_method(), + $this->get_normalized_http_url(), + $this->get_signable_parameters() + ); + + $parts = array_map(array('apiClientOAuthUtil', 'urlencodeRFC3986'), $parts); + + return implode('&', $parts); + } + + /** + * just uppercases the http method + */ + public function get_normalized_http_method() { + return strtoupper($this->http_method); + } + + /** + * parses the url and rebuilds it to be + * scheme://host/path + */ + public function get_normalized_http_url() { + $parts = parse_url($this->http_url); + + // FIXME: port should handle according to http://groups.google.com/group/oauth/browse_thread/thread/1b203a51d9590226 + $port = (isset($parts['port']) && $parts['port'] != '80') ? ':' . $parts['port'] : ''; + $path = (isset($parts['path'])) ? $parts['path'] : ''; + + return $parts['scheme'] . '://' . $parts['host'] . $port . $path; + } + + /** + * builds a url usable for a GET request + */ + public function to_url() { + $out = $this->get_normalized_http_url() . "?"; + $out .= $this->to_postdata(); + return $out; + } + + /** + * builds the data one would send in a POST request + */ + public function to_postdata() { + $total = array(); + foreach ($this->parameters as $k => $v) { + $total[] = apiClientOAuthUtil::urlencodeRFC3986($k) . "=" . apiClientOAuthUtil::urlencodeRFC3986($v); + } + $out = implode("&", $total); + return $out; + } + + /** + * builds the Authorization: header + */ + public function to_header() { + $out ='Authorization: OAuth '; + $total = array(); + foreach ($this->parameters as $k => $v) { + if (substr($k, 0, 5) != "oauth") continue; + $out .= apiClientOAuthUtil::urlencodeRFC3986($k) . '="' . apiClientOAuthUtil::urlencodeRFC3986($v) . '", '; + } + $out = substr_replace($out, '', strlen($out) - 2); + return $out; + } + + public function __toString() { + return $this->to_url(); + } + + + public function sign_request($signature_method, $consumer, $token, $privKey=NULL) { + $this->set_parameter("oauth_signature_method", $signature_method->get_name()); + $signature = $this->build_signature($signature_method, $consumer, $token, $privKey); + $this->set_parameter("oauth_signature", $signature); + } + + public function build_signature($signature_method, $consumer, $token, $privKey=NULL) { + $signature = $signature_method->build_signature($this, $consumer, $token, $privKey); + return $signature; + } + + /** + * util function: current timestamp + */ + private static function generate_timestamp() { + return time(); + } + + /** + * util function: current nonce + */ + private static function generate_nonce() { + $mt = microtime(); + $rand = mt_rand(); + + return md5($mt . $rand); // md5s look nicer than numbers + } + + /** + * util function for turning the Authorization: header into + * parameters, has to do some unescaping + */ + private static function split_header($header) { + // this should be a regex + // error cases: commas in parameter values + $parts = explode(",", $header); + $out = array(); + foreach ($parts as $param) { + $param = ltrim($param); + // skip the "realm" param, nobody ever uses it anyway + if (substr($param, 0, 5) != "oauth") continue; + + $param_parts = explode("=", $param); + + // rawurldecode() used because urldecode() will turn a "+" in the + // value into a space + $out[$param_parts[0]] = rawurldecode(substr($param_parts[1], 1, -1)); + } + return $out; + } + + /** + * helper to try to sort out headers for people who aren't running apache + */ + private static function get_headers() { + if (function_exists('apache_request_headers')) { + // we need this to get the actual Authorization: header + // because apache tends to tell us it doesn't exist + return apache_request_headers(); + } + // otherwise we don't have apache and are just going to have to hope + // that $_SERVER actually contains what we need + $out = array(); + foreach ($_SERVER as $key => $value) { + if (substr($key, 0, 5) == "HTTP_") { + // this is chaos, basically it is just there to capitalize the first + // letter of every word that is not an initial HTTP and strip HTTP + // code from przemek + $key = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($key, 5))))); + $out[$key] = $value; + } + } + return $out; + } +} + +class apiClientOAuthDataStore { + function lookup_consumer($consumer_key) { + // implement me + } + + function lookup_token($consumer, $token_type, $token) { + // implement me + } + + function lookup_nonce($consumer, $token, $nonce, $timestamp) { + // implement me + } + + function fetch_request_token($consumer) { + // return a new token attached to this consumer + } + + function fetch_access_token($token, $consumer) { + // return a new access token attached to this consumer + // for the user associated with this token if the request token + // is authorized + // should also invalidate the request token + } + +} + +class apiClientOAuthUtil { + public static function urlencodeRFC3986($string) { + return str_replace('%7E', '~', rawurlencode($string)); + } + + public static function urldecodeRFC3986($string) { + return rawurldecode($string); + } +} diff --git a/inc/vendors/social-login/Google/external/URITemplateParser.php b/inc/vendors/social-login/Google/external/URITemplateParser.php new file mode 100755 index 00000000..594adbb1 --- /dev/null +++ b/inc/vendors/social-login/Google/external/URITemplateParser.php @@ -0,0 +1,209 @@ +template = $template; + } + + public function expand($data) { + // Modification to make this a bit more performant (since gettype is very slow) + if (! is_array($data)) { + $data = (array)$data; + } + /* + // Original code, which uses a slow gettype() statement, kept in place for if the assumption that is_array always works here is incorrect + switch (gettype($data)) { + case "boolean": + case "integer": + case "double": + case "string": + case "object": + $data = (array)$data; + break; + } +*/ + + // Resolve template vars + preg_match_all('/\{([^\}]*)\}/', $this->template, $em); + + foreach ($em[1] as $i => $bare_expression) { + preg_match('/^([\+\;\?\/\.]{1})?(.*)$/', $bare_expression, $lm); + $exp = new StdClass(); + $exp->expression = $em[0][$i]; + $exp->operator = $lm[1]; + $exp->variable_list = $lm[2]; + $exp->varspecs = explode(',', $exp->variable_list); + $exp->vars = array(); + foreach ($exp->varspecs as $varspec) { + preg_match('/^([a-zA-Z0-9_]+)([\*\+]{1})?([\:\^][0-9-]+)?(\=[^,]+)?$/', $varspec, $vm); + $var = new StdClass(); + $var->name = $vm[1]; + $var->modifier = isset($vm[2]) && $vm[2] ? $vm[2] : null; + $var->modifier = isset($vm[3]) && $vm[3] ? $vm[3] : $var->modifier; + $var->default = isset($vm[4]) ? substr($vm[4], 1) : null; + $exp->vars[] = $var; + } + + // Add processing flags + $exp->reserved = false; + $exp->prefix = ''; + $exp->delimiter = ','; + switch ($exp->operator) { + case '+': + $exp->reserved = 'true'; + break; + case ';': + $exp->prefix = ';'; + $exp->delimiter = ';'; + break; + case '?': + $exp->prefix = '?'; + $exp->delimiter = '&'; + break; + case '/': + $exp->prefix = '/'; + $exp->delimiter = '/'; + break; + case '.': + $exp->prefix = '.'; + $exp->delimiter = '.'; + break; + } + $expressions[] = $exp; + } + + // Expansion + $this->expansion = $this->template; + + foreach ($expressions as $exp) { + $part = $exp->prefix; + $exp->one_var_defined = false; + foreach ($exp->vars as $var) { + $val = ''; + if ($exp->one_var_defined && isset($data[$var->name])) { + $part .= $exp->delimiter; + } + // Variable present + if (isset($data[$var->name])) { + $exp->one_var_defined = true; + $var->data = $data[$var->name]; + + $val = self::val_from_var($var, $exp); + + // Variable missing + } else { + if ($var->default) { + $exp->one_var_defined = true; + $val = $var->default; + } + } + $part .= $val; + } + if (! $exp->one_var_defined) $part = ''; + $this->expansion = str_replace($exp->expression, $part, $this->expansion); + } + + return $this->expansion; + } + + private function val_from_var($var, $exp) { + $val = ''; + if (is_array($var->data)) { + $i = 0; + if ($exp->operator == '?' && ! $var->modifier) { + $val .= $var->name . '='; + } + foreach ($var->data as $k => $v) { + $del = $var->modifier ? $exp->delimiter : ','; + $ek = rawurlencode($k); + $ev = rawurlencode($v); + + // Array + if ($k !== $i) { + if ($var->modifier == '+') { + $val .= $var->name . '.'; + } + if ($exp->operator == '?' && $var->modifier || $exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+') { + $val .= $ek . '='; + } else { + $val .= $ek . $del; + } + + // List + } else { + if ($var->modifier == '+') { + if ($exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+' || $exp->operator == '?' && $var->modifier == '+') { + $val .= $var->name . '='; + } else { + $val .= $var->name . '.'; + } + } + } + $val .= $ev . $del; + $i ++; + } + $val = trim($val, $del); + + // Strings, numbers, etc. + } else { + if ($exp->operator == '?') { + $val = $var->name . (isset($var->data) ? '=' : ''); + } else if ($exp->operator == ';') { + $val = $var->name . ($var->data ? '=' : ''); + } + $val .= rawurlencode($var->data); + if ($exp->operator == '+') { + $val = str_replace(self::$reserved_pct, self::$reserved, $val); + } + } + return $val; + } + + public function match($uri) {} + + public function __toString() { + return $this->template; + } +} diff --git a/inc/vendors/social-login/Google/index.html b/inc/vendors/social-login/Google/index.html new file mode 100755 index 00000000..e69de29b diff --git a/inc/vendors/social-login/Google/io/apiCacheParser.php b/inc/vendors/social-login/Google/io/apiCacheParser.php new file mode 100755 index 00000000..1800508b --- /dev/null +++ b/inc/vendors/social-login/Google/io/apiCacheParser.php @@ -0,0 +1,167 @@ + + */ +class apiCacheParser { + public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD'); + public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301'); + + private function __construct() {} + + /** + * Check if an HTTP request can be cached by a private local cache. + * @static + * @param apiHttpRequest $resp + * @return bool True if the request is cacheable. + * False if the request is uncacheable. + */ + public static function isRequestCacheable (apiHttpRequest $resp) { + $method = $resp->getRequestMethod(); + if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) { + return false; + } + + // Don't cache authorized requests/responses. + // [rfc2616-14.8] When a shared cache receives a request containing an + // Authorization field, it MUST NOT return the corresponding response + // as a reply to any other request... + if ($resp->getRequestHeader("authorization")) { + return false; + } + + return true; + } + + /** + * Check if an HTTP response can be cached by a private local cache. + * @static + * @param apiHttpRequest $resp + * @return bool True if the response is cacheable. + * False if the response is un-cacheable. + */ + public static function isResponseCacheable (apiHttpRequest $resp) { + // First, check if the HTTP request was cacheable before inspecting the + // HTTP response. + if (false == self::isRequestCacheable($resp)) { + return false; + } + + $code = $resp->getResponseHttpCode(); + if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) { + return false; + } + + // The resource is uncacheable if the resource is already expired and + // the resource doesn't have an ETag for revalidation. + $etag = $resp->getResponseHeader("etag"); + if (self::isExpired($resp) && $etag == false) { + return false; + } + + // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT + // store any part of either this response or the request that elicited it. + $cacheControl = $resp->getParsedCacheControl(); + if (isset($cacheControl['no-store'])) { + return false; + } + + // Pragma: no-cache is an http request directive, but is occasionally + // used as a response header incorrectly. + $pragma = $resp->getResponseHeader('pragma'); + if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) { + return false; + } + + // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that + // a cache cannot determine from the request headers of a subsequent request + // whether this response is the appropriate representation." + // Given this, we deem responses with the Vary header as uncacheable. + $vary = $resp->getResponseHeader('vary'); + if ($vary) { + return false; + } + + return true; + } + + /** + * @static + * @param apiHttpRequest $resp + * @return bool True if the HTTP response is considered to be expired. + * False if it is considered to be fresh. + */ + public static function isExpired(apiHttpRequest $resp) { + // HTTP/1.1 clients and caches MUST treat other invalid date formats, + // especially including the value “0”, as in the past. + $parsedExpires = false; + $responseHeaders = $resp->getResponseHeaders(); + if (isset($responseHeaders['expires'])) { + $rawExpires = $responseHeaders['expires']; + // Check for a malformed expires header first. + if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) { + return true; + } + + // See if we can parse the expires header. + $parsedExpires = strtotime($rawExpires); + if (false == $parsedExpires || $parsedExpires <= 0) { + return true; + } + } + + // Calculate the freshness of an http response. + $freshnessLifetime = false; + $cacheControl = $resp->getParsedCacheControl(); + if (isset($cacheControl['max-age'])) { + $freshnessLifetime = $cacheControl['max-age']; + } + + $rawDate = $resp->getResponseHeader('date'); + $parsedDate = strtotime($rawDate); + + if (empty($rawDate) || false == $parsedDate) { + $parsedDate = time(); + } + if (false == $freshnessLifetime && isset($responseHeaders['expires'])) { + $freshnessLifetime = $parsedExpires - $parsedDate; + } + + if (false == $freshnessLifetime) { + return true; + } + + // Calculate the age of an http response. + $age = max(0, time() - $parsedDate); + if (isset($responseHeaders['age'])) { + $age = max($age, strtotime($responseHeaders['age'])); + } + + return $freshnessLifetime <= $age; + } + + /** + * Determine if a cache entry should be revalidated with by the origin. + * @param apiHttpRequest $response + * @return bool True if the entry is expired, else return false. + */ + public static function mustRevalidate(apiHttpRequest $response) { + // [13.3] When a cache has a stale entry that it would like to use as a + // response to a client's request, it first has to check with the origin + // server to see if its cached entry is still usable. + return self::isExpired($response); + } +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/io/apiCurlIO.php b/inc/vendors/social-login/Google/io/apiCurlIO.php new file mode 100755 index 00000000..1befc3e4 --- /dev/null +++ b/inc/vendors/social-login/Google/io/apiCurlIO.php @@ -0,0 +1,248 @@ + + * @author Chirag Shah + */ + +require_once 'apiCacheParser.php'; + +class apiCurlIO implements apiIO { + const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n"; + const FORM_URLENCODED = 'application/x-www-form-urlencoded'; + + private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null); + private static $HOP_BY_HOP = array( + 'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', + 'te', 'trailers', 'transfer-encoding', 'upgrade'); + + private static $DEFAULT_CURL_PARAMS = array ( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => 0, + CURLOPT_FAILONERROR => false, + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_HEADER => true, + ); + + /** + * Perform an authenticated / signed apiHttpRequest. + * This function takes the apiHttpRequest, calls apiAuth->sign on it + * (which can modify the request in what ever way fits the auth mechanism) + * and then calls apiCurlIO::makeRequest on the signed request + * @param apiHttpRequest $request + * @return apiHttpRequest The resulting HTTP response including the + * responseHttpCode, responseHeaders and responseBody. + */ + public function authenticatedRequest(apiHttpRequest $request) { + $request = apiClient::$auth->sign($request); + return $this->makeRequest($request); + } + + /** + * Execute a apiHttpRequest + * @param apiHttpRequest $request the http request to be executed + * @return apiHttpRequest http request with the response http code, response + * headers and response body filled in + * @throws apiIOException on curl or IO error + */ + public function makeRequest(apiHttpRequest $request) { + // First, check to see if we have a valid cached version. + $cached = $this->getCachedRequest($request); + if ($cached !== false) { + if (apiCacheParser::mustRevalidate($cached)) { + $addHeaders = array(); + if ($cached->getResponseHeader('etag')) { + // [13.3.4] If an entity tag has been provided by the origin server, + // we must use that entity tag in any cache-conditional request. + $addHeaders['If-None-Match'] = $cached->getResponseHeader('etag'); + } elseif ($cached->getResponseHeader('date')) { + $addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date'); + } + + $request->setRequestHeaders($addHeaders); + } else { + // No need to revalidate the request, return it directly + return $cached; + } + } + + if (array_key_exists($request->getRequestMethod(), + self::$ENTITY_HTTP_METHODS)) { + $request = $this->processEntityRequest($request); + } + + $ch = curl_init(); + curl_setopt_array($ch, self::$DEFAULT_CURL_PARAMS); + curl_setopt($ch, CURLOPT_URL, $request->getUrl()); + if ($request->getPostBody()) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPostBody()); + } + + $requestHeaders = $request->getRequestHeaders(); + if ($requestHeaders && is_array($requestHeaders)) { + $parsed = array(); + foreach ($requestHeaders as $k => $v) { + $parsed[] = "$k: $v"; + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $parsed); + } + + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod()); + curl_setopt($ch, CURLOPT_USERAGENT, $request->getUserAgent()); + $respData = curl_exec($ch); + + // Retry if certificates are missing. + if (curl_errno($ch) == CURLE_SSL_CACERT) { + error_log('SSL certificate problem, verify that the CA cert is OK.' + . ' Retrying with the CA cert bundle from google-api-php-client.'); + curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem'); + $respData = curl_exec($ch); + } + + $respHeaderSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $respHttpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); + $curlErrorNum = curl_errno($ch); + $curlError = curl_error($ch); + curl_close($ch); + if ($curlErrorNum != CURLE_OK) { + throw new apiIOException("HTTP Error: ($respHttpCode) $curlError"); + } + + // Parse out the raw response into usable bits + list($responseHeaders, $responseBody) = + $this->parseHttpResponseBody($respData, $respHeaderSize); + + if ($respHttpCode == 304 && $cached) { + // If the server responded NOT_MODIFIED, return the cached request. + if (isset($responseHeaders['connection'])) { + $hopByHop = array_merge( + self::$HOP_BY_HOP, + explode(',', $responseHeaders['connection']) + ); + + $endToEnd = array(); + foreach($hopByHop as $key) { + if (isset($responseHeaders[$key])) { + $endToEnd[$key] = $responseHeaders[$key]; + } + } + $cached->setResponseHeaders($endToEnd); + } + return $cached; + } + + // Fill in the apiHttpRequest with the response values + $request->setResponseHttpCode($respHttpCode); + $request->setResponseHeaders($responseHeaders); + $request->setResponseBody($responseBody); + // Store the request in cache (the function checks to see if the request + // can actually be cached) + $this->setCachedRequest($request); + // And finally return it + return $request; + } + + /** + * @visible for testing. + * Cache the response to an HTTP request if it is cacheable. + * @param apiHttpRequest $request + * @return bool Returns true if the insertion was successful. + * Otherwise, return false. + */ + public function setCachedRequest(apiHttpRequest $request) { + // Determine if the request is cacheable. + if (apiCacheParser::isResponseCacheable($request)) { + apiClient::$cache->set($request->getCacheKey(), $request); + return true; + } + + return false; + } + + /** + * @visible for testing. + * @param apiHttpRequest $request + * @return apiHttpRequest|bool Returns the cached object or + * false if the operation was unsuccessful. + */ + public function getCachedRequest(apiHttpRequest $request) { + if (false == apiCacheParser::isRequestCacheable($request)) { + false; + } + + return apiClient::$cache->get($request->getCacheKey()); + } + + /** + * @param $respData + * @param $headerSize + * @return array + */ + public function parseHttpResponseBody($respData, $headerSize) { + if (stripos($respData, self::CONNECTION_ESTABLISHED) !== false) { + $respData = str_ireplace(self::CONNECTION_ESTABLISHED, '', $respData); + } + + $responseBody = substr($respData, $headerSize); + $responseHeaderLines = explode("\r\n", substr($respData, 0, $headerSize)); + $responseHeaders = array(); + + foreach ($responseHeaderLines as $headerLine) { + if ($headerLine && strpos($headerLine, ':') !== false) { + list($header, $value) = explode(': ', $headerLine, 2); + $header = strtolower($header); + if (isset($responseHeaders[$header])) { + $responseHeaders[$header] .= "\n" . $value; + } else { + $responseHeaders[$header] = $value; + } + } + } + + return array($responseHeaders, $responseBody); + } + + /** + * @visible for testing + * Process an http request that contains an enclosed entity. + * @param apiHttpRequest $request + * @return apiHttpRequest Processed request with the enclosed entity. + */ + public function processEntityRequest(apiHttpRequest $request) { + $postBody = $request->getPostBody(); + $contentType = $request->getRequestHeader("content-type"); + + // Set the default content-type as application/x-www-form-urlencoded. + if (false == $contentType) { + $contentType = self::FORM_URLENCODED; + $request->setRequestHeaders(array('content-type' => $contentType)); + } + + // Force the payload to match the content-type asserted in the header. + if ($contentType == self::FORM_URLENCODED && is_array($postBody)) { + $postBody = http_build_query($postBody, '', '&'); + $request->setPostBody($postBody); + } + + // Make sure the content-length header is set. + if (!$postBody || is_string($postBody)) { + $postsLength = strlen($postBody); + $request->setRequestHeaders(array('content-length' => $postsLength)); + } + + return $request; + } +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/io/apiHttpRequest.php b/inc/vendors/social-login/Google/io/apiHttpRequest.php new file mode 100755 index 00000000..c65086a8 --- /dev/null +++ b/inc/vendors/social-login/Google/io/apiHttpRequest.php @@ -0,0 +1,256 @@ + + * @author Chirag Shah + */ +class apiHttpRequest { + const USER_AGENT_SUFFIX = "google-api-php-client/0.5.0"; + + protected $url; + protected $requestMethod; + protected $requestHeaders; + protected $postBody; + protected $userAgent; + + protected $responseHttpCode; + protected $responseHeaders; + protected $responseBody; + + public $accessKey; + + public function __construct($url, $method = 'GET', $headers = array(), $postBody = null) { + $this->url = $url; + $this->setRequestMethod($method); + $this->setRequestHeaders($headers); + $this->setPostBody($postBody); + + global $apiConfig; + if (empty($apiConfig['application_name'])) { + $this->userAgent = self::USER_AGENT_SUFFIX; + } else { + $this->userAgent = $apiConfig['application_name'] . " " . self::USER_AGENT_SUFFIX; + } + } + + /** + * Misc function that returns the base url component of the $url + * used by the OAuth signing class to calculate the base string + * @return string The base url component of the $url. + * @see http://oauth.net/core/1.0a/#anchor13 + */ + public function getBaseUrl() { + if ($pos = strpos($this->url, '?')) { + return substr($this->url, 0, $pos); + } + return $this->url; + } + + /** + * Misc function that returns an array of the query parameters of the current + * url used by the OAuth signing class to calculate the signature + * @return array Query parameters in the query string. + */ + public function getQueryParams() { + if ($pos = strpos($this->url, '?')) { + $queryStr = substr($this->url, $pos + 1); + $params = array(); + parse_str($queryStr, $params); + return $params; + } + return array(); + } + + /** + * @return string HTTP Response Code. + */ + public function getResponseHttpCode() { + return (int) $this->responseHttpCode; + } + + /** + * @param int $responseHttpCode HTTP Response Code. + */ + public function setResponseHttpCode($responseHttpCode) { + $this->responseHttpCode = $responseHttpCode; + } + + /** + * @return $responseHeaders (array) HTTP Response Headers. + */ + public function getResponseHeaders() { + return $this->responseHeaders; + } + + /** + * @return string HTTP Response Body + */ + public function getResponseBody() { + return $this->responseBody; + } + + /** + * @param array $headers The HTTP response headers + * to be normalized. + */ + public function setResponseHeaders($headers) { + $headers = apiUtils::normalize($headers); + if ($this->responseHeaders) { + $headers = array_merge($this->responseHeaders, $headers); + } + + $this->responseHeaders = $headers; + } + + /** + * @param string $key + * @return array|boolean Returns the requested HTTP header or + * false if unavailable. + */ + public function getResponseHeader($key) { + return isset($this->responseHeaders[$key]) + ? $this->responseHeaders[$key] + : false; + } + + /** + * @param string $responseBody The HTTP response body. + */ + public function setResponseBody($responseBody) { + $this->responseBody = $responseBody; + } + + /** + * @return string $url The request URL. + */ + + public function getUrl() { + return $this->url; + } + + /** + * @return string $method HTTP Request Method. + */ + public function getRequestMethod() { + return $this->requestMethod; + } + + /** + * @return array $headers HTTP Request Headers. + */ + public function getRequestHeaders() { + return $this->requestHeaders; + } + + /** + * @param string $key + * @return array|boolean Returns the requested HTTP header or + * false if unavailable. + */ + public function getRequestHeader($key) { + return isset($this->requestHeaders[$key]) + ? $this->requestHeaders[$key] + : false; + } + + /** + * @return string $postBody HTTP Request Body. + */ + public function getPostBody() { + return $this->postBody; + } + + /** + * @param string $url the url to set + */ + public function setUrl($url) { + $this->url = $url; + } + + /** + * @param string $method Set he HTTP Method and normalize + * it to upper-case, as required by HTTP. + */ + public function setRequestMethod($method) { + $this->requestMethod = strtoupper($method); + } + + /** + * @param array $headers The HTTP request headers + * to be set and normalized. + */ + public function setRequestHeaders($headers) { + $headers = apiUtils::normalize($headers); + if ($this->requestHeaders) { + $headers = array_merge($this->requestHeaders, $headers); + } + $this->requestHeaders = $headers; + } + + /** + * @param string $postBody the postBody to set + */ + public function setPostBody($postBody) { + $this->postBody = $postBody; + } + + /** + * Set the User-Agent Header. + * @param string $userAgent The User-Agent. + */ + public function setUserAgent($userAgent) { + $this->userAgent = $userAgent; + } + + /** + * @return string The User-Agent. + */ + public function getUserAgent() { + return $this->userAgent; + } + + /** + * Returns a cache key depending on if this was an OAuth signed request + * in which case it will use the non-signed url and access key to make this + * cache key unique per authenticated user, else use the plain request url + * @return The md5 hash of the request cache key. + */ + public function getCacheKey() { + $key = $this->getUrl(); + + if (isset($this->accessKey)) { + $key .= $this->accessKey; + } + + if (isset($this->requestHeaders['authorization'])) { + $key .= $this->requestHeaders['authorization']; + } + + return md5($key); + } + + public function getParsedCacheControl() { + $parsed = array(); + $rawCacheControl = $this->getResponseHeader('cache-control'); + if ($rawCacheControl) { + $rawCacheControl = str_replace(", ", "&", $rawCacheControl); + parse_str($rawCacheControl, $parsed); + } + + return $parsed; + } +} diff --git a/inc/vendors/social-login/Google/io/apiIO.php b/inc/vendors/social-login/Google/io/apiIO.php new file mode 100755 index 00000000..769f0b83 --- /dev/null +++ b/inc/vendors/social-login/Google/io/apiIO.php @@ -0,0 +1,39 @@ + + */ +interface apiIO { + /** + * An utility function that first calls $this->auth->sign($request) and then executes makeRequest() + * on that signed request. Used for when a request should be authenticated + * @param apiHttpRequest $request + * @return apiHttpRequest $request + */ + public function authenticatedRequest(apiHttpRequest $request); + + /** + * Executes a apIHttpRequest and returns the resulting populated httpRequest + * @param apiHttpRequest $request + * @return apiHttpRequest $request + */ + public function makeRequest(apiHttpRequest $request); +} diff --git a/inc/vendors/social-login/Google/io/apiREST.php b/inc/vendors/social-login/Google/io/apiREST.php new file mode 100755 index 00000000..f18dce40 --- /dev/null +++ b/inc/vendors/social-login/Google/io/apiREST.php @@ -0,0 +1,143 @@ + + * @author Chirag Shah + */ +class apiREST { + /** + * Executes a apiServiceRequest using a RESTful call by transforming it into + * an apiHttpRequest, and executed via apiIO::authenticatedRequest(). + * @param apiServiceRequest $req + * @return array decoded result + * @throws apiServiceException on server side error (ie: not authenticated, invalid or + * malformed post body, invalid url) + */ + static public function execute(apiServiceRequest $req) { + $result = null; + $postBody = $req->getPostBody(); + $url = self::createRequestUri( + $req->getRestBasePath(), $req->getRestPath(), $req->getParameters()); + + $httpRequest = new apiHttpRequest($url, $req->getHttpMethod(), null, $postBody); + if ($postBody) { + $contentTypeHeader = array(); + if (isset($req->contentType) && $req->contentType) { + $contentTypeHeader['content-type'] = $req->contentType; + } else { + $contentTypeHeader['content-type'] = 'application/json; charset=UTF-8'; + $contentTypeHeader['content-length'] = apiUtils::getStrLen($postBody); + } + $httpRequest->setRequestHeaders($contentTypeHeader); + } + + $httpRequest = apiClient::$io->authenticatedRequest($httpRequest); + $decodedResponse = self::decodeHttpResponse($httpRequest); + + //FIXME currently everything is wrapped in a data envelope, but hopefully this might change some day + $ret = isset($decodedResponse['data']) ? $decodedResponse['data'] : $decodedResponse; + return $ret; + } + + + /** + * Decode an HTTP Response. + * @static + * @throws apiServiceException + * @param apiHttpRequest $response The http response to be decoded. + * @return mixed|null + */ + static function decodeHttpResponse($response) { + $code = $response->getResponseHttpCode(); + $body = $response->getResponseBody(); + $decoded = null; + + if ($code != '200' && $code != '201' && $code != '204') { + $decoded = json_decode($body, true); + $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl(); + if ($decoded != null && isset($decoded['error']['message']) && isset($decoded['error']['code'])) { + // if we're getting a json encoded error definition, use that instead of the raw response + // body for improved readability + $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}"; + } else { + $err .= ": ($code) $body"; + } + throw new apiServiceException($err, $code); + } + + // Only attempt to decode the response, if the response code wasn't (204) 'no content' + if ($code != '204') { + $decoded = json_decode($body, true); + if ($decoded == null) { + throw new apiServiceException("Invalid json in service response: $body"); + } + } + return $decoded; + } + + /** + * Parse/expand request parameters and create a fully qualified + * request uri. + * @static + * @param string $basePath + * @param string $restPath + * @param array $params + * @return string $requestUrl + */ + static function createRequestUri($basePath, $restPath, $params) { + $requestUrl = $basePath . $restPath; + $uriTemplateVars = array(); + $queryVars = array(); + foreach ($params as $paramName => $paramSpec) { + // Discovery v1.0 puts the canonical location under the 'location' field. + if (! isset($paramSpec['location'])) { + $paramSpec['location'] = $paramSpec['restParameterType']; + } + + if ($paramSpec['type'] == 'boolean') { + $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false'; + } + if ($paramSpec['location'] == 'path') { + $uriTemplateVars[$paramName] = $paramSpec['value']; + } else { + if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) { + foreach ($paramSpec['value'] as $value) { + $queryVars[] = $paramName . '=' . rawurlencode($value); + } + } else { + $queryVars[] = $paramName . '=' . rawurlencode($paramSpec['value']); + } + } + } + + if (count($uriTemplateVars)) { + $uriTemplateParser = new URI_Template_Parser($requestUrl); + $requestUrl = $uriTemplateParser->expand($uriTemplateVars); + } + //FIXME work around for the the uri template lib which url encodes + // the @'s & confuses our servers. + $requestUrl = str_replace('%40', '@', $requestUrl); + + if (count($queryVars)) { + $requestUrl .= '?' . implode($queryVars, '&'); + } + + return $requestUrl; + } +} diff --git a/inc/vendors/social-login/Google/io/apiRPC.php b/inc/vendors/social-login/Google/io/apiRPC.php new file mode 100755 index 00000000..90f8e36a --- /dev/null +++ b/inc/vendors/social-login/Google/io/apiRPC.php @@ -0,0 +1,59 @@ + + */ +class apiRPC { + static public function execute($requests) { + $jsonRpcRequest = array(); + foreach ($requests as $request) { + $parameters = array(); + foreach ($request->getParameters() as $parameterName => $parameterVal) { + $parameters[$parameterName] = $parameterVal['value']; + } + $jsonRpcRequest[] = array( + 'id' => $request->getBatchKey(), + 'method' => $request->getRpcName(), + 'params' => $parameters, + 'apiVersion' => 'v1' + ); + } + $httpRequest = new apiHttpRequest($request->getRpcPath()); + $httpRequest->setRequestHeaders(array('Content-Type' => 'application/json')); + $httpRequest->setRequestMethod('POST'); + $httpRequest->setPostBody(json_encode($jsonRpcRequest)); + $httpRequest = apiClient::$io->authenticatedRequest($httpRequest); + if (($decodedResponse = json_decode($httpRequest->getResponseBody(), true)) != false) { + $ret = array(); + foreach ($decodedResponse as $response) { + $ret[$response['id']] = self::checkNextLink($response['result']); + } + return $ret; + } else { + throw new apiServiceException("Invalid json returned by the json-rpc end-point"); + } + } + + static private function checkNextLink($response) { + if (isset($response['links']) && isset($response['links']['next'][0]['href'])) { + parse_str($response['links']['next'][0]['href'], $params); + if (isset($params['c'])) { + $response['continuationToken'] = $params['c']; + } + } + return $response; + } +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/io/cacerts.pem b/inc/vendors/social-login/Google/io/cacerts.pem new file mode 100755 index 00000000..da36ed1b --- /dev/null +++ b/inc/vendors/social-login/Google/io/cacerts.pem @@ -0,0 +1,714 @@ +# Certifcate Authority certificates for validating SSL connections. +# +# This file contains PEM format certificates generated from +# http://mxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public 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://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the Netscape security libraries. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1994-2000 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +Verisign/RSA Secure Server CA +============================= + +-----BEGIN CERTIFICATE----- +MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD +VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0 +MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV +BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy +dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ +ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII +0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI +uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI +hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3 +YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc +1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA== +-----END CERTIFICATE----- + +Thawte Personal Basic CA +======================== + +-----BEGIN CERTIFICATE----- +MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD +VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT +ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj +IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X +DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw +EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE +ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy +dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD +QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53 +dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK +wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7 +G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF +AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7 +c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P +9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ== +-----END CERTIFICATE----- + +Thawte Personal Premium CA +========================== + +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD +VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT +ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p +dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv +bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa +QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY +BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u +IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl +bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu +Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs +Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI +Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD +ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH +b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh +KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ +-----END CERTIFICATE----- + +Thawte Personal Freemail CA +=========================== + +-----BEGIN CERTIFICATE----- +MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD +VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT +ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt +YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu +Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT +AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa +MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG +cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh +d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY +DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E +rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq +uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN +BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP +MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa +/RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei +gQ== +-----END CERTIFICATE----- + +Thawte Server CA +================ + +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm +MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx +MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 +dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl +cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 +DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 +yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX +L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj +EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG +7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e +QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ +qdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- + +Thawte Premium Server CA +======================== + +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy +dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t +MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB +MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG +A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl +cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv +bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE +VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ +ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR +uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI +hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM +pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- + +Equifax Secure CA +================= + +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 +MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx +dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f +BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A +cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw +ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj +IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y +7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh +1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority +======================================================= + +-----BEGIN CERTIFICATE----- +MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh +c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05 +NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD +VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp +bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB +jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N +H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR +4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN +BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo +EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5 +FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx +lA== +-----END CERTIFICATE----- + +Verisign Class 2 Public Primary Certification Authority +======================================================= + +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh +YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7 +FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G +CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg +J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc +r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority +======================================================= + +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE +BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is +I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G +CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do +lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc +AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority - G2 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK +VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm +Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J +h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul +uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68 +DzFc6PLZ +-----END CERTIFICATE----- + +Verisign Class 2 Public Primary Certification Authority - G2 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns +YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y +aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe +Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj +IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx +KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM +HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw +DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC +AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji +nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX +rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn +jBJ7xUS0rg== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G2 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 +pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 +13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk +U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i +F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY +oJ2daZH9 +-----END CERTIFICATE----- + +Verisign Class 4 Public Primary Certification Authority - G2 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM +HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK +qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj +cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y +cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP +T8qAkbYp +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority - G3 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 +nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO +8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV +ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb +PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 +6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr +n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a +qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 +wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 +ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs +pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 +E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== +-----END CERTIFICATE----- + +Verisign Class 2 Public Primary Certification Authority - G3 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy +aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp +Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV +BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp +Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g +Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU +J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO +JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY +wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o +koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN +qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E +Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe +xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u +7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU +sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI +sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP +cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Verisign Class 4 Public Primary Certification Authority - G3 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 +GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ ++mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd +U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm +NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY +ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ +ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 +CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq +g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c +2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ +bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- + +Equifax Secure Global eBusiness CA +================================== + +-----BEGIN CERTIFICATE----- +MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT +ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw +MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj +dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l +c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC +UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc +58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ +o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr +aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA +A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA +Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv +8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV +-----END CERTIFICATE----- + +Equifax Secure eBusiness CA 1 +============================= + +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT +ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw +MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j +LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo +RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu +WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw +Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK +eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM +zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ +WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN +/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- + +Equifax Secure eBusiness CA 2 +============================= + +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj +dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0 +NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD +VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G +vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/ +BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX +MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl +IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw +NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq +y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy +0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1 +E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN +-----END CERTIFICATE----- + +Thawte Time Stamping CA +======================= + +-----BEGIN CERTIFICATE----- +MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN +BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd +BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN +MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g +Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG +A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l +c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT +6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa +Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL +8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC +9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ +pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ +CayJSdM= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== + +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ + +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +Entrust.net Secure Server Certification Authority +================================================= + +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 +MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE +ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j +b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg +U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ +I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 +wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC +AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb +oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 +BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p +dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk +MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp +b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 +MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi +E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa +MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI +hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN +95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd +2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- + +Go Daddy Certification Authority Root Certificate Bundle +======================================================== + +-----BEGIN CERTIFICATE----- +MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx +ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw +MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH +QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j +b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j +b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H +KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm +VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR +SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT +cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ +6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu +MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS +kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB +BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f +BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv +c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH +AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO +BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG +OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU +A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o +0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX +RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH +qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV +U+4= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh +bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu +Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g +QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe +BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX +DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE +YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC +ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q +N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO +r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN +f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH +U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU +TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb +VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg +SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv +biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg +MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw +AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv +ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu +Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd +IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv +bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1 +QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O +WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf +SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy +NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY +dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 +WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS +v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v +UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu +IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC +W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd +-----END CERTIFICATE----- + diff --git a/inc/vendors/social-login/Google/service/apiBatch.php b/inc/vendors/social-login/Google/service/apiBatch.php new file mode 100755 index 00000000..216a86e9 --- /dev/null +++ b/inc/vendors/social-login/Google/service/apiBatch.php @@ -0,0 +1,35 @@ + + */ +class apiBatch { + + /** + * Execute one or multiple Google API requests, takes one or multiple requests as param + * Example usage: + * $ret = apiBatch::execute( + * $apiClient->activities->list(array('@public', '@me'), 'listActivitiesKey'), + * $apiClient->people->get(array('userId' => '@me'), 'getPeopleKey') + * ); + * print_r($ret['getPeopleKey']); + */ + static public function execute( /* polymorphic */) { + $requests = func_get_args(); + return apiRPC::execute($requests); + } + +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/service/apiMediaFileUpload.php b/inc/vendors/social-login/Google/service/apiMediaFileUpload.php new file mode 100755 index 00000000..2a53e94e --- /dev/null +++ b/inc/vendors/social-login/Google/service/apiMediaFileUpload.php @@ -0,0 +1,85 @@ + + */ +class apiMediaFileUpload { + public $mimeType; + public $fileName; + public $chunkSize; + + public static function process($metadata, $method, &$params) { + $payload = array(); + + $data = isset($params['data']) ? $params['data']['value'] : false; + $mimeType = isset($params['mimeType']) ? $params['mimeType']['value'] : false; + $file = isset($params['file']) ? $params['file']['value'] : false; + $uploadPath = $method['mediaUpload']['protocols']['simple']['path']; + + unset($params['data']); + unset($params['mimeType']); + unset($params['file']); + + if ($file) { + if (substr($file, 0, 1) != '@') { + $file = '@' . $file; + } + $payload['file'] = $file; + $payload['content-type'] = 'multipart/form-data'; + $payload['restBasePath'] = $uploadPath; + + // This is a standard file upload with curl. + return $payload; + } + + $parsedMeta = is_string($metadata) ? json_decode($metadata, true) : $metadata; + if ($metadata && false == $data) { + // Process as a normal API request. + return false; + } + + // Process as a media upload request. + $params['uploadType'] = array( + 'type' => 'string', + 'location' => 'query', + 'value' => 'media', + ); + + // Determine which type. + $payload['restBasePath'] = $uploadPath; + if (false == $metadata || false == $parsedMeta) { + // This is a simple media upload. + $payload['content-type'] = $mimeType; + $payload['data'] = $data; + } else { + // This is a multipart/related upload. + $boundary = isset($params['boundary']) ? $params['boundary'] : mt_rand(); + $boundary = str_replace('"', '', $boundary); + $payload['content-type'] = 'multipart/related; boundary=' . $boundary; + + $related = "--$boundary\r\n"; + $related .= "Content-Type: application/json; charset=UTF-8\r\n"; + $related .= "\r\n" . $metadata . "\r\n"; + $related .= "--$boundary\r\n"; + $related .= "Content-Type: $mimeType\r\n"; + $related .= "Content-Transfer-Encoding: base64\r\n"; + $related .= "\r\n" . base64_encode($data) . "\r\n"; + $related .= "--$boundary--"; + $payload['data'] = $related; + } + + return $payload; + } +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/service/apiModel.php b/inc/vendors/social-login/Google/service/apiModel.php new file mode 100755 index 00000000..f8964a36 --- /dev/null +++ b/inc/vendors/social-login/Google/service/apiModel.php @@ -0,0 +1,109 @@ + + */ +class apiModel { + public function __construct( /* polymorphic */ ) { + if (func_num_args() == 1 && is_array(func_get_arg(0))) { + // Initialize the model with the array's contents. + $array = func_get_arg(0); + $this->mapTypes($array); + } + } + + /** + * Initialize this object's properties from an array. + * + * @param array Used to seed this object's properties. + * @return void + */ + private function mapTypes($array) { + foreach ($array as $key => $val) { + $this->$key = $val; + + $keyTypeName = "__$key" . 'Type'; + $keyDataType = "__$key" . 'DataType'; + if ($this->useObjects() && property_exists($this, $keyTypeName)) { + if ($this->isAssociativeArray($val)) { + if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) { + foreach($val as $arrayKey => $arrayItem) { + $val[$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem); + } + $this->$key = $val; + } else { + $this->$key = $this->createObjectFromName($keyTypeName, $val); + } + } else if (is_array($val)) { + $arrayObject = array(); + foreach ($val as $arrayIndex => $arrayItem) { + $arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem); + } + $this->$key = $arrayObject; + } + } + } + } + + /** + * Returns true only if the array is associative. + * @param array $array + * @return bool True if the array is associative. + */ + private function isAssociativeArray($array) { + if (!is_array($array)) { + return false; + } + $keys = array_keys($array); + foreach($keys as $key) { + if (is_string($key)) { + return true; + } + } + return false; + } + + /** + * Given a variable name, discover its type. + * @param $name + * @param $item + * @return object The object from the item. + */ + private function createObjectFromName($name, $item) { + $type = $this->$name; + return new $type($item); + } + + protected function useObjects() { + global $apiConfig; + return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']); + } + + /** + * Verify if $obj is an array. + * @throws apiException Thrown if $obj isn't an array. + * @param array $obj Items that should be validated. + * @param string $type Array items should be of this type. + * @param string $method Method expecting an array as an argument. + */ + protected function assertIsArray($obj, $type, $method) { + if ($obj && !is_array($obj)) { + throw new apiException("Incorrect parameter type passed to $method(), expected an" + . " array containing items of type $type."); + } + } +} \ No newline at end of file diff --git a/inc/vendors/social-login/Google/service/apiService.php b/inc/vendors/social-login/Google/service/apiService.php new file mode 100755 index 00000000..10609fb5 --- /dev/null +++ b/inc/vendors/social-login/Google/service/apiService.php @@ -0,0 +1,58 @@ +activities, $this->comments, $this->people, etc. + * @author Chris Chabot + */ +class apiService { + public $version = null; + public $restBasePath; + public $rpcPath; + public $resource = null; + + public function __construct($serviceName, $discoveryDocument) { + global $apiConfig; + if (!isset($discoveryDocument['version']) || !isset($discoveryDocument['restBasePath']) || !isset($discoveryDocument['rpcPath'])) { + throw new apiServiceException("Invalid discovery document"); + } + $this->version = $discoveryDocument['version']; + $this->restBasePath = $apiConfig['basePath'] . $discoveryDocument['restBasePath']; + $this->rpcPath = $apiConfig['basePath'] . $discoveryDocument['rpcPath']; + foreach ($discoveryDocument['resources'] as $resourceName => $resourceTypes) { + $this->$resourceName = new apiServiceResource($this, $serviceName, $resourceName, $resourceTypes); + } + } + + /** + * @return string $restBasePath + */ + public function getRestBasePath() { + return $this->restBasePath; + } + + /** + * @return string $rpcPath + */ + public function getRpcPath() { + return $this->rpcPath; + } +} diff --git a/inc/vendors/social-login/Google/service/apiServiceRequest.php b/inc/vendors/social-login/Google/service/apiServiceRequest.php new file mode 100755 index 00000000..b7d25973 --- /dev/null +++ b/inc/vendors/social-login/Google/service/apiServiceRequest.php @@ -0,0 +1,130 @@ + + * @author Chirag Shah + */ +class apiServiceRequest { + public $restBasePath; + public $restPath; + public $rpcPath; + public $rpcName; + public $httpMethod; + public $parameters; + public $postBody; + public $batchKey; + public $contentType; + + /** + * @param string $restBasePath + * @param string $rpcPath + * @param string $restPath + * @param string $rpcName + * @param string $httpMethod + * @param array $parameters + * @param string $postBody + */ + public function __construct($restBasePath, $rpcPath, $restPath, $rpcName, $httpMethod, $parameters, $postBody = null) { + if (substr($restBasePath, 0, 4) == 'http') { + $this->restBasePath = $restBasePath; + } else { + global $apiConfig; + $this->restBasePath = $apiConfig['basePath'] . $restBasePath; + } + + $this->restPath = $restPath; + $this->rpcPath = $rpcPath; + $this->rpcName = $rpcName; + $this->httpMethod = $httpMethod; + $this->parameters = $parameters; + $this->postBody = $postBody; + } + + /** + * @return string $postBody + */ + public function getPostBody() { + return $this->postBody; + } + + /** + * @param string $postBody The post body. + */ + public function setPostBody($postBody) { + $this->postBody = $postBody; + } + /** + * @return string restBasePath + */ + public function getRestBasePath() { + return $this->restBasePath; + } + /** + * @return string restPath + */ + public function getRestPath() { + return $this->restPath; + } + + /** + * @return string $rpcPath + */ + public function getRpcPath() { + return $this->rpcPath; + } + + /** + * @return string $rpcName + */ + public function getRpcName() { + return $this->rpcName; + } + + /** + * @return string $httpMethod + */ + public function getHttpMethod() { + return $this->httpMethod; + } + + /** + * @return array $parameters + */ + public function getParameters() { + return $this->parameters; + } + + /** + * @return string $batchKey + */ + public function getBatchKey() { + return $this->batchKey; + } + + /** + * @param $batchKey the $batchKey to set + */ + public function setBatchKey($batchKey) { + $this->batchKey = $batchKey; + } + + public function setContentType($type) { + $this->contentType = $type; + } +} diff --git a/inc/vendors/social-login/Google/service/apiServiceResource.php b/inc/vendors/social-login/Google/service/apiServiceResource.php new file mode 100755 index 00000000..5daa5336 --- /dev/null +++ b/inc/vendors/social-login/Google/service/apiServiceResource.php @@ -0,0 +1,202 @@ + + * @author Chirag Shah + */ +class apiServiceResource { + // Valid query parameters that work, but don't appear in discovery. + private $stackParameters = array( + 'alt' => array('type' => 'string', 'location' => 'query'), + 'fields' => array('type' => 'string', 'location' => 'query'), + 'trace' => array('type' => 'string', 'location' => 'query'), + 'userIp' => array('type' => 'string', 'location' => 'query'), + 'userip' => array('type' => 'string', 'location' => 'query'), + 'file' => array('type' => 'complex', 'location' => 'body'), + 'data' => array('type' => 'string', 'location' => 'body'), + 'mimeType' => array('type' => 'string', 'location' => 'header'), + 'uploadType' => array('type' => 'string', 'location' => 'query'), + ); + + /** @var apiService $service */ + private $service; + + /** @var string $serviceName */ + private $serviceName; + + /** @var string $resourceName */ + private $resourceName; + + /** @var array $methods */ + private $methods; + + public function __construct($service, $serviceName, $resourceName, $resource) { + $this->service = $service; + $this->serviceName = $serviceName; + $this->resourceName = $resourceName; + $this->methods = isset($resource['methods']) ? $resource['methods'] : array($resourceName => $resource); + } + + /** + * @param $name + * @param $arguments + * @return apiServiceRequest|array + * @throws apiException + */ + public function __call($name, $arguments) { + if (count($arguments) != 1 && count($arguments) != 2) { + throw new apiException("client method calls expect 1 or 2 parameter (\$client->plus->activities->list(array('userId' => 'me'))"); + } + if (! is_array($arguments[0])) { + throw new apiException("client method parameter should be an array (\$client->plus->activities->list(array('userId' => 'me'))"); + } + $batchKey = false; + if (isset($arguments[1])) { + if (! is_string($arguments[1])) { + throw new apiException("The batch key parameter should be a string (\$client->plus->activities->list( array('userId' => 'me'), 'batchKey'))"); + } + $batchKey = $arguments[1]; + } + if (! isset($this->methods[$name])) { + throw new apiException("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()"); + } + $method = $this->methods[$name]; + $parameters = $arguments[0]; + // postBody is a special case since it's not defined in the discovery document as parameter, but we abuse the param entry for storing it + $postBody = null; + if (isset($parameters['postBody'])) { + if (is_object($parameters['postBody'])) { + $this->stripNull($parameters['postBody']); + } + + // Some APIs require the postBody to be set under the data key. + if (is_array($parameters['postBody']) && 'latitude' == $this->serviceName) { + if (!isset($parameters['postBody']['data'])) { + $rawBody = $parameters['postBody']; + unset($parameters['postBody']); + $parameters['postBody']['data'] = $rawBody; + } + } + + $postBody = is_array($parameters['postBody']) || is_object($parameters['postBody']) + ? json_encode($parameters['postBody']) + : $parameters['postBody']; + unset($parameters['postBody']); + + if (isset($parameters['optParams'])) { + $optParams = $parameters['optParams']; + unset($parameters['optParams']); + $parameters = array_merge($parameters, $optParams); + } + } + + if (!isset($method['parameters'])) { + $method['parameters'] = array(); + } + + $method['parameters'] = array_merge($method['parameters'], $this->stackParameters); + foreach ($parameters as $key => $val) { + if ($key != 'postBody' && ! isset($method['parameters'][$key])) { + throw new apiException("($name) unknown parameter: '$key'"); + } + } + if (isset($method['parameters'])) { + foreach ($method['parameters'] as $paramName => $paramSpec) { + if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) { + throw new apiException("($name) missing required param: '$paramName'"); + } + if (isset($parameters[$paramName])) { + $value = $parameters[$paramName]; + $parameters[$paramName] = $paramSpec; + $parameters[$paramName]['value'] = $value; + unset($parameters[$paramName]['required']); + } else { + unset($parameters[$paramName]); + } + } + } + + // Discovery v1.0 puts the canonical method id under the 'id' field. + if (! isset($method['id'])) { + $method['id'] = $method['rpcMethod']; + } + + // Discovery v1.0 puts the canonical path under the 'path' field. + if (! isset($method['path'])) { + $method['path'] = $method['restPath']; + } + + $restBasePath = $this->service->restBasePath; + + // Process Media Request + $contentType = false; + if (isset($method['mediaUpload'])) { + $media = apiMediaFileUpload::process($postBody, $method, $parameters); + if (isset($media['content-type'])) { + $contentType = $media['content-type']; + } + + if (isset($media['data'])) { + $postBody = $media['data']; + } + + if (isset($media['file'])) { + $postBody = array('file' => $media['file']); + } + + if (isset($media['restBasePath'])) { + $restBasePath = $media['restBasePath']; + $method['path'] = ''; + } + } + + $request = new apiServiceRequest( + $restBasePath, + $this->service->rpcPath, + $method['path'], + $method['id'], + $method['httpMethod'], + $parameters, $postBody + ); + + $request->setContentType($contentType); + if ($batchKey) { + $request->setBatchKey($batchKey); + return $request; + } else { + return apiREST::execute($request); + } + } + + protected function useObjects() { + global $apiConfig; + return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']); + } + + protected function stripNull(&$o) { + $o = (array) $o; + foreach ($o as $k => $v) { + if ($v === null || strstr($k, "\0*\0__")) { + unset($o[$k]); + } + elseif (is_object($v) || is_array($v)) { + $this->stripNull($o[$k]); + } + } + } +} diff --git a/inc/vendors/social-login/Google/service/apiUtils.php b/inc/vendors/social-login/Google/service/apiUtils.php new file mode 100755 index 00000000..e5749515 --- /dev/null +++ b/inc/vendors/social-login/Google/service/apiUtils.php @@ -0,0 +1,111 @@ + + */ +class apiUtils { + public static function urlSafeB64Encode($data) { + $b64 = base64_encode($data); + $b64 = str_replace(array('+', '/', '\r', '\n', '='), + array('-', '_'), + $b64); + return $b64; + } + + public static function urlSafeB64Decode($b64) { + $b64 = str_replace(array('-', '_'), + array('+', '/'), + $b64); + return base64_decode($b64); + } + + /** + * Misc function used to count the number of bytes in a post body, in the world of multi-byte chars + * and the unpredictability of strlen/mb_strlen/sizeof, this is the only way to do that in a sane + * manner at the moment. + * This algorithm was originally developed for the + * Solar Framework by Paul M. Jones + * @link http://solarphp.com/ + * @link http://svn.solarphp.com/core/trunk/Solar/Json.php + * @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php + * @param string $str + * @return int The number of bytes in a string. + */ + static public function getStrLen($str) { + $strlenVar = strlen($str); + $d = $ret = 0; + for ($count = 0; $count < $strlenVar; ++ $count) { + $ordinalValue = ord($str{$ret}); + switch (true) { + case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ret ++; + break; + + case (($ordinalValue & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $ret += 2; + break; + + case (($ordinalValue & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $ret += 3; + break; + + case (($ordinalValue & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $ret += 4; + break; + + case (($ordinalValue & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $ret += 5; + break; + + case (($ordinalValue & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $ret += 6; + break; + default: + $ret ++; + } + } + return $ret; + } + + /** + * Normalize all keys in an array to lower-case. + * @param array $arr + * @return array Normalized array. + */ + public static function normalize($arr) { + if (!is_array($arr)) { + return array(); + } + + $normalized = array(); + foreach ($arr as $key => $val) { + $normalized[strtolower($key)] = $val; + } + return $normalized; + } +} \ No newline at end of file diff --git a/inc/vendors/social-login/class-opalestate-facebook-login.php b/inc/vendors/social-login/class-opalestate-facebook-login.php new file mode 100755 index 00000000..96b31955 --- /dev/null +++ b/inc/vendors/social-login/class-opalestate-facebook-login.php @@ -0,0 +1,315 @@ +facebook_app_id = opalestate_get_option( 'facebook_app_id', '' ); + $this->facebook_secret = opalestate_get_option( 'facebook_secret', '' ); + + $this->includes(); + + add_action( 'query_vars', [ $this, 'add_query_vars' ] ); + add_action( 'parse_request', [ $this, 'process' ] ); + add_action( 'wp_ajax_opalestate_ajax_redirect_facebook_login_link', [ $this, 'ajax_redirect_facebook_login_link' ] ); + add_action( 'wp_ajax_nopriv_opalestate_ajax_redirect_facebook_login_link', [ $this, 'ajax_redirect_facebook_login_link' ] ); + } + + /** + * Includes. + */ + public function includes() { + if ( ! class_exists( 'Facebook/Facebook' ) ) { + require_once 'Facebook/autoload.php'; + } + } + + /** + * Add query vars. + * + * @param $vars + * @return array + */ + public function add_query_vars( $vars ) { + $vars[] = 'opal_facebook_login'; + + return $vars; + } + + /** + * Redirect facebook login link via AJAX. + * + * @throws \Facebook\Exceptions\FacebookSDKException + */ + public function ajax_redirect_facebook_login_link() { + if ( 'off' === opalestate_get_option( 'enable_facebook_login' ) ) { + wp_send_json_error( 'This feature is disabled.', 404 ); + } + + $facebook_app_id = $this->facebook_app_id; + $facebook_secret = $this->facebook_secret; + + if ( ! $facebook_app_id || ! $facebook_secret ) { + wp_send_json_error( 'Missing keys!', 404 ); + } + + $fb = new Facebook\Facebook( [ + 'app_id' => $facebook_app_id, + 'app_secret' => $facebook_secret, + 'default_graph_version' => 'v3.2', + ] ); + + $helper = $fb->getRedirectLoginHelper(); + $permissions = [ 'email' ]; + $link = add_query_arg( 'opal_facebook_login', '1', home_url( '/' ) ); + $login_url = $helper->getLoginUrl( $link, $permissions ); + + if ( ! $facebook_app_id || ! $facebook_secret ) { + wp_send_json_error( 'Missing keys!', 404 ); + } else { + wp_send_json_success( $login_url, 200 ); + } + wp_die(); + } + + /** + * Process. + * + * @param $wp + */ + public function process( $wp ) { + if ( array_key_exists( 'opal_facebook_login', $wp->query_vars ) ) { + if ( isset( $wp->query_vars['opal_facebook_login'] ) && $wp->query_vars['opal_facebook_login'] == '1' ) { + if ( ( isset( $_GET['code'] ) && isset( $_GET['state'] ) ) ) { + $vsessionid = session_id(); + if ( empty( $vsessionid ) ) { + session_name( 'PHPSESSID' ); + session_start(); + } + $this->login(); + } + } + wp_die(); + } + } + + /** + * Handle login. + * + * @throws \Facebook\Exceptions\FacebookSDKException + */ + public function login() { + $facebook_app_id = $this->facebook_app_id; + $facebook_secret = $this->facebook_secret; + + $fb = new Facebook\Facebook( [ + 'app_id' => $facebook_app_id, + 'app_secret' => $facebook_secret, + 'default_graph_version' => 'v3.2', + ] ); + + $helper = $fb->getRedirectLoginHelper(); + + try { + $accessToken = $helper->getAccessToken(); + } catch ( Facebook\Exceptions\FacebookResponseException $e ) { + // When Graph returns an error + echo 'Graph returned an error: ' . $e->getMessage(); + exit; + } catch ( Facebook\Exceptions\FacebookSDKException $e ) { + // When validation fails or other local issues + echo 'Facebook SDK returned an error: ' . $e->getMessage(); + exit; + } + + if ( ! isset( $accessToken ) ) { + if ( $helper->getError() ) { + header( 'HTTP/1.0 401 Unauthorized' ); + echo "Error: " . $helper->getError() . "\n"; + echo "Error Code: " . $helper->getErrorCode() . "\n"; + echo "Error Reason: " . $helper->getErrorReason() . "\n"; + echo "Error Description: " . $helper->getErrorDescription() . "\n"; + } else { + header( 'HTTP/1.0 400 Bad Request' ); + echo 'Bad request'; + } + exit; + } + + // Logged in + // echo '

            Access Token

            '; + // var_dump( $accessToken->getValue() ); + + // The OAuth 2.0 client handler helps us manage access tokens + $oAuth2Client = $fb->getOAuth2Client(); + + // Get the access token metadata from /debug_token + $tokenMetadata = $oAuth2Client->debugToken( $accessToken ); + // echo '

            Metadata

            '; + // var_dump( $tokenMetadata ); + + // Validation (these will throw FacebookSDKException's when they fail) + $tokenMetadata->validateAppId( $facebook_app_id ); // Replace {app-id} with your app id + // If you know the user ID this access token belongs to, you can validate it here + //$tokenMetadata->validateUserId('123'); + $tokenMetadata->validateExpiration(); + + if ( ! $accessToken->isLongLived() ) { + // Exchanges a short-lived access token for a long-lived one + try { + $accessToken = $oAuth2Client->getLongLivedAccessToken( $accessToken ); + } catch ( Facebook\Exceptions\FacebookSDKException $e ) { + echo "

            Error getting long-lived access token: " . $e->getMessage() . "

            \n\n"; + exit; + } + + // echo '

            Long-lived

            '; + // var_dump( $accessToken->getValue() ); + } + + $_SESSION['fb_access_token'] = (string) $accessToken; + + try { + // Returns a `Facebook\FacebookResponse` object + $response = $fb->get( '/me?fields=id,email,name,first_name,last_name', $accessToken ); + } catch ( Facebook\Exceptions\FacebookResponseException $e ) { + print 'Graph returned an error: ' . $e->getMessage(); + exit; + } catch ( Facebook\Exceptions\FacebookSDKException $e ) { + print 'Facebook SDK returned an error: ' . $e->getMessage(); + exit; + } + + $u = $response->getGraphUser(); + + $email = filter_var( $u['email'], FILTER_SANITIZE_EMAIL ); + + if ( ! is_user_logged_in() ) { + $ID = email_exists( $email ); + $random_password = wp_generate_password( 12, false ); + + if ( $ID ) { + // Login. + $user_info = get_userdata( $ID ); + wp_set_password( $random_password, $ID ); + + // Update user meta. + update_user_meta( $ID, 'opal_user_last_activity_date', strtotime( date( 'd-m-Y H:i:s' ) ) ); + + $credentials = []; + $credentials['user_login'] = $user_info->user_login; + $credentials['user_password'] = $random_password; + $credentials['remember'] = true; + + $this->signon( $credentials ); + } else { + // Register. + $sanitized_user_login = sanitize_user( 'Facebook - ' . $u['name'] ); + if ( ! validate_username( $sanitized_user_login ) ) { + $sanitized_user_login = sanitize_user( 'facebook' . $u['id'] ); + } + $defaul_user_name = $sanitized_user_login; + $i = 1; + while ( username_exists( $sanitized_user_login ) ) { + $sanitized_user_login = $defaul_user_name . $i; + $i++; + } + + $credentials = []; + $credentials['user_login'] = $sanitized_user_login; + $credentials['user_password'] = $random_password; + $credentials['remember'] = true; + + $user_id = wp_create_user( $sanitized_user_login, $random_password, $email ); + + // Update user meta. + update_user_meta( $user_id, 'opal_user_registered', 'facebook' ); + + /** + * After create Google user. + */ + do_action( 'opalestate_after_create_facebook_user_new_email', $user_id ); + + wp_update_user( [ + 'ID' => $user_id, + 'display_name' => $u['name'], + 'first_name' => isset( $u['first_name'] ) && $u['first_name'] ? $u['first_name'] : '', + 'last_name' => isset( $u['last_name'] ) && $u['last_name'] ? $u['last_name'] : '', + ] ); + + $this->signon( $credentials ); + } + exit(); + } else { + $user_info = wp_get_current_user(); + set_site_transient( $user_info->ID . '_facebook_admin_notice', 'Facebook logged', 3600 ); + } + exit(); + } + + /** + * Set facebook unique id. + * + * @return mixed|string + */ + public function get_uniqid() { + if ( isset( $_COOKIE['opal_facebook_uniqid'] ) ) { + if ( get_site_transient( 'n_' . $_COOKIE['opal_facebook_uniqid'] ) !== false ) { + return $_COOKIE['opal_facebook_uniqid']; + } + } + + $_COOKIE['opal_facebook_uniqid'] = uniqid( 'nextend', true ); + setcookie( 'opal_facebook_uniqid', $_COOKIE['opal_facebook_uniqid'], time() + 3600, '/' ); + set_site_transient( 'n_' . $_COOKIE['opal_facebook_uniqid'], 1, 3600 ); + + return $_COOKIE['opal_facebook_uniqid']; + } + + /** + * Redirect. + */ + public function redirect() { + $redirect = Opalestate_Social_Login::get_redirect_url(); + + header( 'LOCATION: ' . $redirect ); + delete_site_transient( $this->get_uniqid() . '_facebook_redirect' ); + exit(); + } + + public function signon( $credentials ) { + $user_signon = wp_signon( $credentials, true ); + + if ( is_wp_error( $user_signon ) ) { + wp_redirect( esc_url( home_url() ) ); + } else { + /** + * After signon successfully. + */ + do_action( 'opalestate_after_signon_successfully', $credentials ); + + $redirect = opalestate_get_user_management_page_uri(); + + if ( ! empty( $_REQUEST['redirect'] ) ) { + $redirect = sanitize_text_field( $_REQUEST['redirect'] ); + } + + $redirect = apply_filters( 'opalestate_signon_redirect_url', $redirect ); + wp_redirect( $redirect ); + } + } +} diff --git a/inc/vendors/social-login/class-opalestate-google-login.php b/inc/vendors/social-login/class-opalestate-google-login.php new file mode 100755 index 00000000..7489a425 --- /dev/null +++ b/inc/vendors/social-login/class-opalestate-google-login.php @@ -0,0 +1,309 @@ +google_client_id = opalestate_get_option( 'google_client_id', '' ); + $this->google_client_secret = opalestate_get_option( 'google_client_secret', '' ); + $this->google_api_key = opalestate_get_option( 'google_api_key', '' ); + + $this->includes(); + + add_filter( 'init', [ $this, 'add_query_var' ] ); + add_action( 'parse_request', [ $this, 'google_login_request' ] ); + add_action( 'login_init', [ $this, 'google_login' ] ); + add_action( 'wp_ajax_opalestate_ajax_redirect_google_login_link', [ $this, 'ajax_redirect_google_login_link' ] ); + add_action( 'wp_ajax_nopriv_opalestate_ajax_redirect_google_login_link', [ $this, 'ajax_redirect_google_login_link' ] ); + } + + /** + * Includes. + */ + public function includes() { + if ( ! class_exists( 'apiClient' ) && ! class_exists( 'apiOauth2Service' ) ) { + require_once 'Google/apiClient.php'; + require_once 'Google/contrib/apiOauth2Service.php'; + } + } + + /** + * Get login url. + * + * @return string + */ + public static function get_login_url() { + return home_url( 'wp-login.php' ) . '?opal_google_login=1'; + } + + /** + * Redirect google login link via AJAX. + */ + public function ajax_redirect_google_login_link() { + if ( 'off' === opalestate_get_option( 'enable_google_login' ) ) { + wp_send_json_error( 'This feature is disabled.', 404 ); + } + + $google_client_id = $this->google_client_id; + $google_client_secret = $this->google_client_secret; + $google_api_key = $this->google_api_key; + $google_redirect_url = static::get_login_url(); + + if ( ! $google_client_id || ! $google_client_secret || ! $google_api_key ) { + wp_send_json_error( 'Missing keys!', 404 ); + } else { + wp_send_json_success( $google_redirect_url, 200 ); + } + wp_die(); + } + + /** + * Add query var. + */ + public function add_query_var() { + global $wp; + $wp->add_query_var( 'opal_google_login' ); + } + + /** + * Login when parse request. + */ + public function google_login_request() { + global $wp; + if ( $wp->request == 'opal_google_login' || isset( $wp->query_vars['opal_google_login'] ) ) { + $this->login(); + } + } + + /** + * Login in login page. + */ + public function google_login() { + if ( isset( $_REQUEST['opal_google_login'] ) && $_REQUEST['opal_google_login'] == '1' ) { + $this->login(); + } + } + + /** + * Handle login. + * + * @throws \apiAuthException + */ + public function login() { + $google_client_id = $this->google_client_id; + $google_client_secret = $this->google_client_secret; + $google_api_key = $this->google_api_key; + $google_redirect_url = static::get_login_url(); + + if ( ! $google_client_id || ! $google_client_secret || ! $google_api_key ) { + wp_redirect( esc_url( home_url() ) ); + exit(); + } + + $client = new apiClient(); + $client->setClientId( $google_client_id ); + $client->setClientSecret( $google_client_secret ); + $client->setDeveloperKey( $google_api_key ); + $client->setRedirectUri( $google_redirect_url ); + $client->setApprovalPrompt( 'auto' ); + $oauth2 = new apiOauth2Service( $client ); + + // If isset code, redirect to google redirect url. + if ( isset( $_GET['code'] ) ) { + $_GET['redirect'] = $google_redirect_url; + + set_site_transient( $this->get_uniqid() . '_google_redirect', sanitize_text_field( $_GET['redirect'] ), 3600 ); + $client->authenticate(); + $access_token = $client->getAccessToken(); + set_site_transient( $this->get_uniqid() . '_google_atoken', $access_token, 3600 ); + header( 'Location: ' . filter_var( $google_redirect_url, FILTER_SANITIZE_URL ) ); + exit(); + } + + $access_token = get_site_transient( $this->get_uniqid() . '_google_atoken' ); + if ( $access_token !== false ) { + $client->setAccessToken( $access_token ); + } + + // Delete transient if logout. + if ( isset( $_REQUEST['logout'] ) ) { + delete_site_transient( $this->get_uniqid() . '_google_atoken' ); + $client->revokeToken(); + } + + // Process user data if has data, else redirect to createAuthUrl. + if ( $client->getAccessToken() ) { + try { + $u = $oauth2->userinfo->get(); + + // The access token may have been updated lazily. + set_site_transient( $this->get_uniqid() . '_google_atoken', $client->getAccessToken(), 3600 ); + + $email = filter_var( $u['email'], FILTER_SANITIZE_EMAIL ); + + if ( ! is_user_logged_in() ) { + $ID = email_exists( $email ); + $random_password = wp_generate_password( 12, false ); + + if ( $ID ) { + // Login. + $user_info = get_userdata( $ID ); + wp_set_password( $random_password, $ID ); + + // Update user meta. + update_user_meta( $ID, 'opal_user_last_activity_date', strtotime( date( 'd-m-Y H:i:s' ) ) ); + + $credentials = []; + $credentials['user_login'] = $user_info->user_login; + $credentials['user_password'] = $random_password; + $credentials['remember'] = true; + + $this->signon( $credentials ); + } else { + // Register. + $sanitized_user_login = sanitize_user( 'Google - ' . $u['name'] ); + if ( ! validate_username( $sanitized_user_login ) ) { + $sanitized_user_login = sanitize_user( 'google' . $u['id'] ); + } + $defaul_user_name = $sanitized_user_login; + $i = 1; + while ( username_exists( $sanitized_user_login ) ) { + $sanitized_user_login = $defaul_user_name . $i; + $i++; + } + + $credentials = []; + $credentials['user_login'] = $sanitized_user_login; + $credentials['user_password'] = $random_password; + $credentials['remember'] = true; + + $user_id = wp_create_user( $sanitized_user_login, $random_password, $email ); + + // Update user meta. + update_user_meta( $user_id, 'opal_user_registered', 'google' ); + + if ( isset( $u['picture'] ) && $u['picture'] ) { + update_user_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'avatar', esc_url( $u['picture'] ) ); + } + + /** + * After create Google user. + */ + do_action( 'opalestate_after_create_google_user_new_email', $user_id ); + + wp_update_user( [ + 'ID' => $user_id, + 'display_name' => $u['name'], + 'first_name' => isset( $u['given_name'] ) && $u['given_name'] ? $u['given_name'] : '', + 'last_name' => isset( $u['family_name'] ) && $u['family_name'] ? $u['family_name'] : '', + ] ); + + $this->signon( $credentials ); + } + exit(); + } else { + $user_info = wp_get_current_user(); + set_site_transient( $user_info->ID . '_google_admin_notice', 'Google logged', 3600 ); + } + } catch ( Google_ServiceException $e ) { + echo sprintf( '

            ' . 'Service error' . ' %s

            ', htmlspecialchars( $e->getMessage() ) ); + exit(); + } catch ( Google_Exception $e ) { + echo sprintf( '

            ' . 'Client error' . ' %s

            ', htmlspecialchars( $e->getMessage() ) ); + exit(); + } catch ( apiServiceException $e ) { + // Handle exception. You can also catch Exception here. + // You can also get the error code from $e->getCode(); + echo ( 'google_error_code' ) . ': ' . $e->getCode() . '
            '; + echo( 'google_authencitcation_failed' ); + exit(); + } + // End If + } else { + if ( isset( $_GET['redirect'] ) ) { + set_site_transient( $this->get_uniqid() . '_google_redirect', $_GET['redirect'], 3600 ); + } + + $redirect = get_site_transient( $this->get_uniqid() . '_google_redirect' ); + + if ( $redirect || $redirect == $google_redirect_url ) { + $redirect = esc_url( home_url( '/' ) ); + set_site_transient( $this->get_uniqid() . '_google_redirect', $redirect, 3600 ); + } + header( 'LOCATION: ' . $client->createAuthUrl() ); + exit(); + } + $this->redirect(); + } + + /** + * Set google unique id. + * + * @return mixed|string + */ + public function get_uniqid() { + if ( isset( $_COOKIE['opal_google_uniqid'] ) ) { + if ( get_site_transient( 'n_' . $_COOKIE['opal_google_uniqid'] ) !== false ) { + return $_COOKIE['opal_google_uniqid']; + } + } + + $_COOKIE['opal_google_uniqid'] = uniqid( 'nextend', true ); + setcookie( 'opal_google_uniqid', $_COOKIE['opal_google_uniqid'], time() + 3600, '/' ); + set_site_transient( 'n_' . $_COOKIE['opal_google_uniqid'], 1, 3600 ); + + return $_COOKIE['opal_google_uniqid']; + } + + /** + * Redirect. + */ + public function redirect() { + $redirect = Opalestate_Social_Login::get_redirect_url(); + + header( 'LOCATION: ' . $redirect ); + delete_site_transient( $this->get_uniqid() . '_google_redirect' ); + exit(); + } + + public function signon( $credentials ) { + $user_signon = wp_signon( $credentials, true ); + + if ( is_wp_error( $user_signon ) ) { + wp_redirect( esc_url( home_url() ) ); + } else { + /** + * After signon successfully. + */ + do_action( 'opalestate_after_signon_successfully', $credentials ); + + $redirect = opalestate_get_user_management_page_uri(); + + if ( ! empty( $_REQUEST['redirect'] ) ) { + $redirect = sanitize_text_field( $_REQUEST['redirect'] ); + } + + $redirect = apply_filters( 'opalestate_signon_redirect_url', $redirect ); + wp_redirect( $redirect ); + } + } +} diff --git a/inc/vendors/social-login/class-opalestate-social-login.php b/inc/vendors/social-login/class-opalestate-social-login.php new file mode 100755 index 00000000..9092490f --- /dev/null +++ b/inc/vendors/social-login/class-opalestate-social-login.php @@ -0,0 +1,144 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +class Opalestate_Social_Login { + public function __construct() { + add_action( 'opalestate_member_after_login_form', [ $this, 'login_template' ] ); + add_action( 'opalelementor_after_render_login_form', [ $this, 'login_template' ] ); + + if ( is_admin() ) { + add_filter( 'opalestate_settings_3rd_party_subtabs_nav', [ $this, 'register_admin_setting_tab' ], 1 ); + add_filter( 'opalestate_settings_3rd_party_subtabs_social_login_fields', [ $this, 'register_admin_settings' ], 10, 1 ); + } + + $this->inludes(); + $this->process(); + } + + public function inludes() { + require_once 'class-opalestate-facebook-login.php'; + require_once 'class-opalestate-google-login.php'; + } + + public function process() { + new Opalestate_Facebook_Login(); + new Opalestate_Google_Login(); + } + + public function login_template() { + echo opalestate_load_template_path( 'user/social-login/social-login' ); + } + + public function register_admin_setting_tab( $tabs ) { + $tabs['social_login'] = esc_html__( 'Social Login', 'opalestate-pro' ); + + return $tabs; + } + + public function register_admin_settings( $fields ) { + $fields = apply_filters( 'opalestate_settings_review', [ + [ + 'name' => esc_html__( 'Google', 'opalestate-pro' ), + 'desc' => '', + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_google', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Enable Google login', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Google login', 'opalestate-pro' ), + 'id' => 'enable_google_login', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + 'default' => 'off', + ], + [ + 'name' => esc_html__( 'Google Client ID', 'opalestate-pro' ), + 'desc' => esc_html__( 'Google Client ID is required for Google Login.', 'opalestate-pro' ), + 'id' => 'google_client_id', + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Google Client Secret', 'opalestate-pro' ), + 'desc' => esc_html__( 'Google Client Secret is required for Google Login.', 'opalestate-pro' ), + 'id' => 'google_client_secret', + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Google API key', 'opalestate-pro' ), + 'desc' => esc_html__( 'Google API key is required for Google Login.', 'opalestate-pro' ), + 'id' => 'google_api_key', + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Facebook', 'opalestate-pro' ), + 'desc' => '', + 'type' => 'opalestate_title', + 'id' => 'opalestate_title_general_settings_facebook', + 'before_row' => '
            ', + 'after_row' => '
            ', + ], + [ + 'name' => esc_html__( 'Enable Facebook login', 'opalestate-pro' ), + 'desc' => esc_html__( 'Enable Facebook login', 'opalestate-pro' ), + 'id' => 'enable_facebook_login', + 'type' => 'switch', + 'options' => [ + 'on' => esc_html__( 'Enable', 'opalestate-pro' ), + 'off' => esc_html__( 'Disable', 'opalestate-pro' ), + ], + 'default' => 'off', + ], + [ + 'name' => esc_html__( 'Facebook Application ID', 'opalestate-pro' ), + 'desc' => esc_html__( 'Facebook Application ID is required for Facebook login.', 'opalestate-pro' ), + 'id' => 'facebook_app_id', + 'type' => 'text', + ], + [ + 'name' => esc_html__( 'Facebook Secret', 'opalestate-pro' ), + 'desc' => esc_html__( 'Facebook Secret is required for Facebook login.', 'opalestate-pro' ), + 'id' => 'facebook_secret', + 'type' => 'text', + ], + ] ); + + return $fields; + } + + /** + * Gets redirect URL. + * + * @return mixed|void + */ + public static function get_redirect_url() { + if ( isset( $_GET['redirect_to'] ) && $_GET['redirect_to'] != '' ) { + $redirect = get_permalink( sanitize_text_field( $_GET['redirect_to'] ) ); + } else { + $redirect = esc_url( home_url( '/' ) ); + } + + return apply_filters( 'opal_social_login_redirect_to', $redirect ); + } +} + +new Opalestate_Social_Login(); diff --git a/inc/widgets/featured-properties.php b/inc/widgets/featured-properties.php new file mode 100755 index 00000000..49b477e5 --- /dev/null +++ b/inc/widgets/featured-properties.php @@ -0,0 +1,83 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ + +class Opalestate_featured_properties_Widget extends WP_Widget{ + + public function __construct() { + parent::__construct( + // Base ID of your widget + 'opalestate_featured_properties_widget', + // Widget name will appear in UI + esc_html__('Estate: Featured Properties', 'opalestate-pro'), + // Widget description + array( 'description' => esc_html__( 'Featured Properties widget.', 'opalestate-pro' ), ) + ); + } + + public function widget( $args, $instance ) { + + + extract( $args ); + extract( $instance ); + + + //Check + + $tpl = OPALESTATE_THEMER_WIDGET_TEMPLATES .'widgets/featured-properties.php'; + $tpl_default = OPALESTATE_PLUGIN_DIR .'templates/widgets/featured-properties.php'; + + if( is_file($tpl) ) { + $tpl_default = $tpl; + } + require $tpl_default; + } + + + // Form + + public function form( $instance ) { + //Set up some default widget settings. + $defaults = array( + 'title' => esc_html__('Featured Properties', 'opalestate-pro'), + 'num' => '5' + ); + $instance = wp_parse_args( (array) $instance, $defaults ); ?> +

            + + +

            + +

            + +
            + +

            + diff --git a/inc/widgets/mortgage-calculator.php b/inc/widgets/mortgage-calculator.php new file mode 100755 index 00000000..a958a14c --- /dev/null +++ b/inc/widgets/mortgage-calculator.php @@ -0,0 +1,62 @@ + esc_html__( 'Mortgage Calculator widget.', 'opalestate-pro' ), ] + ); + } + + public function widget( $instance, $args ) { + extract( $args ); + extract( $instance ); + + //Check + $tpl = OPALESTATE_THEMER_WIDGET_TEMPLATES . 'parts/mortgage-calculator.php'; + $tpl_default = OPALESTATE_PLUGIN_DIR . 'templates/parts/mortgage-calculator.php'; + + if ( is_file( $tpl ) ) { + $tpl_default = $tpl; + } + require $tpl_default; + } + + + public function form( $instance ) { + //Set up some default widget settings. + $defaults = [ + 'title' => esc_html__( 'Mortgage Calculator', 'opalestate-pro' ), + ]; + $instance = wp_parse_args( (array) $instance, $defaults ); ?> +

            + + +

            + + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ + +class Opalestate_profile_info_Widget extends WP_Widget { + + public function __construct() { + parent::__construct( + // Base ID of your widget + 'opalestate_profile_info_widget', + // Widget name will appear in UI + esc_html__( 'Estate: User Menu Profile', 'opalestate-pro' ), + // Widget description + [ 'description' => esc_html__( 'Display Profile information in box and menu.', 'opalestate-pro' ), ] + ); + } + + /** + * + */ + public function widget( $args, $instance ) { + + global $before_widget, $after_widget, $before_title, $after_title, $post; + + if ( ! is_user_logged_in() ) { + return; + } + + extract( $args ); + + $title = apply_filters( 'widget_title', $instance['title'] ); + + + echo( $before_widget ); + + + if ( $title ) { + echo ( $before_title ) . $title . ( $after_title ); + } + ?> +
            + + +
            + +
            + +
            + esc_html__( 'My Profile', 'opalestate-pro' ), + ]; + $instance = wp_parse_args( (array) $instance, $defaults ); ?> +

            + + +

            + + diff --git a/inc/widgets/sameprice-properties.php b/inc/widgets/sameprice-properties.php new file mode 100755 index 00000000..62a83e10 --- /dev/null +++ b/inc/widgets/sameprice-properties.php @@ -0,0 +1,92 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ + +class Opalestate_sammeprice_properties_Widget extends WP_Widget{ + + public function __construct() { + parent::__construct( + // Base ID of your widget + 'opalestate_samepriceproperties_widget', + // Widget name will appear in UI + esc_html__('Estate: Same Price', 'opalestate-pro'), + // Widget description + array( 'description' => esc_html__( 'Similar Properties By Same Price with configured range and Status', 'opalestate-pro' ), ) + ); + } + + public function widget( $instance , $args ) { + $default = array( + 'num' => 5, + 'range_price' => 100, + ); + $args = array_merge( $default , $args ); + extract( $args ); + extract( $instance ); + //Check + $tpl = OPALESTATE_THEMER_WIDGET_TEMPLATES .'widgets/sameprice-properties.php'; + $tpl_default = OPALESTATE_PLUGIN_DIR .'templates/widgets/sameprice-properties.php'; + + if( is_file($tpl) ) { + $tpl_default = $tpl; + } + require $tpl_default; + } + + + // Form + + public function form( $instance ) { + //Set up some default widget settings. + $defaults = array( + 'title' => esc_html__('Same Price', 'opalestate-pro'), + 'num' => '5', + 'range_price' => 1000 + ); + $instance = wp_parse_args( (array) $instance, $defaults ); ?> +

            + + +

            + +

            + +
            + +

            + +

            + +
            + +

            + + diff --git a/inc/widgets/search-properties.php b/inc/widgets/search-properties.php new file mode 100755 index 00000000..8c56dd8b --- /dev/null +++ b/inc/widgets/search-properties.php @@ -0,0 +1,153 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ + +class Opalestate_search_properties_Widget extends WP_Widget { + /** + * Opalestate_search_properties_Widget constructor. + */ + public function __construct() { + parent::__construct( + // Base ID of your widget + 'opalestate_search_properties_widget', + // Widget name will appear in UI + __( 'Estate: Search Properties', 'opalestate-pro' ), + // Widget description + [ 'description' => esc_html__( 'Search Properties widget.', 'opalestate-pro' ), ] + ); + } + + public function widget( $args, $instance ) { + extract( $args ); + extract( $instance ); + //Our variables from the widget settings. + $title = apply_filters( 'widget_title', esc_attr( $instance['title'] ) ); + + // Output the widget. + echo $before_widget; // @WPCS: XSS OK. + + if ( $title ) { + echo $before_title . $title . $after_title; // @WPCS: XSS OK. + } + ?> + +
            + +
            + + esc_html__( 'Search Properties', 'opalestate-pro' ), + 'hidden_labels' => 'true', + 'nobutton' => '', + 'style' => 'search-form-v', + 'display_country' => true, + 'display_state' => '', + 'display_city' => '', + ]; + + $instance = wp_parse_args( (array) $instance, $defaults ); ?> +

            + + +

            + +

            + + +

            + +

            + + +

            + +

            + + +

            + +

            + + +

            + +

            + + +

            + +

            + + +

            + + esc_html__( 'No', 'opalestate-pro' ), + 'true' => esc_html__( 'Yes', 'opalestate-pro' ), + ]; + } +} + +register_widget( 'Opalestate_search_properties_Widget' ); diff --git a/inc/widgets/similar-properties.php b/inc/widgets/similar-properties.php new file mode 100755 index 00000000..4ed371f1 --- /dev/null +++ b/inc/widgets/similar-properties.php @@ -0,0 +1,82 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ + +class Opalestate_similar_properties_Widget extends WP_Widget{ + + public function __construct() { + parent::__construct( + // Base ID of your widget + 'opalestate_similarproperties_widget', + // Widget name will appear in UI + esc_html__('Estate: Similar Properties', 'opalestate-pro'), + // Widget description + array( 'description' => esc_html__( 'Similar Properties By Same Types and Status Of the post', 'opalestate-pro' ), ) + ); + } + + public function widget( $args, $instance ) { + + + extract( $args ); + extract( $instance ); + + //Check + + $tpl = OPALESTATE_THEMER_WIDGET_TEMPLATES .'widgets/similar-properties.php'; + $tpl_default = OPALESTATE_PLUGIN_DIR .'templates/widgets/similar-properties.php'; + + if( is_file($tpl) ) { + $tpl_default = $tpl; + } + require $tpl_default; + } + + + // Form + + public function form( $instance ) { + //Set up some default widget settings. + $defaults = array( + 'title' => esc_html__('Similar Properties', 'opalestate-pro'), + 'num' => '5' + ); + $instance = wp_parse_args( (array) $instance, $defaults ); ?> +

            + + +

            + +

            + +
            + +

            + diff --git a/languages/opalestate-pro-backup-201909030250570.pot~ b/languages/opalestate-pro-backup-201909030250570.pot~ new file mode 100644 index 00000000..361de15f --- /dev/null +++ b/languages/opalestate-pro-backup-201909030250570.pot~ @@ -0,0 +1,6515 @@ +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Opal Estate Pro\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-13 06:25+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: \n" +"Language: \n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Loco https://localise.biz/\n" +"X-Loco-Version: 2.3.0; wp-5.2.2" + +#: templates/parts/membership-pricing-info.php:21 +#: templates/parts/membership-pricing-info.php:23 +msgid " Featured" +msgstr "" + +#: templates/parts/membership-pricing-info.php:12 +#: templates/parts/membership-pricing-info.php:14 +msgid " Listings" +msgstr "" + +#: templates/messages/enquiry-form.php:23 +#: templates/messages/enquiry-form.php:38 +#: templates/messages/contact-form.php:37 +#: templates/user/share-search-form.php:48 +#: templates/user-search/render-form.php:33 +msgid " Processing" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:233 +msgid " Unlimited listings ?" +msgstr "" + +#: templates/archive-opalestate_agency.php:74 +#: templates/archive-opalestate_agent.php:64 +#: templates/archive-opalestate_property.php:52 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:318 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:330 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:353 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:318 +msgid "« Previous" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:494 +#: inc/vendors/opalmembership/membership.php:498 +msgid "(Package) Featured Included:" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:493 +#: inc/vendors/opalmembership/membership.php:497 +msgid "(Package) Listings Included:" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:209 +#: templates/single-property/virtualtour.php:8 +msgid "360° Virtual Tour" +msgstr "" + +#: inc/admin/register-settings.php:123 +msgid "3rd Party" +msgstr "" + +#: inc/admin/settings/3rd_party.php:49 +msgid "3rd Party Settings" +msgstr "" + +#: install.php:99 +msgid "[opalestate_myaccount]" +msgstr "" + +#: install.php:135 +msgid "[opalestate_search_map_properties]" +msgstr "" + +#: install.php:117 +msgid "[opalestate_submission]" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:333 +msgid "A metabox with the specified 'metabox_id' doesn't exist." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:60 +msgid "A user could not be found with this email address." +msgstr "" + +#: templates/content-single-agent.php:54 +msgid "About the Agent" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:122 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:176 +msgid "Account" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:212 +msgid "Active Life" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:51 +msgid "add" +msgstr "" + +#. %s is property title +#: templates/rating/opalestate-ratings.php:228 +msgid "Add a review" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:421 +#: inc/property/class-metabox-property-admin.php:611 +#: inc/property/class-metabox-property-admin.php:680 +#: inc/submission/class-metabox-property-submission.php:454 +#: inc/submission/class-metabox-property-submission.php:533 +#: inc/submission/class-metabox-property-submission.php:609 +msgid "Add more" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:42 +#: inc/agency/class-opalestate-agency-posttype.php:43 +msgid "Add New Agency" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:35 +#: inc/agent/class-opalestate-agent-posttype.php:36 +msgid "Add New Agent" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:42 +msgid "Add New Amenity" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:82 +msgid "Add New Category" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:43 +msgid "Add New City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:44 +msgid "Add New Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:45 +msgid "Add New Label" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:80 +msgid "Add New Level" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:74 +msgid "Add New Neighborhood" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:41 +#: inc/property/class-opalestate-posttype.php:42 +#: templates/shortcodes/submission-form.php:30 +#: templates/submission/submission-form.php:16 +msgid "Add New Property" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:46 +msgid "Add New Property Category" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:56 +msgid "Add new rating feature" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:42 +msgid "Add New State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:45 +msgid "Add New Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:83 +msgid "Add New Type" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:55 +msgid "Add rating feature" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:46 +msgid "" +"Add someone to your agency, please enter extractly username in below input:" +msgstr "" + +#: templates/user/favorite-button.php:12 +msgid "Add To Favorite" +msgstr "" + +#: inc/admin/settings/3rd_party.php:67 +msgid "" +"Add Walk Score API key. To get your Walk Score API key, go to your Walk " +"Score Account." +msgstr "" + +#: inc/admin/settings/3rd_party.php:93 +msgid "" +"Add Yelp API Secret. Register here" +msgstr "" + +#: inc/admin/settings/3rd_party.php:86 +msgid "" +"Add Yelp client ID. To get your Yelp Api Client ID, go to your Yelp Account. " +"Register here" +msgstr "" + +#: inc/admin/register-settings.php:115 +msgid "Add-ons" +msgstr "" + +#: inc/admin/register-settings.php:84 +msgid "Addons" +msgstr "" + +#: templates/content-single-agency.php:24 +#: templates/content-single-agency.php:66 +#: inc/classes/class-opalestate-metabox-user.php:103 +#: inc/property/class-metabox-property-admin.php:217 +#: inc/submission/class-metabox-property-submission.php:381 +#: inc/admin/property/class-property.php:101 +msgid "Address" +msgstr "" + +#: templates/content-single-agent.php:79 +msgid "Address:" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:54 +msgctxt "Admin menu name" +msgid "Rating Features" +msgstr "" + +#: inc/email/class-opalestate-abs-email-template.php:43 +msgid "Admin Notice of Expiring Job Listings" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:201 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:170 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:193 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:171 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:201 +msgid "Advanced" +msgstr "" + +#: inc/mixes-functions.php:128 +msgid "Advanced V1 Form" +msgstr "" + +#: inc/mixes-functions.php:129 +msgid "Advanced V2 Form" +msgstr "" + +#: inc/mixes-functions.php:130 +msgid "Advanced V3 Form" +msgstr "" + +#: inc/mixes-functions.php:131 +msgid "Advanced V4 Form" +msgstr "" + +#: inc/mixes-functions.php:132 +msgid "Advanced V5 Form" +msgstr "" + +#: inc/mixes-functions.php:133 +msgid "Advanced V6 Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:105 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:105 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:91 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:91 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:105 +msgid "Advanded" +msgstr "" + +#: inc/mixes-functions.php:475 +msgid "Afghan afghani" +msgstr "" + +#: inc/admin/settings/general.php:206 +msgid "After - 10$" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:270 +#: inc/submission/class-metabox-property-submission.php:140 +msgid "After Price Label (e.g. \"per month\")" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:268 +#: inc/submission/class-metabox-property-submission.php:138 +msgid "After Price Label (optional)" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:40 +#: inc/agency/class-opalestate-agency-posttype.php:52 +msgid "Agencies" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:94 +msgid "Agencies Search/Collection" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:482 +#: inc/user/class-opalestate-user.php:274 +msgid "Agency" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:74 +#: inc/agency/class-opalestate-agency-posttype.php:84 +msgid "Agency Categories" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:443 +#: inc/agency/class-opalestate-agency-metabox.php:391 +msgid "Agency Information" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:96 +msgid "Agency Profile" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:80 +msgid "Agency Search Form" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:102 +#: templates/user/agency/agency-team.php:36 +msgid "Agency Team" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:80 +msgid "Agency/Agent Tab Form Search" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:476 +#: inc/user/class-opalestate-user.php:273 +msgid "Agent" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:442 +msgid "Agent Information" +msgstr "" + +#: templates/single-agent/author-box.php:31 +msgid "Agent details" +msgstr "" + +#: templates/user/agent/profile-agent.php:23 +msgid "Agent edit profile form is not avariable" +msgstr "" + +#: inc/admin/settings/general.php:111 inc/admin/settings/general.php:122 +msgid "Agent Image Size" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:215 +msgid "Agent Information" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:72 +#: inc/agent/class-opalestate-agent-posttype.php:82 +msgid "Agent Levels" +msgstr "" + +#: inc/agent/class-opalestate-agent-front.php:91 +#: inc/agent/class-opalestate-agent-front.php:320 +msgid "Agent Profile" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:36 +msgid "Agent Team" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:33 +#: inc/agent/class-opalestate-agent-posttype.php:45 +msgid "Agents" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:94 +msgid "Agents Search Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:80 +msgid "Agents Search Form" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:43 +#: inc/property/class-opalestate-shortcodes.php:44 +msgid "Ajax Search Map Properties" +msgstr "" + +#: inc/mixes-functions.php:476 +msgid "Albanian lek" +msgstr "" + +#: inc/mixes-functions.php:514 +msgid "Algerian dinar" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:345 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:357 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:380 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:220 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:345 +msgid "Alignment" +msgstr "" + +#: inc/class-opalestate-html.php:222 inc/template-functions.php:354 +#: templates/user/my-properties.php:3 templates/parts/search-form-h.php:25 +#: templates/search-box/fields/status-bar.php:9 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:154 +msgid "All" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:46 +msgid "All Agencies" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:39 +msgid "All Agents" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:37 +msgid "All Amenities" +msgstr "" + +#: templates/parts/mortgage-calculator.php:178 +msgid "" +"All calculation are based on tentative and estimated figure and shall not " +"replace any financial advice" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:77 +msgid "All Categories" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:38 +msgid "All Cities / Town" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:39 +msgid "All Countries" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:40 +msgid "All Label" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:75 +msgid "All Levels" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:69 +msgid "All Neighborhoods" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:45 +msgid "All Properties" +msgstr "" + +#: inc/importer/class-import-steps.php:570 +msgid "" +"All siders are downloading from live server then extract and install, please " +"waiting for a while!" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:37 +msgid "All States / Province" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:40 +msgid "All Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:78 +msgid "All Types" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:30 +msgid "Allow set automatic a free package." +msgstr "" + +#: inc/vendors/cmb2-plugins/uploader/uploader.php:154 +#, php-format +msgid "Allow upload file have size < %s MB and maximum number of files: %s" +msgstr "" + +#: inc/admin/settings/general.php:67 +msgid "" +"Allow User send message Contact/Equire via email and saved into database to " +"exchange theirs message direct in User Message Management" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:34 +#: inc/taxonomies/class-taxomony-amenities.php:44 +#: inc/submission/class-metabox-property-submission.php:65 +#: inc/submission/class-metabox-property-submission.php:416 +#: templates/search-box/search-form-v3.php:51 +#: templates/search-box/search-form-v2.php:34 +msgid "Amenities" +msgstr "" + +#: inc/user/functions.php:223 +msgid "An account is already registered with your email address. Please login." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:682 +msgid "An error occured when removing an item." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:251 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:220 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:243 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:251 +msgid "AND" +msgstr "" + +#: inc/mixes-functions.php:479 +msgid "Angolan kwanza" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:299 +msgid "Animation Speed" +msgstr "" + +#: templates/parts/mortgage-calculator.php:165 +#: templates/parts/mortgage-calculator.php:166 +#: templates/widgets/mortgage-calculator.php:152 +#: templates/widgets/mortgage-calculator.php:153 +msgid "Annual Interest" +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:46 +#: templates/parts/search-form-v.php:63 +msgid "Any" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:679 +#: inc/submission/class-metabox-property-submission.php:532 +msgid "Apartment {#}" +msgstr "" + +#: templates/content-single-property-v5.php:30 +#: inc/property/class-metabox-property-admin.php:83 +#: inc/submission/class-metabox-property-submission.php:67 +#: inc/submission/class-metabox-property-submission.php:469 +#: templates/single-property/apartments.php:14 +msgid "Apartments" +msgstr "" + +#: inc/admin/register-settings.php:122 inc/admin/settings/api_keys.php:28 +#: inc/admin/settings/api_keys.php:34 +msgid "API" +msgstr "" + +#: inc/admin/class-api-keys-table.php:54 +msgid "API Key" +msgstr "" + +#: inc/admin/class-api-keys-table.php:55 +msgid "API Keys" +msgstr "" + +#: inc/admin/functions.php:372 +#, php-format +msgid "" +"API keys allow users to use the Opalestate REST API to " +"retrieve donation data in JSON or XML for external applications or devices, " +"such as Zapi_keyser." +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:78 +msgid "Apply" +msgstr "" + +#: inc/class-opalestate-email.php:331 +msgid "Approve For Publish - {property_name}" +msgstr "" + +#: inc/class-opalestate-email.php:304 +msgid "Approve property for publish" +msgstr "" + +#: templates/user/share-search-form.php:23 +msgid "Are you searching with anyone? Share this search." +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:64 +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:76 +msgid "Are you sure to delete this" +msgstr "" + +#: templates/user-search/content-savedsearch.php:22 +msgid "Are you sure to delete this?" +msgstr "" + +#: inc/class-opalestate-enqueue.php:86 +msgid "Are you sure to remove?" +msgstr "" + +#: templates/user/content-property.php:91 +msgid "Are you sure you wish to delete?" +msgstr "" + +#: inc/function-search-fields.php:83 templates/search-box/search-form-v3.php:61 +#: templates/search-box/search-form-v2.php:44 +msgid "Area" +msgstr "" + +#: inc/template-functions.php:229 +msgid "Area Ascending" +msgstr "" + +#: inc/template-functions.php:230 +msgid "Area Desending" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:346 +#: inc/submission/class-metabox-property-submission.php:288 +msgid "Area Size" +msgstr "" + +#: inc/mixes-functions.php:480 +msgid "Argentine peso" +msgstr "" + +#: inc/mixes-functions.php:477 +msgid "Armenian dram" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:200 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:338 +msgid "Arrows" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:199 +msgid "Arrows and Dots" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:216 +msgid "Arts & Entertainment" +msgstr "" + +#: inc/mixes-functions.php:482 +msgid "Aruban florin" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:44 +msgid "As an author, you can add other users to your agency." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:228 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:197 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:220 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:197 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:228 +msgid "ASC" +msgstr "" + +#: templates/content-single-property-v2.php:66 +msgid "Attachment" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:126 +#: inc/property/class-metabox-property-admin.php:130 +#: inc/submission/class-metabox-property-submission.php:216 +msgid "Attachments" +msgstr "" + +#: inc/mixes-functions.php:481 +msgid "Australian dollar" +msgstr "" + +#: inc/admin/property/class-property.php:103 +msgid "Author" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:469 +msgid "Author Information" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:220 +msgid "Automotive" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:244 +msgid "Autoplay" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:258 +msgid "Autoplay Speed" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:666 +#: inc/submission/class-metabox-property-submission.php:518 +msgid "Available" +msgstr "" + +#: templates/rating/opalestate-ratings.php:252 +#: templates/rating/opalestate-ratings.php:264 +msgid "Average" +msgstr "" + +#: inc/mixes-functions.php:483 +msgid "Azerbaijani manat" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:81 +#: inc/taxonomies/class-taxonomy-status.php:77 +msgid "Background" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:316 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:402 +msgid "Background Color" +msgstr "" + +#: inc/mixes-functions.php:494 +msgid "Bahamian dollar" +msgstr "" + +#: inc/mixes-functions.php:488 +msgid "Bahraini dinar" +msgstr "" + +#: inc/mixes-functions.php:486 +msgid "Bangladeshi taka" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:315 +#: inc/agent/class-opalestate-agent-metabox.php:148 +msgid "Banner" +msgstr "" + +#: inc/mixes-functions.php:485 +msgid "Barbadian dollar" +msgstr "" + +#: templates/rating/opalestate-ratings.php:132 +msgid "based on all ratings" +msgstr "" + +#: inc/property/class-opalestate-search.php:396 +msgid "Bath Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:330 +#: inc/submission/class-metabox-property-submission.php:270 +msgid "Bathrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:586 +#: inc/submission/class-metabox-property-submission.php:582 +msgid "Baths" +msgstr "" + +#: templates/single-property/floor-plans.php:63 +msgid "Baths:" +msgstr "" + +#: templates/rating/opalestate-ratings.php:228 +#, php-format +msgid "Be the first to review “%s”" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:224 +msgid "Beauty & Spas" +msgstr "" + +#: inc/property/class-opalestate-search.php:394 +msgid "Bed Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:320 +#: inc/submission/class-metabox-property-submission.php:258 +msgid "Bedrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:641 +#: inc/submission/class-metabox-property-submission.php:494 +#: templates/single-property/apartments.php:23 +msgid "Beds" +msgstr "" + +#: inc/admin/settings/general.php:205 +msgid "Before - $10" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:264 +#: inc/submission/class-metabox-property-submission.php:134 +msgid "Before Price Label (e.g. \"from\")" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:262 +#: inc/submission/class-metabox-property-submission.php:132 +msgid "Before Price Label (optional)" +msgstr "" + +#: inc/mixes-functions.php:498 +msgid "Belarusian ruble" +msgstr "" + +#: inc/mixes-functions.php:499 +msgid "Belize dollar" +msgstr "" + +#: inc/mixes-functions.php:490 +msgid "Bermudian dollar" +msgstr "" + +#: inc/mixes-functions.php:496 +msgid "Bhutanese ngultrum" +msgstr "" + +#: templates/single-property/walkscore.php:48 +msgid "Bikeable Scores" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:51 +#: inc/agency/class-opalestate-agency-metabox.php:129 +msgid "Biographical Info" +msgstr "" + +#: inc/mixes-functions.php:495 +msgid "Bitcoin" +msgstr "" + +#: inc/admin/class-user.php:168 +msgid "Block Submssion" +msgstr "" + +#: inc/admin/class-user.php:176 +msgid "Block Submssion Message" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:44 +msgid "Block: Account Button" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:54 +msgid "Block: Agencies Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:40 +msgid "Block: Agency - Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:54 +msgid "Block: Agent Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:40 +msgid "Block: Agents - Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:54 +msgid "Block: Category Listing" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:55 +msgid "Block: Property Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:40 +msgid "Block: Split Maps Property Search" +msgstr "" + +#: inc/mixes-functions.php:492 +msgid "Bolivian boliviano" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:357 +msgid "Border Radius" +msgstr "" + +#: inc/mixes-functions.php:484 +msgid "Bosnia and Herzegovina convertible mark" +msgstr "" + +#: inc/mixes-functions.php:497 +msgid "Botswana pula" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:95 +msgid "Brand Items" +msgstr "" + +#: inc/mixes-functions.php:493 +msgid "Brazilian real" +msgstr "" + +#: inc/admin/views/addons/list.php:3 +msgid "Browse All Add-ons" +msgstr "" + +#: templates/archive-opalestate_agent.php:13 +msgid "" +"Browser home sales, rating and review to find the best agent to sell or " +"lease your home" +msgstr "" + +#: inc/mixes-functions.php:491 +msgid "Brunei dollar" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:657 +#: inc/submission/class-metabox-property-submission.php:510 +#: templates/single-property/apartments.php:26 +msgid "Building / Address" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:298 +#: inc/submission/class-metabox-property-submission.php:238 +msgid "Built year" +msgstr "" + +#: inc/mixes-functions.php:487 +msgid "Bulgarian lev" +msgstr "" + +#: inc/mixes-functions.php:565 +msgid "Burmese kyat" +msgstr "" + +#: inc/mixes-functions.php:489 +msgid "Burundian franc" +msgstr "" + +#: inc/classes/class-opalestate-cache.php:205 +#: inc/classes/class-opalestate-cache.php:246 +#: inc/classes/class-opalestate-cache.php:295 +msgid "Cache key format should be opalestate_cache_*" +msgstr "" + +#: templates/parts/property-loop-price.php:15 +msgid "Call to Price" +msgstr "" + +#: inc/mixes-functions.php:548 +msgid "Cambodian riel" +msgstr "" + +#: inc/mixes-functions.php:500 +msgid "Canadian dollar" +msgstr "" + +#: inc/class-opalestate-html.php:56 +msgid "Cancel" +msgstr "" + +#: inc/mixes-functions.php:509 +msgid "Cape Verdean escudo" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:222 +msgid "Carousel Additional Options" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:153 +msgid "Carousel Options" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:237 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:206 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:229 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:206 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:237 +msgid "Categories" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:75 +msgid "Category" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:94 +msgid "Category Collection" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:77 +msgid "Category image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:69 +#: inc/taxonomies/class-taxonomy-labels.php:75 +#: inc/taxonomies/class-taxonomy-status.php:71 +msgid "Category Metabox" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:247 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:216 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:239 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:247 +msgid "Category Operator" +msgstr "" + +#: inc/mixes-functions.php:553 +msgid "Cayman Islands dollar" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:353 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:365 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:388 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:228 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:353 +msgid "Center" +msgstr "" + +#: inc/mixes-functions.php:627 +msgid "Central African CFA franc" +msgstr "" + +#: inc/mixes-functions.php:630 +msgid "CFP franc" +msgstr "" + +#: templates/user/profile.php:41 +msgid "Change Password" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:515 +msgid "" +"Change to new owner of this property, which be listed in That user dashboard" +msgstr "" + +#: opal-estate-pro.php:170 +msgid "Cheatin’ huh?" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:301 +msgid "Check your email address for you new password." +msgstr "" + +#: inc/mixes-functions.php:503 +msgid "Chilean peso" +msgstr "" + +#: inc/mixes-functions.php:504 +msgid "Chinese yuan" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:103 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:157 +msgid "Choose Icon" +msgstr "" + +#: inc/admin/settings/general.php:176 +msgid "Choose layout for single property." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:264 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:287 +msgid "Cities" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:35 +#: inc/taxonomies/class-taxonomy-city.php:45 +msgid "Cities / Towns" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:126 +msgid "City" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:95 +#: inc/submission/class-metabox-property-submission.php:368 +msgid "City / Town" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:77 +msgid "City image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:69 +msgid "City Metabox" +msgstr "" + +#: templates/rating/opalestate-ratings.php:283 +msgid "Click here to login" +msgstr "" + +#: templates/submission/completed.php:11 templates/submission/completed.php:19 +#, php-format +msgid "Click to %s here %s to back to your listing or %s edit %s this." +msgstr "" + +#: templates/parts/membership-warning.php:4 +msgid "Click to this link to see plans" +msgstr "" + +#: inc/mixes-functions.php:139 +msgid "Collapse City Form" +msgstr "" + +#: inc/mixes-functions.php:140 +msgid "Collapse Keyword Form" +msgstr "" + +#: inc/mixes-functions.php:505 +msgid "Colombian peso" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:87 +#: inc/taxonomies/class-taxonomy-status.php:83 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:386 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:448 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:179 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:257 +msgid "Color" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:108 +msgid "Column" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:134 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:106 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:113 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:114 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:125 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:125 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:109 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:134 +msgid "Columns" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:150 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:117 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:127 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:130 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:141 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:141 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:125 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:150 +msgid "Columns Gap" +msgstr "" + +#: inc/mixes-functions.php:549 +msgid "Comorian franc" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:132 +msgid "Company" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:145 +msgid "company" +msgstr "" + +#: inc/importer/class-import-steps.php:911 +msgid "Completed the installation" +msgstr "" + +#: inc/user/class-opalestate-user.php:472 +msgid "Confirm Password" +msgstr "" + +#: inc/importer/class-import-steps.php:66 +msgid "Confirmed to install the sample " +msgstr "" + +#: inc/mixes-functions.php:501 +msgid "Congolese franc" +msgstr "" + +#: templates/user/social-login/facebook-button.php:20 +msgid "Connect with Facebook" +msgstr "" + +#: templates/user/social-login/google-button.php:20 +msgid "Connect with Google" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:151 +msgid "Contact email" +msgstr "" + +#: templates/messages/contact-form.php:13 +msgid "Contact Me" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:143 +msgid "Contact Member" +msgstr "" + +#: templates/parts/property-loop-price.php:34 +msgid "Contact Property" +msgstr "" + +#: templates/content-single-agency.php:140 +msgid "Contact Us" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:415 +#: inc/property/class-metabox-property-admin.php:592 +#: inc/submission/class-metabox-property-submission.php:448 +#: inc/submission/class-metabox-property-submission.php:588 +msgid "Content" +msgstr "" + +#. %s: Name of current post +#: templates/content-single-agency.php:50 templates/content-single-agent.php:58 +#, php-format +msgid "Continue reading %s" +msgstr "" + +#. %s: Name of current post +#: templates/single-property/content.php:6 +#, php-format +msgid "Continue reading %s " +msgstr "" + +#: inc/mixes-functions.php:506 +msgid "Costa Rican colón" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:179 +msgid "Could not allow uploading image" +msgstr "" + +#: inc/importer/class-import-steps.php:249 +msgid "" +"Could not fetch data for the installation, Please try again or contact our " +"developer. Thanks!!!" +msgstr "" + +#: inc/ajax-functions.php:213 inc/ajax-functions.php:218 +msgid "Could not set this as featured" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:185 +msgid "Count" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:36 +#: inc/taxonomies/class-taxonomy-locations.php:46 +msgid "Countries" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:142 +#: inc/taxonomies/class-taxonomy-state.php:91 +#: inc/taxonomies/class-taxonomy-city.php:88 +#: inc/submission/class-metabox-property-submission.php:355 +msgid "Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:85 +msgid "Country image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:77 +msgid "Country Metabox" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:504 +msgid "Create an Account" +msgstr "" + +#: inc/mixes-functions.php:532 +msgid "Croatian kuna" +msgstr "" + +#: inc/mixes-functions.php:507 +msgid "Cuban convertible peso" +msgstr "" + +#: inc/mixes-functions.php:508 +msgid "Cuban peso" +msgstr "" + +#: inc/admin/settings/general.php:192 +msgid "Currency" +msgstr "" + +#: inc/admin/settings/general.php:200 +msgid "Currency Position" +msgstr "" + +#: inc/admin/settings/general.php:184 +msgid "Currency Settings" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:104 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:104 +msgid "Current Page" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:317 +#: inc/agent/class-opalestate-agent-front.php:219 +msgid "Currently, The data could not save!" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:533 +msgid "" +"Currently, your account was blocked, please keep contact admin to resolve " +"this!." +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:47 +msgid "Custom Icon Marker" +msgstr "" + +#: inc/mixes-functions.php:510 +msgid "Czech koruna" +msgstr "" + +#: inc/mixes-functions.php:512 +msgid "Danish krone" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:141 +msgid "Dark" +msgstr "" + +#: inc/user/functions.php:123 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:549 +msgid "Dashboard" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:105 +msgid "Data" +msgstr "" + +#: inc/admin/property/class-property.php:104 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:213 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:182 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:205 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:213 +msgid "Date" +msgstr "" + +#: inc/admin/functions.php:327 +msgid "Deactivate License" +msgstr "" + +#: inc/admin/settings/general.php:218 +msgid "Decimal Separator" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:169 +msgid "Default" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:501 +msgid "Default User" +msgstr "" + +#: templates/user-search/content-savedsearch.php:12 +msgid "Delete" +msgstr "" + +#: templates/user/content-property.php:91 +msgid "Delete Property" +msgstr "" + +#: templates/parts/mortgage-calculator.php:158 +#: templates/parts/mortgage-calculator.php:159 +#: templates/widgets/mortgage-calculator.php:145 +#: templates/widgets/mortgage-calculator.php:146 +msgid "Deposit" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:229 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:198 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:221 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:198 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:229 +msgid "DESC" +msgstr "" + +#: templates/content-single-property-v2.php:63 +#: templates/content-single-property-v5.php:16 +#: templates/content-property-list.php:51 +#: templates/content-single-agency.php:23 +#: templates/content-single-agency.php:44 templates/content-single-agent.php:16 +#: inc/rating/class-opalestate-rating-metabox.php:110 +#: inc/submission/class-metabox-property-submission.php:109 +#: templates/single-property/content.php:2 +msgid "Description" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:309 +msgid "Direction" +msgstr "" + +#: inc/class-opalestate-email.php:317 +#: inc/submission/class-opalestate-submission.php:180 +#: inc/submission/class-opalestate-submission.php:190 +#: inc/submission/class-opalestate-submission.php:200 +#: inc/submission/class-opalestate-submission.php:210 +#: inc/submission/class-opalestate-submission.php:220 +#: inc/submission/class-opalestate-submission.php:230 +#: inc/submission/class-opalestate-submission.php:240 +#: inc/vendors/social-login/class-opalestate-social-login.php:70 +#: inc/vendors/social-login/class-opalestate-social-login.php:107 +#: inc/admin/settings/property.php:71 inc/admin/settings/property.php:82 +#: inc/admin/settings/property.php:127 inc/admin/settings/property.php:138 +#: inc/admin/settings/property.php:174 inc/admin/settings/property.php:236 +#: inc/admin/settings/property.php:247 inc/admin/settings/property.php:266 +#: inc/admin/settings/property.php:277 inc/admin/settings/property.php:301 +#: inc/admin/settings/property.php:312 inc/admin/settings/property.php:323 +#: inc/admin/settings/property.php:334 inc/admin/settings/property.php:345 +#: inc/admin/settings/property.php:356 inc/admin/settings/property.php:367 +#: inc/admin/settings/property.php:378 inc/admin/settings/property.php:389 +#: inc/admin/settings/property.php:400 inc/admin/settings/general.php:72 +#: inc/admin/rating/class-rating.php:70 inc/admin/rating/class-rating.php:80 +#: inc/admin/rating/class-rating.php:90 +msgid "Disable" +msgstr "" + +#: inc/widgets/search-properties.php:83 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:109 +msgid "Disable Labels" +msgstr "" + +#: inc/admin/settings/property.php:224 +msgid "Disable or enable fields appearing in search form" +msgstr "" + +#: inc/widgets/search-properties.php:92 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:118 +msgid "Disable Search button" +msgstr "" + +#: inc/admin/class-user.php:170 +msgid "Disable Submssion Functions to not allow submit property" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:136 +msgid "Display captcha box with color style." +msgstr "" + +#: inc/widgets/search-properties.php:119 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:149 +msgid "Display City select" +msgstr "" + +#: inc/widgets/search-properties.php:101 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:126 +msgid "Display Country select" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:160 +msgid "Display More Options" +msgstr "" + +#: inc/widgets/profile-info.php:24 +msgid "Display Profile information in box and menu." +msgstr "" + +#: inc/admin/settings/property.php:77 inc/admin/settings/property.php:99 +#: inc/admin/settings/property.php:122 inc/admin/settings/property.php:133 +msgid "Display Save Search Link Management" +msgstr "" + +#: inc/widgets/search-properties.php:110 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:138 +msgid "Display State select" +msgstr "" + +#: inc/mixes-functions.php:511 +msgid "Djiboutian franc" +msgstr "" + +#: inc/classes/class-opalestate-cache.php:170 +msgid "Do not pass empty action to generate cache key." +msgstr "" + +#: inc/classes/class-opalestate-cache.php:203 +msgid "Do not pass invalid empty cache key" +msgstr "" + +#: inc/mixes-functions.php:513 +msgid "Dominican peso" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:201 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:400 +msgid "Dots" +msgstr "" + +#: inc/importer/class-import-steps.php:375 +msgid "Downloading:" +msgstr "" + +#: templates/user/share-search-form.php:39 +msgid "E-mail" +msgstr "" + +#: inc/mixes-functions.php:628 +msgid "East Caribbean dollar" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:57 +#: templates/user/content-property.php:82 +#: inc/vendors/opalmembership/membership.php:508 +msgid "Edit" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:44 +msgid "Edit Agency" +msgstr "" + +#: templates/user/agency/profile-agency.php:23 +msgid "Edit Agency Profile" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:37 +msgid "Edit Agent" +msgstr "" + +#: templates/user/agent/profile-agent.php:7 +msgid "Edit Agent Profile" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:40 +msgid "Edit Amenity" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:80 +msgid "Edit Category" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:41 +msgid "Edit City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:42 +msgid "Edit Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:43 +msgid "Edit Label" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:78 +msgid "Edit Level" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:267 +msgid "Edit My Property" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:72 +msgid "Edit Neighborhood" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:43 +#: templates/shortcodes/submission-form.php:32 +#: templates/submission/submission-form.php:19 +msgid "Edit Property" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:58 +msgid "Edit rating feature" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:40 +msgid "Edit State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:43 +msgid "Edit Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:81 +msgid "Edit Type" +msgstr "" + +#: templates/user/profile.php:22 +msgid "Edit User Profile" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:228 +msgid "Education" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:282 +msgid "Effect" +msgstr "" + +#: inc/mixes-functions.php:515 +msgid "Egyptian pound" +msgstr "" + +#: inc/class-opalestate-email.php:152 +#: inc/classes/class-opalestate-metabox-user.php:178 +#: inc/agency/class-opalestate-agency-metabox.php:351 +#: inc/message/class-opalestate-message.php:525 +#: inc/message/class-opalestate-message.php:626 +#: inc/agent/class-opalestate-agent-metabox.php:177 +#: templates/rating/opalestate-ratings.php:237 +msgid "Email" +msgstr "" + +#: templates/user/register-form.php:50 +msgid "Email address" +msgstr "" + +#: inc/class-opalestate-email.php:297 inc/class-opalestate-email.php:336 +#: inc/class-opalestate-email.php:364 +msgid "Email Body" +msgstr "" + +#: inc/class-opalestate-email.php:344 +msgid "Email Contact Templates (Template Tags)" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:172 +msgid "Email is required." +msgstr "" + +#: inc/message/class-opalestate-message.php:229 +msgid "Email Sent successful" +msgstr "" + +#: inc/class-opalestate-email.php:240 inc/class-opalestate-email.php:244 +#: inc/submission/class-opalestate-submission.php:121 +msgid "Email Settings" +msgstr "" + +#: inc/class-opalestate-email.php:285 inc/class-opalestate-email.php:324 +#: inc/class-opalestate-email.php:352 +msgid "Email Subject" +msgstr "" + +#: inc/class-opalestate-email.php:267 +msgid "Email Submission Templates (Template Tags)" +msgstr "" + +#: templates/single-property/sharebox.php:72 +msgid "Email to a Friend" +msgstr "" + +#: inc/class-opalestate-email.php:259 +msgid "" +"Email to send donation receipts from. This will act as the \"from\" and " +"\"reply-to\" address." +msgstr "" + +#: inc/class-opalestate-email.php:316 +#: inc/submission/class-opalestate-submission.php:179 +#: inc/submission/class-opalestate-submission.php:189 +#: inc/submission/class-opalestate-submission.php:199 +#: inc/submission/class-opalestate-submission.php:209 +#: inc/submission/class-opalestate-submission.php:219 +#: inc/submission/class-opalestate-submission.php:229 +#: inc/submission/class-opalestate-submission.php:239 +#: inc/vendors/social-login/class-opalestate-social-login.php:69 +#: inc/vendors/social-login/class-opalestate-social-login.php:106 +#: inc/admin/settings/property.php:70 inc/admin/settings/property.php:81 +#: inc/admin/settings/property.php:126 inc/admin/settings/property.php:137 +#: inc/admin/settings/property.php:175 inc/admin/settings/property.php:237 +#: inc/admin/settings/property.php:248 inc/admin/settings/property.php:267 +#: inc/admin/settings/property.php:278 inc/admin/settings/property.php:300 +#: inc/admin/settings/property.php:311 inc/admin/settings/property.php:322 +#: inc/admin/settings/property.php:333 inc/admin/settings/property.php:344 +#: inc/admin/settings/property.php:355 inc/admin/settings/property.php:366 +#: inc/admin/settings/property.php:377 inc/admin/settings/property.php:388 +#: inc/admin/settings/property.php:399 inc/admin/settings/general.php:71 +#: inc/admin/rating/class-rating.php:69 inc/admin/rating/class-rating.php:79 +#: inc/admin/rating/class-rating.php:89 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:171 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:171 +msgid "Enable" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:154 +msgid "Enable Admin Approve" +msgstr "" + +#: inc/admin/rating/class-rating.php:74 inc/admin/rating/class-rating.php:75 +msgid "Enable agency reviews" +msgstr "" + +#: inc/admin/rating/class-rating.php:84 inc/admin/rating/class-rating.php:85 +msgid "Enable agent reviews" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:204 +#: inc/submission/class-opalestate-submission.php:205 +msgid "Enable Amenities tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:224 +#: inc/submission/class-opalestate-submission.php:225 +msgid "Enable Apartments tab" +msgstr "" + +#: inc/class-opalestate-email.php:311 +msgid "Enable approve property email" +msgstr "" + +#: inc/class-opalestate-email.php:312 +msgid "Enable approve property email." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:140 +msgid "Enable Avatar" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:138 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:161 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:152 +msgid "Enable Carousel" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:101 +#: inc/vendors/social-login/class-opalestate-social-login.php:102 +msgid "Enable Facebook login" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:214 +#: inc/submission/class-opalestate-submission.php:215 +msgid "Enable Facilities tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:234 +#: inc/submission/class-opalestate-submission.php:235 +msgid "Enable Floor plans tab" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:29 +msgid "Enable Free Submission" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:102 +msgid "" +"Enable google captch in contact , register form. After Set yes, you change " +"setting in Google Captcha Tab. Register here: https://www.google." +"com/recaptcha/admin Version 2" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:64 +#: inc/vendors/social-login/class-opalestate-social-login.php:65 +msgid "Enable Google login" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:396 +msgid "Enable Google Map" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:194 +#: inc/submission/class-opalestate-submission.php:195 +msgid "Enable Information tab" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:112 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:166 +msgid "Enable Label" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:184 +#: inc/submission/class-opalestate-submission.php:185 +msgid "Enable Location tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:174 +#: inc/submission/class-opalestate-submission.php:175 +msgid "Enable Media tab" +msgstr "" + +#: inc/admin/settings/general.php:66 +msgid "Enable Message Database" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:149 +msgid "Enable Notification" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:161 +msgid "Enable or Disable require user enter price and price label." +msgstr "" + +#: inc/admin/rating/class-rating.php:64 inc/admin/rating/class-rating.php:65 +msgid "Enable property reviews" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:160 +msgid "Enable Require Price" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:114 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:114 +msgid "Enable Sortable Bar" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:99 +msgid "Enable Static Map" +msgstr "" + +#: inc/admin/settings/property.php:66 +msgid "Enable to allow user post/submit properties in front-end" +msgstr "" + +#: inc/admin/settings/property.php:65 +msgid "Enable User Submission" +msgstr "" + +#: templates/messages/enquiry-form.php:7 +msgid "Enquire about property" +msgstr "" + +#: templates/parts/search-agency-form.php:20 +msgid "Enter Agency Name" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:250 +#: inc/property/class-metabox-property-admin.php:258 +#: inc/submission/class-metabox-property-submission.php:120 +#: inc/submission/class-metabox-property-submission.php:128 +msgid "Enter amount without currency" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:251 +msgid "Enter an username or e-mail address." +msgstr "" + +#: inc/property/class-metabox-property-admin.php:301 +#: inc/submission/class-metabox-property-submission.php:241 +msgid "Enter built year" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:153 +msgid "" +"Enter contact name that allow user contact you via the contact form of " +"website." +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:61 +#: inc/agent/class-opalestate-agent-metabox.php:128 +msgid "Enter max price of property which is for sale/rent..." +msgstr "" + +#: inc/admin/settings/property.php:213 +msgid "Enter maximum of area for starting search" +msgstr "" + +#: inc/admin/settings/property.php:191 +msgid "Enter maximum of price for starting search" +msgstr "" + +#: inc/admin/settings/general.php:166 +msgid "Enter maximum of price for starting search agent by target" +msgstr "" + +#: inc/admin/settings/property.php:158 +msgid "Enter min of properties display in search page" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:54 +#: inc/agent/class-opalestate-agent-metabox.php:121 +msgid "Enter min price of property which is for sale/rent..." +msgstr "" + +#: inc/admin/settings/general.php:156 +msgid "Enter minimum of price for starting search agent by target" +msgstr "" + +#: inc/admin/settings/property.php:203 +msgid "Enter minimum of area for starting search" +msgstr "" + +#: inc/admin/settings/property.php:181 +msgid "Enter minimum of price for starting search" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:388 +#: inc/submission/class-metabox-property-submission.php:341 +msgid "Enter Number of Amount Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:337 +#: inc/submission/class-metabox-property-submission.php:279 +msgid "Enter number of bathrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:327 +#: inc/submission/class-metabox-property-submission.php:267 +msgid "Enter number of bedrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:377 +#: inc/submission/class-metabox-property-submission.php:328 +msgid "Enter Number of Kitchens" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:366 +#: inc/submission/class-metabox-property-submission.php:315 +msgid "Enter Number of Living Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:316 +#: inc/submission/class-metabox-property-submission.php:255 +msgid "Enter number of Parking" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:355 +#: inc/submission/class-metabox-property-submission.php:303 +msgid "Enter Orientation of property" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:349 +#: inc/submission/class-metabox-property-submission.php:297 +msgid "Enter size of area in sqft" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:343 +#: inc/submission/class-metabox-property-submission.php:285 +msgid "Enter size of Plot as 20x30, 20x30x40, 20x30x40x50" +msgstr "" + +#: inc/class-opalestate-email.php:338 +msgid "" +"Enter the email a user should receive when they make an initial payment " +"request." +msgstr "" + +#: inc/class-opalestate-email.php:299 +msgid "" +"Enter the email an admin should receive when an initial payment request is " +"made." +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:47 +msgid "Enter User ID to show information without using user info" +msgstr "" + +#: inc/class-opalestate-html.php:41 +msgid "Enter username" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:182 +msgid "Enter your facebook profile or facebook newfeed" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:160 +msgid "Enter your home phone." +msgstr "" + +#: inc/mixes-functions.php:516 +msgid "Eritrean nakfa" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:46 +#: inc/user/class-opalestate-user-form-handler.php:51 +#: inc/user/class-opalestate-user-form-handler.php:60 +#: inc/user/class-opalestate-user-form-handler.php:70 +#: inc/user/class-opalestate-user-form-handler.php:160 +#: inc/user/class-opalestate-user-form-handler.php:165 +#: inc/user/class-opalestate-user-form-handler.php:172 +#: inc/user/class-opalestate-user-form-handler.php:179 +#: inc/user/class-opalestate-user-form-handler.php:182 +#: inc/user/class-opalestate-user-form-handler.php:191 +msgid "ERROR" +msgstr "" + +#: inc/api/class-opalestate-api.php:1097 inc/api/class-opalestate-api.php:1102 +#: inc/api/class-opalestate-api.php:1120 inc/api/class-opalestate-api.php:1130 +msgid "Error" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/featured-properties.php:22 +msgid "Estate: Featured Properties" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/mortgage-calculator.php:25 +msgid "Estate: Mortgage Calculator" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/sameprice-properties.php:22 +msgid "Estate: Same Price" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/search-properties.php:23 +msgid "Estate: Search Properties" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/similar-properties.php:22 +msgid "Estate: Similar Properties" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/profile-info.php:22 +msgid "Estate: User Menu Profile" +msgstr "" + +#: inc/mixes-functions.php:517 +msgid "Ethiopian birr" +msgstr "" + +#: inc/mixes-functions.php:518 +msgid "Euro" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:232 +msgid "Event Planning & Services" +msgstr "" + +#: templates/user/my-properties.php:6 +#: inc/vendors/opalmembership/membership.php:594 +#: inc/vendors/opalmembership/membership.php:603 +msgid "Expired" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:219 +#: inc/agency/class-opalestate-agency-metabox.php:180 +#: inc/vendors/social-login/class-opalestate-social-login.php:93 +#: templates/user/social-login/facebook-button.php:19 +msgid "Facebook" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:112 +msgid "Facebook Application ID" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:113 +msgid "Facebook Application ID is required for Facebook login." +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:118 +msgid "Facebook Secret" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:119 +msgid "Facebook Secret is required for Facebook login." +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:66 +msgid "Facilities" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:68 +msgid "Facility" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:420 +#: inc/submission/class-metabox-property-submission.php:453 +msgid "Facility {#}" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:287 +msgid "Fade" +msgstr "" + +#: inc/mixes-functions.php:520 +msgid "Falkland Islands pound" +msgstr "" + +#: inc/user/functions.php:137 +msgid "Favorite" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:201 +#: inc/agency/class-opalestate-agency-metabox.php:374 +#: inc/agent/class-opalestate-agent-metabox.php:200 +msgid "Fax" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:52 +msgctxt "Feature plural name" +msgid "Rating Features" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:53 +msgctxt "Feature singular name" +msgid "Rating Feature" +msgstr "" + +#: templates/content-agent-list.php:14 templates/content-agent-grid.php:15 +#: templates/content-agent-grid-v2.php:13 templates/content-agency-grid.php:15 +#: templates/content-agency-list.php:15 +#: inc/property/class-metabox-property-admin.php:177 +#: templates/single-agent/author-box.php:15 +#: templates/user/content-property.php:22 +#: templates/single-agency/author-box.php:22 +#: templates/parts/featured-label.php:5 +#: inc/admin/property/class-property.php:99 +msgid "Featured" +msgstr "" + +#: templates/content-agency-grid.php:14 templates/content-agency-list.php:14 +#: templates/single-agency/author-box.php:21 +#: templates/single-agency/author-box.php:21 +msgid "Featured Agency" +msgstr "" + +#: templates/content-agent-list.php:12 templates/content-agent-grid.php:13 +#: templates/content-agent-grid-v2.php:11 +#: templates/single-agent/author-box.php:13 +msgid "Featured Agent" +msgstr "" + +#: inc/template-functions.php:226 +msgid "Featured Desending" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:183 +msgid "Featured Image" +msgstr "" + +#: inc/admin/settings/general.php:145 +msgid "Featured Image Size" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:152 +msgid "Featured only" +msgstr "" + +#: inc/widgets/featured-properties.php:52 +#: templates/single-agent/featured-properties.php:20 +#: templates/user/dashboard.php:17 +msgid "Featured Properties" +msgstr "" + +#: inc/widgets/featured-properties.php:24 +msgid "Featured Properties widget." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:501 +msgid "Featured Remaining:" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:100 +msgid "Field" +msgstr "" + +#: inc/mixes-functions.php:519 +msgid "Fijian dollar" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:65 +msgid "Filter rating features" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:236 +msgid "Financial Services" +msgstr "" + +#: templates/archive-opalestate_agency.php:12 +msgid "Find A Local Real Estate Agencies" +msgstr "" + +#: templates/elementor-templates/opalestate-office-agent-search.php:19 +msgid "Find An Agency" +msgstr "" + +#: templates/elementor-templates/opalestate-office-agent-search.php:14 +msgid "Find An Agent" +msgstr "" + +#: templates/parts/search-agents-form-address.php:20 +#: templates/parts/search-agents-form.php:20 +#: templates/parts/search-agency-form-address.php:20 +msgid "Find an experienced agent with:" +msgstr "" + +#: templates/archive-opalestate_agent.php:12 +msgid "Find The Best Real Estate Agent For Your" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:33 +#: inc/agency/class-opalestate-agency-metabox.php:110 +msgid "First Name" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:651 +#: inc/submission/class-metabox-property-submission.php:504 +#: templates/single-property/apartments.php:25 +msgid "Floor" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:76 +msgid "Floor Plan" +msgstr "" + +#: templates/content-single-property-v2.php:65 +#: templates/content-single-property-v5.php:33 +#: inc/submission/class-metabox-property-submission.php:548 +#: templates/single-property/floor-plans.php:15 +msgid "Floor Plans" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:68 +msgid "Floor plans" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:610 +#: inc/submission/class-metabox-property-submission.php:608 +msgid "Floor {#}" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:240 +msgid "Food" +msgstr "" + +#. %s: property +#: inc/api/class-opalestate-api.php:678 inc/api/class-opalestate-api.php:769 +#: inc/api/class-opalestate-api.php:821 +#, php-format +msgid "Form %s not found!" +msgstr "" + +#: templates/archive-opalestate_agency.php:39 +#: templates/elementor-templates/opalestate-agency-collection.php:26 +#, php-format +msgid "Found %s Agency" +msgstr "" + +#: templates/archive-opalestate_agent.php:39 +#: templates/elementor-templates/opalestate-agent-collection.php:29 +#: templates/shortcodes/search-agents.php:15 +#, php-format +msgid "Found %s Agents" +msgstr "" + +#: templates/shortcodes/search-properties-result.php:22 +#: templates/shortcodes/ajax-map-search-result.php:14 +#: templates/parts/archive-simple-bars.php:6 +#, php-format +msgid "Found %s Properties" +msgstr "" + +#: inc/user/class-opalestate-user.php:362 +msgid "Found a problem while updating" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:90 +msgid "Free membership" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:22 +msgid "Free Submission" +msgstr "" + +#: templates/user/share-search-form.php:31 +msgid "Friend Email" +msgstr "" + +#: inc/class-opalestate-email.php:258 +msgid "From Email" +msgstr "" + +#: inc/class-opalestate-email.php:251 +msgid "From Name" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:91 +#: inc/agency/class-opalestate-agency-metabox.php:344 +#: templates/single-agency/gallery.php:6 inc/admin/agency/class-agency.php:72 +#: templates/single-property/preview/tabs.php:15 +msgid "Gallery" +msgstr "" + +#: inc/template-functions.php:470 +msgid "Gallery Metro" +msgstr "" + +#: inc/template-functions.php:464 +msgid "Gallery Slider" +msgstr "" + +#: inc/template-functions.php:463 +msgid "Gallery Thumb Nav" +msgstr "" + +#: inc/mixes-functions.php:526 +msgid "Gambian dalasi" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:47 +#: inc/admin/register-settings.php:110 inc/admin/class-user.php:105 +#: inc/submission/class-metabox-property-submission.php:60 +#: inc/admin/settings/property.php:26 inc/admin/agency/class-agency.php:129 +#: inc/admin/agent/class-agent.php:80 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:212 +msgid "General" +msgstr "" + +#: inc/admin/settings/email.php:28 inc/admin/settings/general.php:28 +#: inc/admin/settings/general.php:43 +msgid "General Settings" +msgstr "" + +#: inc/api/class-opalestate-api.php:1062 +msgid "Generate API Key" +msgstr "" + +#: inc/admin/class-api-keys-table.php:235 +msgid "Generate New API Keys" +msgstr "" + +#: inc/mixes-functions.php:522 +msgid "Georgian lari" +msgstr "" + +#: inc/mixes-functions.php:524 +msgid "Ghana cedi" +msgstr "" + +#: inc/mixes-functions.php:525 +msgid "Gibraltar pound" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:105 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:105 +msgid "Global Agent Search Page" +msgstr "" + +#: inc/admin/functions.php:198 +msgid "Global Default" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:201 +#, php-format +msgid "" +"Go to the Menus screen to manage your " +"menus." +msgstr "" + +#: templates/rating/opalestate-ratings.php:251 +#: templates/rating/opalestate-ratings.php:263 +msgid "Good" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:225 +#: inc/vendors/social-login/class-opalestate-social-login.php:57 +#: templates/user/social-login/google-button.php:19 +msgid "Google" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:87 +msgid "Google API key" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:88 +msgid "Google API key is required for Google Login." +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:154 +msgid "Google Captcha" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:114 +msgid "Google Captcha page Settings" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:75 +msgid "Google Client ID" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:76 +msgid "Google Client ID is required for Google Login." +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:81 +msgid "Google Client Secret" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:82 +msgid "Google Client Secret is required for Google Login." +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:400 +msgid "Google Map" +msgstr "" + +#: inc/admin/settings/general.php:248 +msgid "Google Map API" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:207 +#: inc/submission/class-metabox-property-submission.php:389 +msgid "Google Map View" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:207 +msgid "Google Plus Url" +msgstr "" + +#: inc/template-functions.php:264 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:126 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:117 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:117 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:101 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:126 +msgid "Grid" +msgstr "" + +#: inc/mixes-functions.php:528 +msgid "Guatemalan quetzal" +msgstr "" + +#: inc/mixes-functions.php:523 +msgid "Guernsey pound" +msgstr "" + +#: inc/mixes-functions.php:527 +msgid "Guinean franc" +msgstr "" + +#: inc/mixes-functions.php:529 +msgid "Guyanese dollar" +msgstr "" + +#: inc/mixes-functions.php:533 +msgid "Haitian gourde" +msgstr "" + +#: templates/content-single-agency.php:71 +msgid "Head Agency:" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:244 +msgid "Health & Medical" +msgstr "" + +#: templates/user/share-search-form.php:8 +#: templates/user-search/render-form.php:8 +#, php-format +msgid "" +"Hey there! I saved this search on %s, please check out these homes that are " +"listed. Remember to save this search to be first to catch any new listings." +msgstr "" + +#: templates/content-single-agency.php:141 +#, php-format +msgid "Hi %s. I saw your profile and wanted to see if you could help me." +msgstr "" + +#: templates/parts/has-warning.php:3 +msgid "" +"Hi! you could not edit/create a property at this time, you have not " +"permission to do." +msgstr "" + +#: templates/messages/enquiry-form.php:4 +#, php-format +msgid "Hi, I am interested in %s (Property ID: %s)" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:440 +msgid "Hide Author Information" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:248 +msgid "Home Services " +msgstr "" + +#: inc/mixes-functions.php:531 +msgid "Honduran lempira" +msgstr "" + +#: inc/mixes-functions.php:530 +msgid "Hong Kong dollar" +msgstr "" + +#: inc/admin/settings/property.php:223 +msgid "Horizontal Search Fields" +msgstr "" + +#: templates/single-property/map.php:47 templates/single-property/map-v2.php:49 +#: templates/single-property/preview/tabs.php:41 +#: templates/single-property/preview/map.php:17 +msgid "Hospital" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:252 +msgid "Hotels & Travel" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:383 +msgid "Hover" +msgstr "" + +#. Author URI of the plugin +msgid "http://www.wpopal.com" +msgstr "" + +#. URI of the plugin +msgid "http://www.wpopal.com/product/opal-estate-wordpress-plugin/" +msgstr "" + +#: inc/mixes-functions.php:534 +msgid "Hungarian forint" +msgstr "" + +#: templates/user/register-form.php:80 +msgid "I agree with" +msgstr "" + +#: inc/mixes-functions.php:541 +msgid "Icelandic króna" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:49 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:284 +msgid "Icon" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:300 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:390 +msgid "Icon Color" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:328 +msgid "Icon Font Size" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:183 +msgid "ID" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:84 +#: inc/taxonomies/class-taxonomy-categories.php:76 +#: inc/taxonomies/class-taxonomy-state.php:79 +#: inc/taxonomies/class-taxonomy-city.php:76 +#: inc/taxonomies/class-taxonomy-types.php:58 +msgid "Image" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:74 +msgid "Image Icon" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:94 +msgid "Image Logo" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:597 +#: inc/submission/class-metabox-property-submission.php:593 +msgid "Image Preview" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:95 +#: inc/submission/class-metabox-property-submission.php:194 +msgid "Images Gallery" +msgstr "" + +#: inc/importer/class-import-steps.php:857 +msgid "" +"Import all setting, options, other contents, please waiting for a while!" +msgstr "" + +#: inc/importer/class-import-steps.php:757 +msgid "Import all settings for theme, please waiting for a while!" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:252 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:221 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:244 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:252 +msgid "IN" +msgstr "" + +#: inc/classes/class-opalestate-cache.php:150 +#, php-format +msgid "" +"In order for database caching to work with Give you must " +"add %1$s to the \"Ignored query stems\" option in W3 Total " +"Cache settings." +msgstr "" + +#: templates/user/read-messages.php:7 +msgid "Inbox" +msgstr "" + +#: inc/mixes-functions.php:538 +msgid "Indian rupee" +msgstr "" + +#: inc/mixes-functions.php:535 +msgid "Indonesian rupiah" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:268 +msgid "Infinite Loop" +msgstr "" + +#: templates/content-single-property-v2.php:64 +#: inc/property/class-metabox-property-admin.php:61 +#: inc/agency/class-opalestate-agency-metabox.php:140 +#: inc/agency/class-opalestate-agency-metabox.php:266 +#: inc/agent/class-opalestate-agent-metabox.php:100 +#: inc/submission/class-metabox-property-submission.php:64 +msgid "Information" +msgstr "" + +#: inc/template-functions.php:462 +#: inc/property/class-metabox-property-admin.php:536 +#: inc/admin/settings/general.php:179 +msgid "Inherit" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:209 +msgid "Input for goolge plus profile or your newfeed." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:196 +msgid "Input for instagram profile." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:190 +msgid "Input for linked in profile." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:202 +msgid "Input for pinterest feed" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:167 +msgid "Input for skype account." +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:53 +#: inc/property/class-metabox-property-admin.php:230 +#: inc/agency/class-opalestate-agency-metabox.php:131 +#: inc/submission/class-metabox-property-submission.php:205 +msgid "" +"Input for videos, audios from Youtube, Vimeo and all supported sites by " +"WordPress. It has preview feature." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:223 +msgid "Input for your channel Vimeo" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:216 +msgid "Input for your channel youtube." +msgstr "" + +#: inc/property/class-metabox-property-admin.php:117 +#: inc/property/class-metabox-property-admin.php:606 +#: inc/submission/class-metabox-property-submission.php:211 +#: inc/submission/class-metabox-property-submission.php:604 +msgid "Input iframe to show 360° Virtual Tour." +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:354 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:417 +msgid "Inside" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:242 +msgid "Instagram" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:194 +msgid "Instagram URL" +msgstr "" + +#: inc/importer/class-import-steps.php:67 +#: inc/importer/class-import-steps.php:68 +#: inc/importer/class-import-steps.php:69 +#: inc/importer/class-import-steps.php:70 +#: inc/importer/class-import-steps.php:71 +#: inc/importer/class-import-steps.php:72 +#: inc/importer/class-import-steps.php:73 +#: inc/importer/class-import-steps.php:74 +#: inc/importer/class-import-steps.php:75 +msgid "Install required plugins " +msgstr "" + +#: inc/api/class-opalestate-api.php:457 +msgid "Invalid API key!" +msgstr "" + +#: inc/api/class-opalestate-api.php:473 +msgid "Invalid API version!" +msgstr "" + +#: inc/importer/class-content-importer.php:466 +msgid "Invalid file type" +msgstr "" + +#: inc/api/class-opalestate-api.php:601 +msgid "Invalid query!" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:266 +msgid "Invalid username or e-mail address." +msgstr "" + +#: inc/mixes-functions.php:540 +msgid "Iranian rial" +msgstr "" + +#: inc/mixes-functions.php:539 +msgid "Iraqi dinar" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:148 +#: inc/agency/class-opalestate-agency-metabox.php:57 +msgid "Is Featured" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:274 +msgid "Is Price On Call" +msgstr "" + +#: inc/mixes-functions.php:536 +msgid "Israeli new shekel" +msgstr "" + +#: inc/importer/class-import-steps.php:259 +msgid "It is getting data from live server for comming installation!" +msgstr "" + +#: templates/content-no-results.php:6 +msgid "" +"It seems we can’t find what you’re looking for. Perhaps " +"searching can help." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:122 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:113 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:113 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:97 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:122 +msgid "Item Layout" +msgstr "" + +#: inc/mixes-functions.php:543 +msgid "Jamaican dollar" +msgstr "" + +#: inc/mixes-functions.php:545 +msgid "Japanese yen" +msgstr "" + +#: inc/mixes-functions.php:542 +msgid "Jersey pound" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:126 +msgid "Job" +msgstr "" + +#: inc/mixes-functions.php:544 +msgid "Jordanian dinar" +msgstr "" + +#: inc/mixes-functions.php:554 +msgid "Kazakhstani tenge" +msgstr "" + +#: inc/mixes-functions.php:546 +msgid "Kenyan shilling" +msgstr "" + +#: templates/parts/search-form-v.php:39 +#: templates/search-box/fields/search-text.php:1 +msgid "Keyword" +msgstr "" + +#: inc/admin/settings/3rd_party.php:130 +msgid "kilometers" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:370 +#: inc/submission/class-metabox-property-submission.php:319 +msgid "Kitchens" +msgstr "" + +#: inc/template-functions.php:704 +msgid "km" +msgstr "" + +#: inc/mixes-functions.php:552 +msgid "Kuwaiti dinar" +msgstr "" + +#: inc/mixes-functions.php:547 +msgid "Kyrgyzstani som" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:410 +#: inc/taxonomies/class-taxonomy-labels.php:37 +#: inc/taxonomies/class-taxonomy-labels.php:47 +#: inc/submission/class-metabox-property-submission.php:443 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:171 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:249 +msgid "Label" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:120 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:174 +msgid "Label Text" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:244 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:267 +msgid "Lables" +msgstr "" + +#: inc/mixes-functions.php:555 +msgid "Lao kip" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:43 +#: inc/agency/class-opalestate-agency-metabox.php:120 +msgid "Last Name" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:54 +msgid "Latitude" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:156 +#: inc/widgets/search-properties.php:74 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:99 +msgid "Layout" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:533 +msgid "Layout Display" +msgstr "" + +#. %s is property title +#: templates/rating/opalestate-ratings.php:230 +#, php-format +msgid "Leave a Reply to %s" +msgstr "" + +#: inc/mixes-functions.php:556 +msgid "Lebanese pound" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:313 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:349 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:361 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:384 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:224 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:349 +msgid "Left" +msgstr "" + +#: inc/mixes-functions.php:559 +msgid "Lesotho loti" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:73 +msgid "Level" +msgstr "" + +#: inc/mixes-functions.php:558 +msgid "Liberian dollar" +msgstr "" + +#: templates/single-property/map.php:53 templates/single-property/map-v2.php:55 +#: templates/single-property/preview/tabs.php:47 +#: templates/single-property/preview/map.php:23 +msgid "Library" +msgstr "" + +#: inc/mixes-functions.php:560 +msgid "Libyan dinar" +msgstr "" + +#: inc/admin/register-settings.php:119 +msgid "Licenses" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:140 +msgid "Light" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:216 +msgid "Limit" +msgstr "" + +#: inc/widgets/featured-properties.php:62 +#: inc/widgets/sameprice-properties.php:63 +#: inc/widgets/similar-properties.php:61 +msgid "Limit:" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:673 +#: inc/submission/class-metabox-property-submission.php:525 +msgid "Link" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:45 +msgid "Link to User" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:30 +msgid "Link To User ID" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:174 +msgid "Link to your website" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:231 +msgid "LinkedIn" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:188 +msgid "Linkedin URL" +msgstr "" + +#: inc/template-functions.php:268 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:127 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:118 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:118 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:102 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:127 +msgid "List" +msgstr "" + +#: templates/content-single-agency.php:26 +msgid "Listing" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:500 +msgid "Listings Remaining:" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:359 +#: inc/submission/class-metabox-property-submission.php:306 +msgid "Living Rooms" +msgstr "" + +#: templates/single-agency/properties.php:27 +msgid "Load More" +msgstr "" + +#: templates/elementor-templates/opalestate-split-maps-search.php:12 +msgid "Loading map..." +msgstr "" + +#: templates/parts/mortgage-calculator.php:23 +#: templates/parts/mortgage-calculator.php:132 +#: templates/widgets/mortgage-calculator.php:23 +#: templates/widgets/mortgage-calculator.php:126 +msgid "Loan Amount" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:256 +msgid "Local Flavor" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:260 +msgid "Local Services" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:79 +#: inc/property/class-metabox-property-admin.php:194 +#: inc/submission/class-metabox-property-submission.php:63 +#: templates/parts/search-form-v.php:50 +#: templates/search-box/search-form-v3.php:28 +#: templates/search-box/fields/search-city-text.php:23 +#: templates/search-box/fields/location.php:1 +#: templates/search-box/fields/location.php:2 +msgid "Location" +msgstr "" + +#: templates/content-single-agency.php:76 templates/content-single-agent.php:84 +msgid "Location:" +msgstr "" + +#: inc/user/functions.php:196 +msgid "Log out" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:133 +msgid "Logged in" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:96 +msgid "Logged successfully, welcome back!" +msgstr "" + +#: templates/user/my-account-popup.php:4 templates/user/my-account.php:4 +#: templates/user/login-form.php:16 templates/user/login-form.php:51 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:531 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:532 +msgid "Login" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:46 +msgid "Login Form" +msgstr "" + +#: templates/submission/submission-completed.php:8 +#: templates/submission/require-login.php:8 +msgid "" +"Login in allowing you to edit your property or submit a property, save " +"favorite real estate." +msgstr "" + +#: templates/submission/submission-completed.php:9 +#: templates/submission/require-login.php:9 +msgid "Login Now" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:64 +msgid "Longitude" +msgstr "" + +#: inc/admin/settings/general.php:134 +msgid "Loop Image Size" +msgstr "" + +#: templates/user/login-form.php:52 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:542 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:542 +msgid "Lost your password?" +msgstr "" + +#: inc/admin/settings/general.php:243 +msgid "m2" +msgstr "" + +#: inc/mixes-functions.php:567 +msgid "Macanese pataca" +msgstr "" + +#: inc/mixes-functions.php:564 +msgid "Macedonian denar" +msgstr "" + +#: inc/mixes-functions.php:563 +msgid "Malagasy ariary" +msgstr "" + +#: inc/mixes-functions.php:571 +msgid "Malawian kwacha" +msgstr "" + +#: inc/mixes-functions.php:573 +msgid "Malaysian ringgit" +msgstr "" + +#: inc/mixes-functions.php:570 +msgid "Maldivian rufiyaa" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:109 +msgid "Manual Images 360 " +msgstr "" + +#: inc/mixes-functions.php:537 +msgid "Manx pound" +msgstr "" + +#: templates/content-single-property-v5.php:21 +#: templates/single-property/map.php:25 templates/single-property/map-v2.php:21 +#: templates/single-property/preview/tabs.php:17 +msgid "Map" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:46 +msgid "Map Address" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:144 +msgid "Map Height" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:112 +msgid "Map Location" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:108 +msgid "Map On Right?" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:80 +msgid "Map Preview Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:121 +msgid "Map Width %" +msgstr "" + +#: inc/template-functions.php:465 +msgid "Maps" +msgstr "" + +#: inc/template-functions.php:471 +msgid "Mark Picture" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:264 +msgid "Mass Media" +msgstr "" + +#: inc/mixes-functions.php:568 +msgid "Mauritanian ouguiya" +msgstr "" + +#: inc/mixes-functions.php:569 +msgid "Mauritian rupee" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:50 +msgid "Maximum number of Free Featured that users can set." +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:40 +msgid "Maximum number of Free Listing that users can submit." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:217 +msgid "Maximum number of terms to return." +msgstr "" + +#: inc/admin/settings/property.php:212 +msgid "Maximum of Search Aea" +msgstr "" + +#: inc/admin/settings/property.php:190 +msgid "Maximum of Search Price" +msgstr "" + +#: inc/admin/settings/general.php:165 +msgid "Maximum of Target Price For Agent" +msgstr "" + +#: inc/admin/settings/general.php:86 +msgid "Maximun Upload Image Files" +msgstr "" + +#: inc/admin/settings/general.php:78 +msgid "Maximun Upload Image Size" +msgstr "" + +#: inc/admin/settings/general.php:102 +msgid "Maximun Upload Other Files" +msgstr "" + +#: inc/admin/settings/general.php:94 +msgid "Maximun Upload Other Size" +msgstr "" + +#: inc/admin/settings/general.php:235 inc/admin/settings/general.php:236 +msgid "Measurement Unit" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:62 +msgid "Media" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:563 +msgid "Membership Information" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:546 +msgid "Membership Package" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:195 +msgid "Menu" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:215 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:184 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:207 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:215 +msgid "Menu Order" +msgstr "" + +#: inc/message/class-opalestate-message.php:542 +#: inc/message/class-opalestate-message.php:566 +#: inc/message/class-opalestate-message.php:643 +#: inc/message/class-opalestate-message.php:719 +#: templates/user/share-search-form.php:43 +msgid "Message" +msgstr "" + +#: inc/class-opalestate-email.php:117 inc/class-opalestate-email.php:120 +msgid "Message has been successfully sent." +msgstr "" + +#: inc/user/functions.php:159 +msgid "Messages" +msgstr "" + +#: templates/user/messages.php:9 +msgid "Messages for you" +msgstr "" + +#: inc/admin/class-user.php:87 inc/admin/agency/class-agency.php:110 +#: inc/admin/agent/class-agent.php:62 +msgid "Metabox" +msgstr "" + +#: inc/mixes-functions.php:572 +msgid "Mexican peso" +msgstr "" + +#: inc/template-functions.php:700 inc/admin/settings/3rd_party.php:129 +msgid "miles" +msgstr "" + +#: inc/admin/settings/property.php:202 +msgid "Minimum of Search Aea" +msgstr "" + +#: inc/admin/settings/property.php:180 +msgid "Minimum of Search Price" +msgstr "" + +#: inc/admin/settings/general.php:155 +msgid "Minimum of Target Price For Agent" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:195 +#: inc/agency/class-opalestate-agency-metabox.php:368 +#: inc/agent/class-opalestate-agent-metabox.php:194 +msgid "Mobile" +msgstr "" + +#: inc/mixes-functions.php:562 +msgid "Moldovan leu" +msgstr "" + +#: inc/mixes-functions.php:566 +msgid "Mongolian tögrög" +msgstr "" + +#: templates/parts/mortgage-calculator.php:129 +#: templates/widgets/mortgage-calculator.php:123 +msgid "month" +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:37 +msgid "More" +msgstr "" + +#: templates/single-property/walkscore.php:51 +msgid "More details here" +msgstr "" + +#: templates/single-property/walkscore.php:25 +#: templates/single-property/walkscore.php:38 +msgid "more details here" +msgstr "" + +#: templates/search-box/fields/more-options.php:19 +msgid "More Search Options" +msgstr "" + +#: inc/mixes-functions.php:561 +msgid "Moroccan dirham" +msgstr "" + +#: inc/widgets/mortgage-calculator.php:49 +msgid "Mortgage Calculator" +msgstr "" + +#: inc/widgets/mortgage-calculator.php:27 +msgid "Mortgage Calculator widget." +msgstr "" + +#: templates/parts/mortgage-calculator.php:102 +msgid "Mortgage Payment Calculator" +msgstr "" + +#: inc/mixes-functions.php:574 +msgid "Mozambican metical" +msgstr "" + +#: inc/admin/settings/general.php:242 +msgid "mq" +msgstr "" + +#: install.php:98 inc/user/class-opalestate-user.php:51 +msgid "My Account" +msgstr "" + +#: inc/admin/settings/general.php:59 +msgid "My Account Page" +msgstr "" + +#: templates/content-single-agent.php:75 +msgid "My Address" +msgstr "" + +#: templates/single-agency/properties.php:34 +msgid "My Agency has not any property yet." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:259 +msgid "My Invoices" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:252 +msgid "My Membership" +msgstr "" + +#: inc/widgets/profile-info.php:74 +msgid "My Profile" +msgstr "" + +#: inc/user/functions.php:174 inc/submission/class-opalestate-submission.php:97 +#: templates/single-agent/properties.php:11 templates/user/dashboard.php:10 +#: templates/single-agency/properties.php:16 +msgid "My Properties" +msgstr "" + +#: templates/user-search/content-savedsearch.php:9 +msgid "My Saved Searches" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:564 +#: inc/message/class-opalestate-message.php:516 +#: inc/message/class-opalestate-message.php:618 +#: inc/submission/class-metabox-property-submission.php:560 +#: templates/rating/opalestate-ratings.php:235 +#: templates/user/share-search-form.php:35 +#: templates/user-search/content-savedsearch.php:12 +#: templates/user-search/render-form.php:29 +#: templates/user/agency/agency-team.php:21 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:184 +msgid "Name" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:82 +#: inc/user/class-opalestate-user.php:432 +#: inc/user/class-opalestate-user.php:445 +#: inc/submission/class-metabox-property-submission.php:44 +msgid "Name and Description" +msgstr "" + +#: templates/user-search/render-form.php:21 +msgid "Name this search." +msgstr "" + +#: inc/mixes-functions.php:575 +msgid "Namibian dollar" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:195 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:329 +msgid "Navigation" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:66 +#: inc/taxonomies/class-taxonomy-neighborhood.php:76 +msgid "Neighborhoods" +msgstr "" + +#: inc/mixes-functions.php:579 +msgid "Nepalese rupee" +msgstr "" + +#: inc/mixes-functions.php:478 +msgid "Netherlands Antillean guilder" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:45 +msgid "New Agency" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:38 +msgid "New Agent" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:43 +msgid "New Amenity" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:83 +msgid "New Category Name" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:44 +msgid "New City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:45 +msgid "New Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:46 +msgid "New Label" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:81 +msgid "New Level Name" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:75 +msgid "New Neighborhood" +msgstr "" + +#: inc/user/class-opalestate-user.php:463 +msgid "New Password" +msgstr "" + +#: inc/user/class-opalestate-user.php:378 +msgid "New password is not same confirm password" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:44 +msgid "New Property" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:47 +msgid "New Property Category" +msgstr "" + +#: inc/email/class-opalesate-approve.php:31 +#: inc/email/class-opalestate-new-submitted.php:31 +#, php-format +msgid "New Property Listing Submitted: %s" +msgstr "" + +#: inc/class-opalestate-email.php:292 +msgid "New property submitted - {property_name}" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:59 +msgid "New rating feature" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:43 +msgid "New State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:46 +msgid "New Status" +msgstr "" + +#: inc/mixes-functions.php:616 +msgid "New Taiwan dollar" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:84 +msgid "New Type" +msgstr "" + +#: inc/mixes-functions.php:580 +msgid "New Zealand dollar" +msgstr "" + +#: inc/template-functions.php:325 +msgid "Next" +msgstr "" + +#: templates/archive-opalestate_agency.php:75 +#: templates/archive-opalestate_agent.php:65 +#: templates/archive-opalestate_property.php:53 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:332 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:344 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:367 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:332 +msgid "Next »" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:331 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:343 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:366 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:331 +msgid "Next Label" +msgstr "" + +#: templates/single-opalestate_agency.php:19 +msgid "Next page" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:162 +#: inc/submission/class-metabox-property-submission.php:226 +#: inc/submission/class-metabox-property-submission.php:343 +#: inc/submission/class-metabox-property-submission.php:405 +#: inc/submission/class-metabox-property-submission.php:421 +#: inc/submission/class-metabox-property-submission.php:439 +#: inc/submission/class-metabox-property-submission.php:482 +#: inc/submission/class-metabox-property-submission.php:674 +msgid "Next Step" +msgstr "" + +#: inc/mixes-functions.php:577 +msgid "Nicaraguan córdoba" +msgstr "" + +#: inc/mixes-functions.php:576 +msgid "Nigerian naira" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:268 +msgid "Nightlife" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:107 +#: inc/classes/class-opalestate-metabox-user.php:152 +#: inc/classes/class-opalestate-metabox-user.php:163 +#: inc/property/class-metabox-property-admin.php:181 +#: inc/property/class-metabox-property-admin.php:212 +#: inc/property/class-metabox-property-admin.php:278 +#: inc/property/class-metabox-property-admin.php:448 +#: inc/property/class-metabox-property-admin.php:458 +#: inc/agency/class-opalestate-agency-metabox.php:61 +#: inc/widgets/search-properties.php:147 +#: inc/submission/class-metabox-property-submission.php:393 +#: inc/submission/class-metabox-property-submission.php:473 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:235 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:249 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:273 +#: inc/vendors/opalmembership/free-package.php:35 +msgid "No" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:49 +msgid "No Agencies found" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:50 +msgid "No Agencies found in Trash" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:42 +msgid "No Agents found" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:43 +msgid "No Agents found in Trash" +msgstr "" + +#: templates/user-search/content-savedsearch.php:37 +msgid "No Item In Saved Searches" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:48 +msgid "No Properties found" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:49 +msgid "No Properties found in Trash" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:62 +msgid "No rating features found" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:63 +msgid "No rating features found in trash" +msgstr "" + +#: inc/admin/functions.php:563 +msgid "No users found" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:237 +msgid "" +"No, it is not unlimited, If not set it will be unlimited. Number of " +"properties can make featured with this package." +msgstr "" + +#: inc/api/class-opalestate-api.php:1097 +msgid "Nonce verification failed." +msgstr "" + +#: inc/class-opalestate-html.php:223 +#: inc/property/class-metabox-property-admin.php:665 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:202 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:280 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:292 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:315 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:280 +msgid "None" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:293 +msgid "Normal" +msgstr "" + +#: inc/mixes-functions.php:550 +msgid "North Korean won" +msgstr "" + +#: inc/mixes-functions.php:578 +msgid "Norwegian krone" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:253 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:222 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:245 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:253 +msgid "NOT IN" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:96 +msgid "Not logged in" +msgstr "" + +#: templates/rating/opalestate-ratings.php:253 +#: templates/rating/opalestate-ratings.php:265 +msgid "Not that bad" +msgstr "" + +#: templates/content-no-results.php:3 +msgid "Nothing Found" +msgstr "" + +#: inc/class-opalestate-email.php:276 +msgid "Notification For New Property Submission" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:49 +msgid "Number Free Featured" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:39 +msgid "Number Free Listing" +msgstr "" + +#: inc/admin/settings/general.php:225 +msgid "Number of Decimals" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:220 +#: inc/vendors/opalmembership/membership.php:581 +msgid "Number Of Featured Properties" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:207 +#: inc/vendors/opalmembership/membership.php:568 +msgid "Number Of Properties" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:229 +#: inc/vendors/opalmembership/membership.php:590 +msgid "Number of properties can make featured with this package." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:216 +#: inc/vendors/opalmembership/membership.php:577 +msgid "" +"Number of properties with this package. If not set it will be unlimited." +msgstr "" + +#: inc/admin/settings/3rd_party.php:114 +msgid "Number of results to show on listing page for each category." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:281 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:283 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:293 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:295 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:316 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:318 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:281 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:283 +msgid "Numbers" +msgstr "" + +#: templates/search-box/fields/search-city-text.php:38 +msgid "Of My Location" +msgstr "" + +#: inc/user/class-opalestate-user.php:454 +msgid "Old Password" +msgstr "" + +#: inc/user/class-opalestate-user.php:389 +msgid "Old password is not correct" +msgstr "" + +#: inc/mixes-functions.php:581 +msgid "Omani rial" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:305 +msgid "Oops! Something went wrong while updating your account." +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-extended.php:78 +msgid "Opal Estate" +msgstr "" + +#: inc/admin/views/addons/list.php:2 +msgid "Opal Estate Add-ons" +msgstr "" + +#: inc/class-opalestate-roles.php:92 +msgid "Opal Estate Agency" +msgstr "" + +#: inc/class-opalestate-roles.php:80 +msgid "Opal Estate Agent" +msgstr "" + +#: inc/class-opalestate-roles.php:49 +msgid "Opal Estate Manager" +msgstr "" + +#. Name of the plugin +msgid "Opal Estate Pro" +msgstr "" + +#. Description of the plugin +msgid "" +"Opal Real Estate Plugin is an ideal solution and brilliant choice for you to " +"set up a professional estate website." +msgstr "" + +#: inc/api/class-opalestate-api.php:1053 +msgid "Opalestate API Keys" +msgstr "" + +#: inc/template-hook-functions.php:268 +msgid "Opalestate Fullwidth" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:115 +msgid "Or 360° Virtual Tour" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:95 +msgid "Or Using Image Logo without using text" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:116 +#: inc/taxonomies/class-taxonomy-status.php:89 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:224 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:193 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:216 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:193 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:224 +msgid "Order" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:209 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:178 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:201 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:179 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:209 +msgid "Order By" +msgstr "" + +#: inc/mixes-functions.php:245 +msgid "Orginal Size" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:352 +#: inc/submission/class-metabox-property-submission.php:300 +msgid "Orientation" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:355 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:416 +msgid "Outside" +msgstr "" + +#: templates/rating/opalestate-ratings.php:106 +msgid "Overall rating" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:553 +msgid "Package" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:369 +msgid "Padding" +msgstr "" + +#: templates/fullwidth-page.php:33 templates/single-opalestate_agency.php:20 +#: templates/archive-opalestate_agency.php:76 +#: templates/archive-opalestate_agent.php:66 +#: templates/archive-opalestate_property.php:54 +msgid "Page" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:291 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:303 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:326 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:291 +msgid "Page Limit" +msgstr "" + +#: templates/single-property/views-statistics.php:16 +#: templates/single-property/views-statistics.php:28 +msgid "Page Views Statistics" +msgstr "" + +#: templates/fullwidth-page.php:29 templates/content-single-agent.php:63 +#: templates/single-property/content.php:11 +msgid "Pages:" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:266 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:276 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:281 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:288 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:304 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:311 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:266 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:276 +msgid "Pagination" +msgstr "" + +#: inc/mixes-functions.php:586 +msgid "Pakistani rupee" +msgstr "" + +#: inc/mixes-functions.php:582 +msgid "Panamanian balboa" +msgstr "" + +#: inc/mixes-functions.php:584 +msgid "Papua New Guinean kina" +msgstr "" + +#: inc/mixes-functions.php:589 +msgid "Paraguayan guaraní" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:38 +msgid "Parent Amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:39 +msgid "Parent Amenity:" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:78 +msgid "Parent Category" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:79 +msgid "Parent Category:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:39 +msgid "Parent City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:40 +msgid "Parent City:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:40 +msgid "Parent Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:41 +msgid "Parent Country:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:41 +msgid "Parent Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:42 +msgid "Parent Label:" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:76 +msgid "Parent Level" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:77 +msgid "Parent Level:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:70 +msgid "Parent Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:71 +msgid "Parent Neighborhood:" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:64 +msgid "Parent rating features" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:38 +msgid "Parent State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:39 +msgid "Parent State:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:41 +msgid "Parent Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:42 +msgid "Parent Status:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:79 +msgid "Parent Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:80 +msgid "Parent Type:" +msgstr "" + +#: inc/property/class-opalestate-search.php:395 +#: inc/property/class-metabox-property-admin.php:309 +#: inc/submission/class-metabox-property-submission.php:246 +msgid "Parking" +msgstr "" + +#: templates/user/register-form.php:57 templates/user/login-form.php:34 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:516 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:517 +msgid "Password" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:70 +#: inc/user/class-opalestate-user-form-handler.php:179 +msgid "Password is required." +msgstr "" + +#: inc/user/functions.php:237 +msgid "Password is requried." +msgstr "" + +#: inc/user/class-opalestate-user.php:387 +msgid "Password Updated" +msgstr "" + +#: inc/user/class-opalestate-user.php:373 +msgid "passwords fields are not empty" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:230 +msgid "Pause on Hover" +msgstr "" + +#: templates/user/my-properties.php:5 +msgid "Pending" +msgstr "" + +#: templates/user/dashboard.php:24 +msgid "Pending Properties" +msgstr "" + +#: templates/rating/opalestate-ratings.php:250 +#: templates/rating/opalestate-ratings.php:262 +msgid "Perfect" +msgstr "" + +#: inc/user/functions.php:130 +msgid "Personal Information" +msgstr "" + +#: inc/mixes-functions.php:583 +msgid "Peruvian nuevo sol" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:272 +msgid "Pets" +msgstr "" + +#: templates/single-property/map.php:59 templates/single-property/map-v2.php:61 +#: templates/single-property/preview/tabs.php:53 +#: templates/single-property/preview/map.php:29 +msgid "Pharmacy" +msgstr "" + +#: inc/mixes-functions.php:585 +msgid "Philippine peso" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:189 +#: inc/agency/class-opalestate-agency-metabox.php:158 +#: inc/agency/class-opalestate-agency-metabox.php:362 +#: inc/message/class-opalestate-message.php:534 +#: inc/message/class-opalestate-message.php:635 +#: inc/message/class-opalestate-message.php:711 +#: inc/agent/class-opalestate-agent-metabox.php:188 +msgid "Phone" +msgstr "" + +#: inc/template-hook-functions.php:235 +msgid "" +"Physical Arrange viewings is always been attractive to property clients. " +"Fill out the form to arrange visualizations around our properties." +msgstr "" + +#: templates/single-property/map-v2.php:20 +msgid "Picture" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:237 +msgid "Pinterest" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:200 +msgid "Pinterest Url" +msgstr "" + +#: templates/single-property/floor-plans.php:22 +#: templates/single-property/floor-plans.php:34 +#, php-format +msgid "Plan %s" +msgstr "" + +#: inc/user/functions.php:228 +msgid "Please enter a valid account username." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:147 +msgid "Please enter company name." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:460 +msgid "Please enter data for all require fields before submitting" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:139 +msgid "Please enter position or job in your company." +msgstr "" + +#: inc/user/class-opalestate-user.php:477 +msgid "Please enter your confirm password." +msgstr "" + +#: inc/user/class-opalestate-user.php:468 +msgid "Please enter your new password." +msgstr "" + +#: inc/user/class-opalestate-user.php:459 +msgid "Please enter your old password" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:190 +msgid "Please Enter Your Property SKU" +msgstr "" + +#: inc/rating/class-opalestate-rating-init.php:96 +msgid "Please rate all features." +msgstr "" + +#: inc/rating/class-opalestate-rating-init.php:102 +msgid "Please rate." +msgstr "" + +#: inc/user/class-opalestate-user-search.php:147 +msgid "Please sign in to save this search." +msgstr "" + +#: inc/importer/class-import-steps.php:594 +msgid "Please waiting for downloading sliders from live server" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:634 +#: inc/submission/class-metabox-property-submission.php:486 +#: templates/single-property/apartments.php:22 +msgid "Plot" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:340 +#: inc/submission/class-metabox-property-submission.php:282 +msgid "Plot Size" +msgstr "" + +#: inc/mixes-functions.php:587 +msgid "Polish złoty" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:350 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:412 +msgid "Position" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:201 +#: inc/submission/class-metabox-property-submission.php:374 +msgid "Postal Code / Zip" +msgstr "" + +#. %s: property date +#: templates/content-single-property-v2.php:38 +#: templates/content-single-property-v3.php:60 +#: templates/content-single-property-v4.php:33 +#: templates/content-single-property-v5.php:73 +#: templates/content-single-property.php:31 +#, php-format +msgid "Posted: %s" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:190 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:159 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:182 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:190 +msgid "Posts Per Page" +msgstr "" + +#: inc/mixes-functions.php:521 +msgid "Pound sterling" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:541 +msgid "Preview Display" +msgstr "" + +#: inc/template-functions.php:314 +msgid "Previous" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:317 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:329 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:352 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:317 +msgid "Previous Label" +msgstr "" + +#: templates/single-opalestate_agency.php:18 +msgid "Previous page" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:342 +#: inc/submission/class-metabox-property-submission.php:404 +#: inc/submission/class-metabox-property-submission.php:420 +#: inc/submission/class-metabox-property-submission.php:438 +#: inc/submission/class-metabox-property-submission.php:481 +#: inc/submission/class-metabox-property-submission.php:556 +#: inc/submission/class-metabox-property-submission.php:673 +msgid "Previous Step" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:225 +msgid "Previous Step " +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:282 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:283 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:294 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:295 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:317 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:318 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:282 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:283 +msgid "Previous/Next" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:252 +#: inc/property/class-metabox-property-admin.php:570 +#: inc/submission/class-metabox-property-submission.php:566 +#: templates/search-box/search-form-v3.php:56 +#: templates/search-box/search-form-v2.php:39 +#: templates/search-box/fields/price.php:20 +msgid "Price" +msgstr "" + +#: inc/template-functions.php:227 +msgid "Price Ascending" +msgstr "" + +#: inc/template-functions.php:228 +msgid "Price Desending" +msgstr "" + +#: templates/single-property/apartments.php:24 +msgid "Price From" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:646 +#: inc/submission/class-metabox-property-submission.php:499 +msgid "Price from" +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:65 +#: templates/single-property/meta.php:13 templates/single-property/price.php:9 +#: templates/single-property/floor-plans.php:42 +#: templates/parts/search-form-h.php:83 +#: templates/parts/search-agents-form.php:46 +#: templates/parts/search-form-v.php:87 +msgid "Price:" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:54 +msgid "Prices" +msgstr "" + +#: inc/template-functions.php:1035 inc/template-functions.php:1037 +msgid "Print" +msgstr "" + +#: templates/user/agency/agency-team.php:45 +msgid "Processing" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:276 +msgid "Professional Services" +msgstr "" + +#: templates/content-single-agency.php:112 +#: templates/content-single-agent.php:18 +#: inc/property/class-opalestate-posttype.php:39 +#: inc/property/class-opalestate-posttype.php:51 +#: templates/single-agency/tabs.php:6 +msgid "Properties" +msgstr "" + +#: templates/single-property/sameagent.php:8 +#, php-format +msgid "Properties by %s" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:35 +msgid "Properties By Amenity" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:36 +msgid "Properties By City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:37 +msgid "Properties By Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:38 +msgid "Properties By Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:67 +msgid "Properties By Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:35 +msgid "Properties By State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:38 +msgid "Properties By Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:76 +msgid "Properties By Type" +msgstr "" + +#: inc/admin/settings/property.php:157 +msgid "Properties Per Page" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:40 +#: inc/agency/class-opalestate-agency-posttype.php:41 +#: inc/admin/register-settings.php:112 +#: inc/agent/class-opalestate-agent-posttype.php:34 +msgid "Property" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:62 +msgid "property" +msgstr "" + +#: templates/content-single-property-v2.php:132 +msgid "Property Attachments" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:45 +msgid "Property Categories" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:95 +msgid "Property Collection" +msgstr "" + +#: templates/content-single-property-print.php:44 +#: templates/content-single-property-v2.php:83 +#: templates/content-single-property-v3.php:71 +#: templates/content-single-property-v4.php:51 +#: templates/content-single-property-v5.php:84 +#: templates/content-single-property.php:56 +msgid "Property Description" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:680 +msgid "Property has been successfully removed." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:501 +msgid "Property has been successfully updated." +msgstr "" + +#: inc/message/class-opalestate-message.php:500 +#: inc/message/class-opalestate-message.php:604 +#: inc/message/class-opalestate-message.php:681 +msgid "Property ID" +msgstr "" + +#: templates/content-single-property-print.php:49 +#: templates/content-single-property-v2.php:89 +#: templates/content-single-property-v3.php:76 +#: templates/content-single-property-v4.php:57 +#: templates/content-single-property-v5.php:90 +#: templates/content-single-property.php:62 +msgid "Property ID: " +msgstr "" + +#: templates/content-single-property-v2.php:122 +#: inc/property/class-metabox-property-admin.php:303 +#: templates/single-property/features.php:11 +msgid "Property Information" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:28 +msgid "Property Metabox" +msgstr "" + +#: templates/single-property/map.php:16 +msgid "Property on Map" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:83 +msgid "Property Search Form" +msgstr "" + +#: inc/admin/settings/property.php:55 +msgid "Property Settings" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:187 +msgid "Property SKU" +msgstr "" + +#: install.php:116 inc/submission/class-opalestate-submission.php:131 +msgid "Property Submission Page" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:52 +msgid "property-city" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:54 +msgid "property-label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:53 +msgid "property-location" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:83 +msgid "property-neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:51 +msgid "property-state" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:53 +msgid "property-status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:92 +msgid "property-type" +msgstr "" + +#: inc/admin/class-api-keys-table.php:181 +msgid "Public Key" +msgstr "" + +#: inc/api/class-opalestate-api.php:1064 +msgid "Public key:" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:280 +msgid "Public Services & Government" +msgstr "" + +#: templates/user/my-properties.php:4 +msgid "Published" +msgstr "" + +#: inc/mixes-functions.php:590 +msgid "Qatari riyal" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:182 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:151 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:174 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:163 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:182 +msgid "Query" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:61 +msgid "Query rating features" +msgstr "" + +#: templates/single-property/information.php:9 +msgid "Quick Information" +msgstr "" + +#: templates/search-box/fields/search-city-text.php:37 +msgid "Radius" +msgstr "" + +#: templates/search-box/fields/radius.php:14 +msgid "Radius:" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:216 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:185 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:208 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:216 +msgid "Random" +msgstr "" + +#: inc/widgets/sameprice-properties.php:69 +msgid "Range Price:" +msgstr "" + +#: templates/rating/opalestate-ratings.php:249 +#: templates/rating/opalestate-ratings.php:261 +msgid "Rate…" +msgstr "" + +#. 1: rating 2: rating count +#: inc/template-functions.php:875 +#, php-format +msgid "Rated %1$s out of 5 based on %2$s customer rating" +msgid_plural "Rated %1$s out of 5 based on %2$s customer ratings" +msgstr[0] "" +msgstr[1] "" + +#. %s: rating +#: inc/template-functions.php:856 inc/template-functions.php:880 +#, php-format +msgid "Rated %s out of 5" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:57 +msgid "Rating" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:57 +msgid "Rating features" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:67 +msgid "Rating Features List" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:66 +msgid "Rating Features navigation" +msgstr "" + +#. %s number of ratings +#: templates/rating/opalestate-ratings.php:118 +#, php-format +msgctxt "rating numbers" +msgid "%s rating" +msgid_plural "%s ratings" +msgstr[0] "" +msgstr[1] "" + +#: templates/rating/opalestate-ratings.php:64 +msgid "Ratings & Reviews" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:182 +msgid "Re-Password is not match." +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:284 +msgid "Real Estate" +msgstr "" + +#: templates/archive-opalestate_agency.php:13 +msgid "" +"Reality Agencies are local expert who can get you better results for lower " +"fees" +msgstr "" + +#: templates/user/my-account-popup.php:5 templates/user/register-form.php:31 +#: templates/user/register-form.php:93 templates/user/my-account.php:5 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:504 +msgid "Register" +msgstr "" + +#: templates/user/login-form.php:56 +msgid "Register now!" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:45 +msgid "Register User Form" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:248 +#: inc/submission/class-metabox-property-submission.php:118 +msgid "Regular Price" +msgstr "" + +#: inc/admin/class-api-keys-table.php:154 +msgid "Reissue" +msgstr "" + +#: templates/parts/modules/carousel.php:11 +msgid "Related Properties" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:288 +msgid "Religious Organizations" +msgstr "" + +#: templates/user/login-form.php:42 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:523 +msgid "Remember me" +msgstr "" + +#: inc/importer/class-content-importer.php:607 +#, php-format +msgid "Remote file is too large, limit is %s" +msgstr "" + +#: inc/importer/class-import-steps.php:114 +msgid "Remote Request Fails" +msgstr "" + +#: inc/importer/class-content-importer.php:588 +#, php-format +msgid "Remote server returned %1$d %2$s for %3$s" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:422 +#: inc/property/class-metabox-property-admin.php:612 +#: inc/property/class-metabox-property-admin.php:681 +#: inc/submission/class-metabox-property-submission.php:455 +#: inc/submission/class-metabox-property-submission.php:534 +#: inc/submission/class-metabox-property-submission.php:610 +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:64 +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:76 +msgid "Remove" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:266 +msgid "Renew membership" +msgstr "" + +#: templates/user/register-form.php:62 +msgid "Repeat-Password" +msgstr "" + +#: templates/user/read-messages.php:45 +msgid "Reply" +msgstr "" + +#: inc/template-hook-functions.php:195 inc/template-hook-functions.php:238 +msgid "Request Viewing" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:292 +msgid "Restaurants" +msgstr "" + +#: inc/importer/class-import-steps.php:121 +msgid "Retrieve Body Fails" +msgstr "" + +#: templates/content-single-agent.php:17 templates/single-agency/tabs.php:17 +#: inc/admin/rating/class-rating.php:46 +msgid "Review" +msgstr "" + +#. %s number of reviews +#: inc/template-functions.php:986 templates/rating/opalestate-ratings.php:173 +#, php-format +msgctxt "review numbers" +msgid "%s review" +msgid_plural "%s reviews" +msgstr[0] "" +msgstr[1] "" + +#: inc/admin/rating/class-rating.php:54 inc/admin/rating/class-rating.php:58 +msgid "Review Settings" +msgstr "" + +#: templates/content-single-property-v5.php:35 inc/user/functions.php:144 +#: inc/user/functions.php:151 +msgid "Reviews" +msgstr "" + +#: inc/admin/class-api-keys-table.php:163 +msgid "Revoke" +msgstr "" + +#: inc/api/class-opalestate-api.php:1074 +msgid "Revoke API Keys" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:314 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:357 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:369 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:392 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:232 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:357 +msgid "Right" +msgstr "" + +#: inc/mixes-functions.php:591 +msgid "Romanian leu" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:381 +#: inc/property/class-metabox-property-admin.php:581 +#: inc/submission/class-metabox-property-submission.php:332 +#: inc/submission/class-metabox-property-submission.php:577 +msgid "Rooms" +msgstr "" + +#: templates/single-property/floor-plans.php:56 +msgid "Rooms:" +msgstr "" + +#: inc/mixes-functions.php:593 +msgid "Russian ruble" +msgstr "" + +#: inc/mixes-functions.php:594 +msgid "Rwandan franc" +msgstr "" + +#: inc/mixes-functions.php:606 +msgid "São Tomé and Príncipe dobra" +msgstr "" + +#: inc/mixes-functions.php:601 +msgid "Saint Helena pound" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:256 +#: inc/submission/class-metabox-property-submission.php:126 +#: templates/parts/mortgage-calculator.php:152 +#: templates/parts/mortgage-calculator.php:153 +#: templates/widgets/mortgage-calculator.php:139 +#: templates/widgets/mortgage-calculator.php:140 +msgid "Sale Price" +msgstr "" + +#: templates/single-property/price.php:12 +msgid "Sale Price:" +msgstr "" + +#: inc/widgets/sameprice-properties.php:52 +msgid "Same Price" +msgstr "" + +#: inc/mixes-functions.php:626 +msgid "Samoan tālā" +msgstr "" + +#: inc/mixes-functions.php:595 +msgid "Saudi riyal" +msgstr "" + +#: templates/user-search/render-form.php:33 +msgid "Save" +msgstr "" + +#: templates/user/profile.php:30 templates/user/profile.php:50 +#: templates/user/agency/profile-agency.php:32 +#: templates/user/agent/profile-agent.php:16 +msgid "Save Change" +msgstr "" + +#: templates/shortcodes/submission-form.php:52 +#: templates/submission/submission-form.php:39 +#: templates/submission/submission-form.php:40 +msgid "Save property" +msgstr "" + +#: templates/user-search/render-form.php:12 +msgid "Save search" +msgstr "" + +#: inc/admin/functions.php:288 +msgid "Save Settings" +msgstr "" + +#: inc/user/class-opalestate-user-search.php:191 +msgid "Saved Search" +msgstr "" + +#: inc/user/class-opalestate-user-search.php:142 +msgid "Saved this search successful." +msgstr "" + +#: inc/message/class-opalestate-message.php:695 +msgid "Schedule" +msgstr "" + +#: templates/single-property/map.php:66 templates/single-property/map-v2.php:68 +#: templates/single-property/preview/tabs.php:60 +#: templates/single-property/preview/map.php:36 +msgid "School" +msgstr "" + +#: templates/content-single-property-v5.php:24 +msgid "Scores" +msgstr "" + +#: templates/shortcodes/ajax-map-quick-search.php:34 +#: templates/parts/search-agents-form-address.php:40 +#: templates/parts/search-form-h.php:95 +#: templates/parts/search-agents-form.php:55 +#: templates/parts/search-agency-form-address.php:40 +#: templates/parts/search-form-v.php:101 +#: templates/parts/search-agency-form.php:27 +#: templates/search-box/fields/submit-button.php:2 +msgid "Search" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:48 +msgid "Search Agency" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:41 +msgid "Search Agent" +msgstr "" + +#: inc/agent/class-opalestate-agent-front.php:321 +msgid "Search Agents" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:36 +msgid "Search Amenities" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:106 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:106 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:92 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:92 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:106 +msgid "Search By Address" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:76 +msgid "Search Category" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:37 +msgid "Search Cities / Towns" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:38 +msgid "Search Countries" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:101 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:101 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:87 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:87 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:80 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:87 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:101 +msgid "Search Form" +msgstr "" + +#: inc/admin/functions.php:365 +msgid "Search Key" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:39 +msgid "Search Label" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:74 +msgid "Search Level" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:42 +msgid "Search Map Properties" +msgstr "" + +#: install.php:134 +msgid "Search Map Properties Page" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:68 +msgid "Search Neighborhoods" +msgstr "" + +#: inc/admin/settings/property.php:27 +msgid "Search Page" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:39 +#: inc/widgets/search-properties.php:57 templates/parts/search-form-v.php:30 +msgid "Search Properties" +msgstr "" + +#: inc/admin/settings/property.php:144 +msgid "Search Properties Page" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:38 +msgid "Search Properties Result" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:40 +msgid "Search Properties Vertical" +msgstr "" + +#: inc/widgets/search-properties.php:25 +msgid "Search Properties widget." +msgstr "" + +#: inc/property/class-opalestate-posttype.php:47 +msgid "Search Property" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:36 +msgid "Search States" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:39 +msgid "Search Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:77 +msgid "Search Types" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:40 +msgid "Search: Form Builder" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:40 +msgid "Search: Maps Preview" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:43 +msgid "Search: Property Form " +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:40 +msgid "Search: Property Results" +msgstr "" + +#: inc/admin/class-api-keys-table.php:183 +msgid "Secret Key" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:128 +msgid "Secret key" +msgstr "" + +#: inc/api/class-opalestate-api.php:1067 +msgid "Secret key:" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:537 +#: inc/property/class-metabox-property-admin.php:545 +msgid "Select a layout to display full information of this property" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:75 +msgid "Select an image icon (SVG, PNG or JPEG)." +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:100 +msgid "Select category" +msgstr "" + +#: inc/ajax-functions.php:139 inc/taxonomies/class-taxonomy-city.php:112 +msgid "Select City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:108 +#: inc/taxonomies/class-taxonomy-locations.php:128 +msgid "Select Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:114 +msgid "Select Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:98 +msgid "Select Neighborhoods" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:135 +#: inc/submission/class-metabox-property-submission.php:224 +msgid "Select one or more files to allow download" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:97 +#: inc/property/class-metabox-property-admin.php:111 +#: inc/agency/class-opalestate-agency-metabox.php:320 +#: inc/agent/class-opalestate-agent-metabox.php:153 +#: inc/submission/class-metabox-property-submission.php:187 +#: inc/submission/class-metabox-property-submission.php:196 +msgid "Select one or more images to show as gallery" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:96 +msgid "Select one, to add new you create in city of estate panel" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:98 +msgid "Select one, to add new you create in City/Town of estate panel" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:92 +#: inc/taxonomies/class-taxonomy-city.php:89 +msgid "Select one, to add new you create in countries of estate panel" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:80 +#: inc/agency/class-opalestate-agency-metabox.php:37 +#: inc/agency/class-opalestate-agency-metabox.php:277 +#: inc/agency/class-opalestate-agency-metabox.php:345 +#: inc/agent/class-opalestate-agent-metabox.php:65 +#: inc/agent/class-opalestate-agent-metabox.php:111 +#: inc/admin/agency/class-agency.php:73 +msgid "Select one, to add new you create in location of estate panel" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:89 +msgid "Select one, to add new you create in state of estate panel" +msgstr "" + +#: inc/ajax-functions.php:97 inc/taxonomies/class-taxonomy-state.php:108 +#: inc/taxonomies/class-taxonomy-state.php:125 +msgid "Select State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:128 +msgid "Select Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:111 +msgid "Select Type" +msgstr "" + +#: templates/messages/enquiry-form.php:23 +#: templates/messages/enquiry-form.php:38 +#: templates/messages/contact-form.php:37 +#: templates/user/share-search-form.php:48 +#: templates/user/agency/agency-team.php:45 +msgid "Send message" +msgstr "" + +#: inc/email/class-opalestate-abs-email-template.php:53 +msgid "Send notices to the site administrator before a job listing expires." +msgstr "" + +#: templates/messages/request-reviewing-form.php:10 +#: templates/messages/request-reviewing-form.php:11 +msgid "Send now" +msgstr "" + +#: inc/message/class-opalestate-message.php:508 +#: inc/message/class-opalestate-message.php:611 +#: inc/message/class-opalestate-message.php:688 +#: templates/user/agency/agency-team.php:14 +msgid "Sender ID" +msgstr "" + +#: inc/message/class-opalestate-message.php:230 +#: inc/message/class-opalestate-message.php:234 +msgid "Sending Message" +msgstr "" + +#: inc/mixes-functions.php:592 +msgid "Serbian dinar" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:117 +#: inc/taxonomies/class-taxonomy-status.php:90 +msgid "Set a priority to display" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:82 +#: inc/taxonomies/class-taxonomy-status.php:78 +msgid "Set background of label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:84 +msgid "Set background of text" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:88 +msgid "Set color of text" +msgstr "" + +#: templates/user/content-property.php:79 +msgid "Set Featured" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:180 +msgid "Set how many slides are scrolled per swipe." +msgstr "" + +#: inc/admin/settings/general.php:79 inc/admin/settings/general.php:87 +msgid "Set maximun volumn size having < x MB" +msgstr "" + +#: inc/admin/settings/general.php:95 inc/admin/settings/general.php:103 +msgid "Set maximun volumn size having < x MB for upload docx, pdf..." +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:150 +msgid "Set member as featured" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:562 +msgid "Set package ID with -1 as free package." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:32 +msgid "" +"Set relationship to existed user, allow user can edit Agency profile in " +"front-end and show account info in each property." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:59 +msgid "Set this agent as featured" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:161 +msgid "Set this member as Trusted Member" +msgstr "" + +#: inc/admin/register-settings.php:79 +msgid "Settings" +msgstr "" + +#: inc/admin/register-settings.php:280 +msgid "Settings updated." +msgstr "" + +#: inc/mixes-functions.php:597 +msgid "Seychellois rupee" +msgstr "" + +#: templates/single-property/sharebox.php:28 +msgid "Share on facebook" +msgstr "" + +#: templates/single-property/sharebox.php:57 +msgid "Share on Google plus" +msgstr "" + +#: templates/single-property/sharebox.php:42 +msgid "Share on LinkedIn" +msgstr "" + +#: templates/single-property/sharebox.php:65 +msgid "Share on Pinterest" +msgstr "" + +#: templates/single-property/sharebox.php:49 +msgid "Share on Tumblr" +msgstr "" + +#: templates/single-property/sharebox.php:35 +msgid "Share on Twitter" +msgstr "" + +#: templates/user/share-search-form.php:14 +msgid "Share this Search" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:296 +#: templates/single-property/map.php:73 templates/single-property/map-v2.php:75 +#: templates/single-property/preview/tabs.php:67 +#: templates/single-property/preview/map.php:43 +msgid "Shopping" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:302 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:314 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:337 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:302 +msgid "Shorten" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:148 +msgid "Show" +msgstr "" + +#: inc/admin/settings/property.php:295 +msgid "Show Amenities tab" +msgstr "" + +#: inc/admin/settings/property.php:296 +msgid "Show Amenities tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:372 +msgid "Show Apartments tab" +msgstr "" + +#: inc/admin/settings/property.php:373 +msgid "Show Apartments tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:317 +msgid "Show Attachments tab" +msgstr "" + +#: inc/admin/settings/property.php:318 +msgid "Show Attachments tab in the single property page." +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:101 +msgid "Show Captcha In Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:80 +msgid "Show Collection as Default Results" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:142 +msgid "Show Content Use Not Login" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:599 +#: inc/vendors/opalmembership/membership.php:607 +msgid "Show expired time in double format." +msgstr "" + +#: inc/admin/settings/property.php:306 +msgid "Show Facilities tab" +msgstr "" + +#: inc/admin/settings/property.php:307 +msgid "Show Facilities tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:169 +msgid "Show Featured First" +msgstr "" + +#: inc/admin/settings/property.php:171 +msgid "Show featured first in page result, as default Newest is showed" +msgstr "" + +#: inc/admin/settings/property.php:383 +msgid "Show Floor Plans tab" +msgstr "" + +#: inc/admin/settings/property.php:384 +msgid "Show Floor Plans tab in the single property page." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:148 +msgid "Show Login Form" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:149 +msgid "Show Login Form and Submission Form" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:143 +msgid "Show Login/Register form and submission form if user not logined" +msgstr "" + +#: inc/admin/settings/property.php:339 +msgid "Show Map tab" +msgstr "" + +#: inc/admin/settings/property.php:340 +msgid "Show Map tab in the single property page." +msgstr "" + +#: inc/admin/class-user.php:178 +msgid "Show message for disabled user" +msgstr "" + +#: inc/admin/settings/property.php:98 +msgid "Show Meta Information In Grid and Single Page" +msgstr "" + +#: inc/admin/settings/property.php:350 +msgid "Show Nearby tab" +msgstr "" + +#: inc/admin/settings/property.php:351 +msgid "Show Nearby tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:232 inc/admin/settings/property.php:262 +msgid "Show Price" +msgstr "" + +#: inc/admin/settings/property.php:328 +msgid "Show Video tab" +msgstr "" + +#: inc/admin/settings/property.php:329 +msgid "Show Video tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:394 +msgid "Show Views Statistics tab" +msgstr "" + +#: inc/admin/settings/property.php:395 +msgid "Show Views Statistics tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:361 +msgid "Show Walk Scores tab" +msgstr "" + +#: inc/admin/settings/property.php:362 +msgid "Show Walk Scores tab in the single property page." +msgstr "" + +#: templates/search-box/fields/search-city-text.php:35 +msgid "Show with in." +msgstr "" + +#: inc/mixes-functions.php:602 +msgid "Sierra Leonean leone" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:501 +msgid "Sign in" +msgstr "" + +#: inc/widgets/similar-properties.php:51 +msgid "Similar Properties" +msgstr "" + +#: inc/widgets/sameprice-properties.php:24 +msgid "Similar Properties By Same Price with configured range and Status" +msgstr "" + +#: inc/widgets/similar-properties.php:24 +msgid "Similar Properties By Same Types and Status Of the post" +msgstr "" + +#: inc/mixes-functions.php:137 +msgid "Simple City Form" +msgstr "" + +#: inc/mixes-functions.php:138 +msgid "Simple Keyword Form" +msgstr "" + +#: inc/mixes-functions.php:600 +msgid "Singapore dollar" +msgstr "" + +#: inc/admin/settings/general.php:175 +msgid "Single Layout Page" +msgstr "" + +#: inc/admin/settings/property.php:28 +msgid "Single Page" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:121 +msgid "Site Key" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:576 +#: inc/submission/class-metabox-property-submission.php:572 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:366 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:428 +msgid "Size" +msgstr "" + +#: templates/single-property/floor-plans.php:49 +msgid "Size:" +msgstr "" + +#: inc/admin/property/class-property.php:100 +msgid "Sku" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:165 +msgid "Skype" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:286 +msgid "Slide" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:178 +msgid "Slides to Scroll" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:166 +msgid "Slides to Show" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:261 +#: inc/admin/agency/class-agency.php:79 +msgid "slogan" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:51 +msgctxt "slug" +msgid "opal-property-amenity" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:53 +msgctxt "slug" +msgid "property-category" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:183 +msgid "Social" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:49 +msgid "Social Login" +msgstr "" + +#: inc/admin/class-user.php:112 inc/admin/agency/class-agency.php:136 +#: inc/admin/agent/class-agent.php:87 +msgid "Socials" +msgstr "" + +#: inc/mixes-functions.php:596 +msgid "Solomon Islands dollar" +msgstr "" + +#: inc/mixes-functions.php:603 +msgid "Somali shilling" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:540 +msgid "Sorry! Your submitted datcould not save a at this time" +msgstr "" + +#: inc/template-functions.php:234 +msgid "Sort By" +msgstr "" + +#: inc/mixes-functions.php:632 +msgid "South African rand" +msgstr "" + +#: inc/mixes-functions.php:551 +msgid "South Korean won" +msgstr "" + +#: inc/mixes-functions.php:605 +msgid "South Sudanese pound" +msgstr "" + +#: inc/admin/settings/general.php:240 +msgid "sq ft" +msgstr "" + +#: inc/admin/settings/general.php:241 +msgid "sq m" +msgstr "" + +#: inc/mixes-functions.php:557 +msgid "Sri Lankan rupee" +msgstr "" + +#: templates/rating/opalestate-ratings.php:79 +msgid "star" +msgstr "" + +#: inc/importer/class-import-steps.php:286 +msgid "Starting to download attachments then import" +msgstr "" + +#: inc/importer/class-import-steps.php:399 +#: inc/importer/class-import-steps.php:451 +#: inc/importer/class-import-steps.php:473 +msgid "Starting to import Content" +msgstr "" + +#: inc/importer/class-import-steps.php:622 +msgid "Starting to import customizer" +msgstr "" + +#: inc/importer/class-import-steps.php:860 +msgid "Starting to import other content and settings" +msgstr "" + +#: inc/importer/class-import-steps.php:450 +msgid "Starting to import other sample content" +msgstr "" + +#: inc/importer/class-import-steps.php:262 +msgid "Starting to import required plugins" +msgstr "" + +#: inc/importer/class-import-steps.php:576 +msgid "Starting to import required slider" +msgstr "" + +#: inc/importer/class-import-steps.php:497 +msgid "Starting to import required widgets" +msgstr "" + +#: inc/importer/class-import-steps.php:552 +msgid "Starting to import website menu" +msgstr "" + +#: inc/importer/class-import-steps.php:761 +msgid "Starting to theme Options" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:139 +msgid "State" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:88 +#: inc/taxonomies/class-taxonomy-city.php:97 +msgid "State / Province" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:80 +msgid "State image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:72 +msgid "State Metabox" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:362 +msgid "States / Province" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:34 +#: inc/taxonomies/class-taxonomy-state.php:44 +msgid "States / Provinces" +msgstr "" + +#: templates/content-single-property-v5.php:27 +msgid "Statistics" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:662 +#: inc/taxonomies/class-taxonomy-status.php:37 +#: inc/taxonomies/class-taxonomy-status.php:47 +#: inc/taxonomies/class-taxonomy-status.php:140 +#: inc/submission/class-metabox-property-submission.php:515 +#: templates/single-property/features.php:38 +#: templates/single-property/apartments.php:27 +#: templates/parts/search-form-v.php:44 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:254 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:277 +msgid "Status" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:143 +msgid "Statuses" +msgstr "" + +#: templates/single-property/map.php:28 templates/single-property/map-v2.php:25 +#: templates/single-property/preview/tabs.php:19 +msgid "Street View" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:96 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:103 +msgid "Style Item Layout" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:93 +msgid "Submission Form" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:462 +#: inc/submission/class-opalestate-submission.php:527 +#: inc/submission/class-opalestate-submission.php:534 +#: inc/submission/class-opalestate-submission.php:541 +#: inc/vendors/opalmembership/membership.php:426 +msgid "Submission Information" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:110 +msgid "Submission Page" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:125 +msgid "Submission Page Settings" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:167 +msgid "Submission Tab Settings" +msgstr "" + +#: templates/rating/opalestate-ratings.php:240 +msgid "Submit" +msgstr "" + +#: inc/user/functions.php:167 +msgid "Submit Property" +msgstr "" + +#: inc/user/class-opalestate-user.php:272 +msgid "Subscriber" +msgstr "" + +#: inc/mixes-functions.php:598 +msgid "Sudanese pound" +msgstr "" + +#: inc/mixes-functions.php:604 +msgid "Surinamese dollar" +msgstr "" + +#: inc/mixes-functions.php:608 +msgid "Swazi lilangeni" +msgstr "" + +#: inc/mixes-functions.php:599 +msgid "Swedish krona" +msgstr "" + +#: inc/mixes-functions.php:502 +msgid "Swiss franc" +msgstr "" + +#: inc/mixes-functions.php:607 +msgid "Syrian pound" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:303 +msgid "System is unable to send you mail containg your new password." +msgstr "" + +#: inc/template-functions.php:466 +msgid "Tabs - Gallery Active" +msgstr "" + +#: inc/template-functions.php:467 +msgid "Tabs - Map Active" +msgstr "" + +#: inc/template-functions.php:468 +msgid "Tabs - Street Map Active" +msgstr "" + +#: inc/mixes-functions.php:610 +msgid "Tajikistani somoni" +msgstr "" + +#: inc/mixes-functions.php:617 +msgid "Tanzanian shilling" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:59 +#: inc/agent/class-opalestate-agent-metabox.php:126 +msgid "Target Max Price" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:52 +#: inc/agent/class-opalestate-agent-metabox.php:119 +msgid "Target Min Price" +msgstr "" + +#: inc/admin/agent/class-agent.php:94 +msgid "Target Search" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:100 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:100 +msgid "Target Submit Page" +msgstr "" + +#: templates/content-single-agency.php:27 +#: templates/content-single-agency.php:101 templates/single-agency/tabs.php:11 +#: inc/admin/agency/class-agency.php:144 +msgid "Team" +msgstr "" + +#: templates/user/register-form.php:81 +msgid "terms & conditions" +msgstr "" + +#: inc/mixes-functions.php:609 +msgid "Thai baht" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:88 +msgid "The captcha is not verified, please try again!" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:308 +#: inc/agent/class-opalestate-agent-front.php:210 +msgid "The data updated successful, please wait for redirecting" +msgstr "" + +#: inc/class-opalestate-email.php:326 inc/class-opalestate-email.php:354 +msgid "" +"The email subject a user should receive when they make an initial property " +"request." +msgstr "" + +#: inc/class-opalestate-email.php:287 +msgid "The email subject for admin notifications." +msgstr "" + +#: inc/admin/settings/general.php:146 +msgid "" +"The Featured Image is an image that is chosen as the representative image in " +"single page. ." +msgstr "" + +#: inc/admin/views/addons/list.php:7 +msgid "The following Add-ons extend the functionality of Opal Estate." +msgstr "" + +#: inc/importer/class-import-steps.php:248 +msgid "The installation was not complete" +msgstr "" + +#: inc/importer/class-import-steps.php:548 +msgid "The Installer is excuting to import menu, please waiting for a while!" +msgstr "" + +#: inc/admin/settings/general.php:112 inc/admin/settings/general.php:123 +msgid "" +"The Loop Image is an Agent that is chosen as the representative Agent in " +"grid and list." +msgstr "" + +#: inc/admin/settings/general.php:135 +msgid "" +"The Loop Image is an image that is chosen as the representative image in " +"grid and list." +msgstr "" + +#: inc/class-opalestate-email.php:252 +msgid "" +"The name donation receipts are said to come from. This should probably be " +"your site or shop name." +msgstr "" + +#: inc/admin/settings/property.php:406 +msgid "The number of days will be saved to the database." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:507 +msgid "The property has updated completed with new information" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:155 +msgid "" +"the Property will be auto approve when user submit, if you do not enable it." +msgstr "" + +#: inc/admin/settings/general.php:212 +msgid "The symbol (typically , or .) to separate thousands" +msgstr "" + +#: inc/admin/settings/general.php:219 +msgid "The symbol (usually , or .) to separate decimal points" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:135 +msgid "Theme" +msgstr "" + +#: templates/rating/opalestate-ratings.php:207 +msgid "There are no reviews yet." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:257 +msgid "There is no user registered with that email address." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:263 +msgid "There is no user registered with that username." +msgstr "" + +#: inc/admin/views/addons/list.php:21 +msgid "" +"There was an error retrieving the Give Add-ons list from the server. Please " +"try again later." +msgstr "" + +#: inc/class-opalestate-enqueue.php:87 +msgid "This file is has large volume size, please try to upload other." +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:50 +#: inc/taxonomies/class-taxonomy-types.php:48 +msgid "This image will display in google map" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:90 +msgid "" +"This is often used for building seach page, it combines with block => Search:" +" Map Preview, Search: Property Results." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:89 +msgid "" +"This is often used for building seach page, it combines with block => Search:" +" Property Form, Search: Property Results." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:87 +msgid "" +"This is often used for building seach page, it combines with block => Search:" +" Property Form, Search:Map Preview." +msgstr "" + +#: inc/admin/settings/property.php:145 +msgid "" +"This is page to display result of properties after user searching via form." +msgstr "" + +#: inc/admin/settings/general.php:60 +msgid "This is page use User login and register an account, or reset password." +msgstr "" + +#: inc/admin/settings/general.php:53 +msgid "" +"This is page use User Management Page using for show content of management " +"page such as profile, my properties" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:132 +msgid "" +"This is the submission page. The [opalestate_submission] " +"shortcode should be on this page." +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:69 +msgid "This is where store rating features are stored." +msgstr "" + +#: inc/admin/settings/general.php:226 +msgid "This sets the number of decimal points shown in displayed prices." +msgstr "" + +#: inc/admin/class-user.php:49 +#, php-format +msgid "" +"This user has role Opal Estate Agency and click here to update Agency profile" +msgstr "" + +#: inc/user/class-opalestate-user.php:167 +#, php-format +msgid "" +"This user has role Opal Estate Agency and click here to update Agency profile" +msgstr "" + +#: inc/admin/class-user.php:59 +#, php-format +msgid "" +"This user has role Opal Estate Agent and click here to update Agent profile" +msgstr "" + +#: inc/user/class-opalestate-user.php:177 +#, php-format +msgid "" +"This user has role Opal Estate Agent and click here to update Agent profile" +msgstr "" + +#: inc/admin/settings/general.php:211 +msgid "Thousands Separator" +msgstr "" + +#: inc/message/class-opalestate-message.php:703 +msgid "Time" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:99 +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:87 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:214 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:183 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:206 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:214 +msgid "Title" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:137 +msgid "Title/Job" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:252 +#: inc/agent/class-opalestate-agent-metabox.php:91 +msgid "Title/Name" +msgstr "" + +#: inc/widgets/featured-properties.php:57 +#: inc/widgets/sameprice-properties.php:58 +#: inc/widgets/similar-properties.php:56 inc/widgets/profile-info.php:78 +#: inc/widgets/search-properties.php:68 inc/widgets/mortgage-calculator.php:53 +msgid "Title:" +msgstr "" + +#: inc/admin/settings/general.php:151 +msgid "" +"To generate images with new image sizes, you can use this Force Regenerate Thumbnails" +msgstr "" + +#: inc/admin/class-api-keys-table.php:182 +msgid "Token" +msgstr "" + +#: inc/api/class-opalestate-api.php:1070 +msgid "Token:" +msgstr "" + +#: inc/mixes-functions.php:613 +msgid "Tongan paʻanga" +msgstr "" + +#: inc/template-functions.php:469 +msgid "Tour 360" +msgstr "" + +#: templates/single-property/map.php:79 templates/single-property/map-v2.php:81 +#: templates/single-property/preview/tabs.php:73 +#: templates/single-property/preview/map.php:49 +msgid "Trainstation" +msgstr "" + +#: templates/single-property/walkscore.php:35 +msgid "Transit Scores" +msgstr "" + +#: inc/mixes-functions.php:588 +msgid "Transnistrian ruble" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:300 +msgid "Transportation" +msgstr "" + +#: inc/mixes-functions.php:615 +msgid "Trinidad and Tobago dollar" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:159 +msgid "Trusted" +msgstr "" + +#: templates/content-agent-list.php:26 templates/content-agent-list.php:27 +#: templates/content-agent-grid.php:20 templates/content-agent-grid.php:20 +#: templates/content-agent-grid-v2.php:19 +#: templates/content-agent-grid-v2.php:19 templates/content-agency-grid.php:21 +#: templates/content-agency-grid.php:21 templates/content-agency-list.php:28 +#: templates/content-agency-list.php:29 +#: templates/single-agent/author-box.php:21 +#: templates/single-agent/author-box.php:21 +#: templates/single-agency/author-box.php:28 +#: templates/single-agency/author-box.php:28 +#: templates/single-property/user/author-member-box.php:28 +#: templates/single-property/user/author-member-box.php:28 +#: templates/single-property/user/author-user-box.php:64 +#: templates/single-property/user/author-user-box.php:64 +#: templates/single-property/user/author-user-box-list.php:50 +#: templates/single-property/user/author-user-box-list.php:50 +msgid "Trusted Member" +msgstr "" + +#: inc/mixes-functions.php:612 +msgid "Tunisian dinar" +msgstr "" + +#: inc/mixes-functions.php:614 +msgid "Turkish lira" +msgstr "" + +#: inc/mixes-functions.php:611 +msgid "Turkmenistan manat" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:212 +msgid "Twitter" +msgstr "" + +#: inc/message/class-opalestate-message.php:493 +#: inc/message/class-opalestate-message.php:559 +#: inc/message/class-opalestate-message.php:597 +#: inc/message/class-opalestate-message.php:674 +#: inc/taxonomies/class-taxonomy-types.php:123 +#: templates/user/register-form.php:69 +#: templates/single-property/features.php:26 +#: templates/parts/search-form-v.php:55 +msgid "Type" +msgstr "" + +#: templates/search-box/fields/search-city-text.php:24 +msgid "Type City or Area" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:59 +msgid "Type image" +msgstr "" + +#: templates/search-box/fields/search-text.php:2 +msgid "Type keyword" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:68 +#: inc/taxonomies/class-taxonomy-neighborhood.php:42 +#: inc/taxonomies/class-taxonomy-types.php:40 +msgid "Type Metabox" +msgstr "" + +#: templates/single-property/information.php:15 +msgid "Type:" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:276 +#: inc/agent/class-opalestate-agent-metabox.php:64 +#: inc/agent/class-opalestate-agent-metabox.php:110 +#: inc/taxonomies/class-taxonomy-types.php:75 +#: inc/taxonomies/class-taxonomy-types.php:85 +#: inc/submission/class-metabox-property-submission.php:154 +#: templates/search-box/search-form-v3.php:46 +#: templates/search-box/search-form-v2.php:29 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:234 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:257 +msgid "Types" +msgstr "" + +#: inc/mixes-functions.php:619 +msgid "Ugandan shilling" +msgstr "" + +#: inc/mixes-functions.php:618 +msgid "Ukrainian hryvnia" +msgstr "" + +#: inc/message/class-opalestate-request-reviewing.php:94 +#: inc/message/class-opalestate-message.php:234 +#: inc/message/class-opalestate-message.php:282 +msgid "Unable to send a message." +msgstr "" + +#: inc/property/class-metabox-property-admin.php:667 +#: inc/submission/class-metabox-property-submission.php:519 +msgid "Unavailable" +msgstr "" + +#: inc/mixes-functions.php:474 +msgid "United Arab Emirates dirham" +msgstr "" + +#: inc/mixes-functions.php:620 +msgid "United States dollar" +msgstr "" + +#: templates/parts/membership-pricing-info.php:14 +#: templates/parts/membership-pricing-info.php:23 +#: inc/vendors/opalmembership/membership.php:493 +#: inc/vendors/opalmembership/membership.php:494 +msgid "Unlimited" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:41 +msgid "Update Amenity" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:81 +msgid "Update Category" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:42 +msgid "Update City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:43 +msgid "Update Country" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:310 +#: inc/agency/class-opalestate-agency-front.php:318 +#: inc/agent/class-opalestate-agent-front.php:212 +#: inc/agent/class-opalestate-agent-front.php:220 +msgid "Update Information" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:44 +msgid "Update Label" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:79 +msgid "Update Level" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:73 +msgid "Update Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:41 +msgid "Update State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:44 +msgid "Update Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:82 +msgid "Update Type" +msgstr "" + +#: templates/emails/publish_property.php:14 +msgid "URL" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:63 +msgctxt "URL Slug" +msgid "agency" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:56 +msgctxt "URL Slug" +msgid "agent" +msgstr "" + +#: inc/mixes-functions.php:621 +msgid "Uruguayan peso" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:187 +msgid "Use Custom Dashboard Menu" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:129 +msgid "Used for communication between your site and Google. Grab it." +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:122 +#, php-format +msgid "Used for displaying the CAPTCHA. Grab it %s" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:512 +msgid "User" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:441 +msgid "User Author Information" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:150 +msgid "User Assignment" +msgstr "" + +#: install.php:80 +msgid "User Dashboard Page" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:472 +#: inc/agent/class-opalestate-agent-front.php:497 +msgid "User ID" +msgstr "" + +#: inc/api/class-opalestate-api.php:1102 +msgid "User ID Required." +msgstr "" + +#: inc/template-hook-functions.php:267 +msgid "User Management" +msgstr "" + +#: inc/admin/settings/general.php:52 +msgid "User Management Page" +msgstr "" + +#: inc/user/class-opalestate-user.php:50 +msgid "User Profile" +msgstr "" + +#: inc/admin/settings/property.php:76 inc/admin/settings/property.php:132 +msgid "User Saved Search" +msgstr "" + +#: inc/admin/settings/property.php:121 +msgid "User Share Search" +msgstr "" + +#: inc/admin/class-api-keys-table.php:180 templates/user/register-form.php:43 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:512 +msgid "Username" +msgstr "" + +#: inc/user/functions.php:232 +msgid "Username is already exists." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:51 +#: inc/user/class-opalestate-user-form-handler.php:165 +msgid "Username is required." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:511 +msgid "Username or email" +msgstr "" + +#: templates/user/login-form.php:27 +msgid "Username or email address" +msgstr "" + +#: inc/mixes-functions.php:622 +msgid "Uzbekistani som" +msgstr "" + +#: inc/mixes-functions.php:625 +msgid "Vanuatu vatu" +msgstr "" + +#: inc/mixes-functions.php:623 +msgid "Venezuelan bolívar" +msgstr "" + +#: inc/mixes-functions.php:134 +msgid "Vertical Advanced Form" +msgstr "" + +#: inc/mixes-functions.php:135 +msgid "Vertical Advanced V2 Form" +msgstr "" + +#: inc/mixes-functions.php:136 +msgid "Vertical Advanced V3 Form" +msgstr "" + +#: inc/admin/settings/property.php:254 +msgid "Vertical Search Fields" +msgstr "" + +#: templates/rating/opalestate-ratings.php:254 +#: templates/rating/opalestate-ratings.php:266 +msgid "Very poor" +msgstr "" + +#: inc/template-functions.php:437 +msgid "Vesion 2" +msgstr "" + +#: inc/template-functions.php:438 +msgid "Vesion 3" +msgstr "" + +#: inc/template-functions.php:439 +msgid "Vesion 4" +msgstr "" + +#: inc/template-functions.php:440 +msgid "Vesion 5" +msgstr "" + +#: templates/content-single-property-v5.php:18 +#: inc/property/class-metabox-property-admin.php:228 +#: inc/submission/class-metabox-property-submission.php:202 +#: templates/single-property/video.php:12 +msgid "Video" +msgstr "" + +#: inc/mixes-functions.php:624 +msgid "Vietnamese đồng" +msgstr "" + +#: templates/user-search/content-savedsearch.php:12 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:211 +msgid "View" +msgstr "" + +#: templates/single-property/apartments.php:43 +msgid "view" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:47 +msgid "View Agency" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:40 +msgid "View Agent" +msgstr "" + +#: inc/admin/views/addons/list.php:3 +msgid "View All Add-ons" +msgstr "" + +#: inc/admin/class-api-keys-table.php:143 +msgid "View API Log" +msgstr "" + +#: templates/single-agent/author-box.php:122 +msgid "View Profile" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:46 +#: templates/user/dashboard.php:128 templates/user/property-ratings.php:91 +msgid "View Property" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:60 +msgid "View rating feature" +msgstr "" + +#: inc/admin/settings/property.php:405 +msgid "Views Statistics time limit (days)" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:221 +msgid "Vimeo Url" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:104 +msgid "Virtual Tour 360" +msgstr "" + +#: inc/importer/class-import-steps.php:400 +msgid "Waiting for a while to download all attachment files!" +msgstr "" + +#: inc/importer/class-import-steps.php:489 +msgid "Waiting for a while to import content!" +msgstr "" + +#: inc/admin/settings/3rd_party.php:58 +msgid "Walk Score" +msgstr "" + +#: inc/admin/settings/3rd_party.php:66 +msgid "Walk Score APi Key" +msgstr "" + +#: templates/single-property/walkscore.php:12 +#: templates/single-property/walkscore.php:22 +msgid "Walk Scores" +msgstr "" + +#: inc/admin/functions.php:586 +msgid "We could find this user" +msgstr "" + +#: inc/admin/functions.php:590 +msgid "We could not find this user" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:184 +#: inc/agency/class-opalestate-agency-metabox.php:357 +#: inc/agent/class-opalestate-agent-metabox.php:183 +msgid "Website" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:172 +msgid "Website URL" +msgstr "" + +#: inc/mixes-functions.php:629 +msgid "West African CFA franc" +msgstr "" + +#: templates/single-property/nearby.php:27 +msgid "What's nearby" +msgstr "" + +#: templates/parts/search-agents-form-address.php:23 +#: templates/parts/search-agents-form.php:23 +#: templates/parts/search-agency-form-address.php:23 +msgid "Who sale between:" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:153 +msgid "Without Featured" +msgstr "" + +#. Author of the plugin +msgid "WPOPAL" +msgstr "" + +#: templates/parts/mortgage-calculator.php:172 +#: templates/parts/mortgage-calculator.php:173 +#: templates/widgets/mortgage-calculator.php:159 +#: templates/widgets/mortgage-calculator.php:160 +msgid "Years" +msgstr "" + +#: inc/admin/settings/3rd_party.php:77 +msgid "Yelp" +msgstr "" + +#: inc/admin/settings/3rd_party.php:113 +msgid "Yelp - Number of results" +msgstr "" + +#: inc/admin/settings/3rd_party.php:85 +msgid "Yelp API Client ID" +msgstr "" + +#: inc/admin/settings/3rd_party.php:92 +msgid "Yelp API Secret" +msgstr "" + +#: inc/admin/settings/3rd_party.php:99 +msgid "Yelp App key" +msgstr "" + +#: inc/admin/settings/3rd_party.php:106 +msgid "Yelp Categories" +msgstr "" + +#: inc/admin/settings/3rd_party.php:107 +msgid "Yelp Categories to show on front page" +msgstr "" + +#: inc/admin/settings/3rd_party.php:124 inc/admin/settings/3rd_party.php:125 +msgid "Yelp Distance Measurement Unit" +msgstr "" + +#: inc/mixes-functions.php:631 +msgid "Yemeni rial" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:108 +#: inc/classes/class-opalestate-metabox-user.php:153 +#: inc/classes/class-opalestate-metabox-user.php:164 +#: inc/property/class-metabox-property-admin.php:182 +#: inc/property/class-metabox-property-admin.php:211 +#: inc/property/class-metabox-property-admin.php:279 +#: inc/agency/class-opalestate-agency-metabox.php:62 +#: inc/widgets/search-properties.php:148 +#: inc/submission/class-metabox-property-submission.php:394 +#: inc/submission/class-metabox-property-submission.php:474 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:234 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:248 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:272 +#: inc/vendors/opalmembership/free-package.php:34 +msgid "Yes" +msgstr "" + +#: templates/user/register-form.php:22 templates/user/login-form.php:7 +msgid "You are currently logged in." +msgstr "" + +#: templates/parts/not-allowed.php:8 +msgid "You are not allowed to access this page." +msgstr "" + +#: inc/admin/settings/3rd_party.php:100 +msgid "" +"You can find it in your Yelp Application Dashboard. Register here" +msgstr "" + +#. %s: process +#: inc/api/class-opalestate-api.php:1117 inc/api/class-opalestate-api.php:1127 +#, php-format +msgid "You do not have permission to %s API keys for this user." +msgstr "" + +#: inc/class-opalestate-email.php:359 +#: inc/message/class-opalestate-message.php:102 +msgid "You got a message" +msgstr "" + +#: inc/message/class-opalestate-message.php:161 +#: inc/email/class-opalestate-email-notifycation.php:38 +msgid "You got a message contact" +msgstr "" + +#: inc/email/class-opalestate-email-notifycation.php:34 +msgid "You got a message enquiry" +msgstr "" + +#: inc/email/class-opalestate-request-viewing.php:31 +#, php-format +msgid "You have a message request reviewing: %s at" +msgstr "" + +#: templates/user/favorite-properties.php:24 +msgid "You have not added any property as favorite." +msgstr "" + +#: templates/user-search/content-savedsearch.php:38 +msgid "You have not added any search data." +msgstr "" + +#: templates/user/my-properties.php:47 +msgid "You have not submited any property." +msgstr "" + +#: templates/user/dashboard.php:55 templates/user/property-ratings.php:11 +msgid "You have not written any reviews yet." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:511 +msgid "You have submitted the property successful" +msgstr "" + +#: templates/rating/opalestate-ratings.php:282 +msgid "You must be logged in to review." +msgstr "" + +#: inc/api/class-opalestate-api.php:423 +msgid "You must specify both a token and API key!" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:73 +msgid "" +"You need to register Google API " +"Key, then put the key in plugin setting." +msgstr "" + +#: inc/admin/settings/general.php:249 +msgid "" +"You need to register Google API " +"Key, then put the key in this setting." +msgstr "" + +#: inc/user/class-opalestate-user-search.php:144 +msgid "You saved this search" +msgstr "" + +#: inc/user/class-opalestate-user.php:263 +msgid "Your account is blocked, you could not complete this action" +msgstr "" + +#: inc/user/class-opalestate-user.php:251 +msgid "" +"Your account was blocked to use the submission form, so you could not submit " +"any property." +msgstr "" + +#: templates/parts/mortgage-calculator.php:140 +#: templates/widgets/mortgage-calculator.php:110 +msgid "Your deposit" +msgstr "" + +#: templates/parts/mortgage-calculator.php:141 +#: templates/widgets/mortgage-calculator.php:111 +msgid "Your interest" +msgstr "" + +#: inc/mixes-functions.php:324 inc/mixes-functions.php:328 +msgid "Your Location" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:424 +msgid "" +"Your membership package is expired or Your package has 0 left listing, " +"please upgrade now." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:289 +msgid "Your new password" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:292 +msgid "Your new password is: " +msgstr "" + +#: templates/parts/membership-warning.php:3 +msgid "" +"Your package has 0 left listing, you could not add any more. Please upgrade " +"now" +msgstr "" + +#: templates/parts/mortgage-calculator.php:24 +#: templates/parts/mortgage-calculator.php:125 +#: templates/widgets/mortgage-calculator.php:24 +#: templates/widgets/mortgage-calculator.php:119 +msgid "Your payment" +msgstr "" + +#: templates/parts/mortgage-calculator.php:139 +#: templates/widgets/mortgage-calculator.php:109 +msgid "Your price" +msgstr "" + +#: templates/rating/opalestate-ratings.php:260 +msgid "Your rating" +msgstr "" + +#: inc/api/class-opalestate-api.php:440 +msgid "Your request could not be authenticated!" +msgstr "" + +#: templates/rating/opalestate-ratings.php:270 +msgid "Your review" +msgstr "" + +#: templates/rating/opalestate-ratings.php:278 +msgid "Your review already exists!" +msgstr "" + +#: templates/rating/review-meta.php:14 +msgid "Your review is awaiting approval" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:214 +msgid "Youtube Url" +msgstr "" + +#: inc/mixes-functions.php:633 +msgid "Zambian kwacha" +msgstr "" + +#: inc/importer/class-content-importer.php:601 +msgid "Zero size file downloaded" +msgstr "" diff --git a/languages/opalestate-pro.pot b/languages/opalestate-pro.pot new file mode 100755 index 00000000..6da263ce --- /dev/null +++ b/languages/opalestate-pro.pot @@ -0,0 +1,6511 @@ +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Opal Estate Pro\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-09-03 02:50+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: \n" +"Language: \n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Loco https://localise.biz/\n" +"X-Loco-Version: 2.3.0; wp-5.2.2" + +#: opal-estate-pro.php:170 +msgid "Cheatin’ huh?" +msgstr "" + +#: inc/function-search-fields.php:80 templates/search-box/search-form-v3.php:61 +#: templates/search-box/search-form-v2.php:44 +msgid "Area" +msgstr "" + +#: inc/class-opalestate-enqueue.php:86 +msgid "Are you sure to remove?" +msgstr "" + +#: inc/class-opalestate-enqueue.php:87 +msgid "This file is has large volume size, please try to upload other." +msgstr "" + +#: inc/class-opalestate-email.php:135 inc/class-opalestate-email.php:138 +msgid "Message has been successfully sent." +msgstr "" + +#: inc/class-opalestate-email.php:170 +#: inc/classes/class-opalestate-metabox-user.php:154 +#: inc/classes/class-opalestate-metabox-user.php:219 +#: inc/agency/class-opalestate-agency-metabox.php:338 +#: inc/message/class-opalestate-message.php:530 +#: inc/message/class-opalestate-message.php:632 +#: inc/agent/class-opalestate-agent-metabox.php:177 +#: templates/rating/opalestate-ratings.php:239 +msgid "Email" +msgstr "" + +#: inc/class-opalestate-email.php:258 inc/class-opalestate-email.php:262 +#: inc/submission/class-opalestate-submission.php:121 +msgid "Email Settings" +msgstr "" + +#: inc/class-opalestate-email.php:269 +msgid "From Name" +msgstr "" + +#: inc/class-opalestate-email.php:270 +msgid "" +"The name donation receipts are said to come from. This should probably be " +"your site or shop name." +msgstr "" + +#: inc/class-opalestate-email.php:276 +msgid "From Email" +msgstr "" + +#: inc/class-opalestate-email.php:277 +msgid "" +"Email to send donation receipts from. This will act as the \"from\" and " +"\"reply-to\" address." +msgstr "" + +#: inc/class-opalestate-email.php:285 +msgid "Email Submission Templates (Template Tags)" +msgstr "" + +#: inc/class-opalestate-email.php:294 +msgid "Notification For New Property Submission" +msgstr "" + +#: inc/class-opalestate-email.php:303 inc/class-opalestate-email.php:342 +#: inc/class-opalestate-email.php:370 +msgid "Email Subject" +msgstr "" + +#: inc/class-opalestate-email.php:305 +msgid "The email subject for admin notifications." +msgstr "" + +#: inc/class-opalestate-email.php:310 inc/class-opalestate-email.php:349 +#: inc/email/class-opalesate-approve.php:31 +#: inc/email/class-opalestate-new-submitted.php:31 +msgid "New Property Listing Submitted: {property_name}" +msgstr "" + +#: inc/class-opalestate-email.php:315 inc/class-opalestate-email.php:354 +#: inc/class-opalestate-email.php:382 +msgid "Email Body" +msgstr "" + +#: inc/class-opalestate-email.php:317 +msgid "" +"Enter the email an admin should receive when an initial payment request is " +"made." +msgstr "" + +#: inc/class-opalestate-email.php:322 +msgid "Approve property for publish" +msgstr "" + +#: inc/class-opalestate-email.php:329 +msgid "Enable approve property email" +msgstr "" + +#: inc/class-opalestate-email.php:330 +msgid "Enable approve property email." +msgstr "" + +#: inc/class-opalestate-email.php:334 +#: inc/submission/class-opalestate-submission.php:179 +#: inc/submission/class-opalestate-submission.php:189 +#: inc/submission/class-opalestate-submission.php:199 +#: inc/submission/class-opalestate-submission.php:209 +#: inc/submission/class-opalestate-submission.php:219 +#: inc/submission/class-opalestate-submission.php:229 +#: inc/submission/class-opalestate-submission.php:239 +#: inc/vendors/social-login/class-opalestate-social-login.php:69 +#: inc/vendors/social-login/class-opalestate-social-login.php:106 +#: inc/admin/settings/property.php:65 inc/admin/settings/property.php:123 +#: inc/admin/settings/property.php:134 inc/admin/settings/property.php:172 +#: inc/admin/settings/property.php:248 inc/admin/settings/property.php:259 +#: inc/admin/settings/property.php:278 inc/admin/settings/property.php:289 +#: inc/admin/settings/property.php:311 inc/admin/settings/property.php:322 +#: inc/admin/settings/property.php:333 inc/admin/settings/property.php:344 +#: inc/admin/settings/property.php:355 inc/admin/settings/property.php:366 +#: inc/admin/settings/property.php:377 inc/admin/settings/property.php:388 +#: inc/admin/settings/property.php:399 inc/admin/settings/property.php:410 +#: inc/admin/settings/general.php:70 inc/admin/rating/class-rating.php:69 +#: inc/admin/rating/class-rating.php:79 inc/admin/rating/class-rating.php:89 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:171 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:171 +msgid "Enable" +msgstr "" + +#: inc/class-opalestate-email.php:335 +#: inc/submission/class-opalestate-submission.php:180 +#: inc/submission/class-opalestate-submission.php:190 +#: inc/submission/class-opalestate-submission.php:200 +#: inc/submission/class-opalestate-submission.php:210 +#: inc/submission/class-opalestate-submission.php:220 +#: inc/submission/class-opalestate-submission.php:230 +#: inc/submission/class-opalestate-submission.php:240 +#: inc/vendors/social-login/class-opalestate-social-login.php:70 +#: inc/vendors/social-login/class-opalestate-social-login.php:107 +#: inc/admin/settings/property.php:66 inc/admin/settings/property.php:124 +#: inc/admin/settings/property.php:135 inc/admin/settings/property.php:171 +#: inc/admin/settings/property.php:247 inc/admin/settings/property.php:258 +#: inc/admin/settings/property.php:277 inc/admin/settings/property.php:288 +#: inc/admin/settings/property.php:312 inc/admin/settings/property.php:323 +#: inc/admin/settings/property.php:334 inc/admin/settings/property.php:345 +#: inc/admin/settings/property.php:356 inc/admin/settings/property.php:367 +#: inc/admin/settings/property.php:378 inc/admin/settings/property.php:389 +#: inc/admin/settings/property.php:400 inc/admin/settings/property.php:411 +#: inc/admin/settings/general.php:71 inc/admin/rating/class-rating.php:70 +#: inc/admin/rating/class-rating.php:80 inc/admin/rating/class-rating.php:90 +msgid "Disable" +msgstr "" + +#: inc/class-opalestate-email.php:344 inc/class-opalestate-email.php:372 +msgid "" +"The email subject a user should receive when they make an initial property " +"request." +msgstr "" + +#: inc/class-opalestate-email.php:356 +msgid "" +"Enter the email a user should receive when they make an initial payment " +"request." +msgstr "" + +#: inc/class-opalestate-email.php:362 +msgid "Email Contact Templates (Template Tags)" +msgstr "" + +#: inc/class-opalestate-email.php:377 +#: inc/message/class-opalestate-message.php:103 +msgid "You got a message" +msgstr "" + +#: inc/class-opalestate-roles.php:49 +msgid "Opal Estate Manager" +msgstr "" + +#: inc/class-opalestate-roles.php:80 +msgid "Opal Estate Agent" +msgstr "" + +#: inc/class-opalestate-roles.php:92 +msgid "Opal Estate Agency" +msgstr "" + +#: inc/class-opalestate-install.php:142 +msgid "User Dashboard Page" +msgstr "" + +#: inc/class-opalestate-install.php:160 inc/user/class-opalestate-user.php:58 +msgid "My Account" +msgstr "" + +#: inc/class-opalestate-install.php:161 +msgid "[opalestate_myaccount]" +msgstr "" + +#: inc/class-opalestate-install.php:178 +#: inc/submission/class-opalestate-submission.php:131 +msgid "Property Submission Page" +msgstr "" + +#: inc/class-opalestate-install.php:179 +msgid "[opalestate_submission]" +msgstr "" + +#: inc/class-opalestate-install.php:196 +msgid "Search Map Properties Page" +msgstr "" + +#: inc/class-opalestate-install.php:197 +msgid "[opalestate_search_map_properties]" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:88 +msgid "The captcha is not verified, please try again!" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:101 +msgid "Show Captcha In Form" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:102 +msgid "" +"Enable google captch in contact , register form. After Set yes, you change " +"setting in Google Captcha Tab. Register here: https://www.google." +"com/recaptcha/admin Version 2" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:107 +#: inc/classes/class-opalestate-metabox-user.php:193 +#: inc/classes/class-opalestate-metabox-user.php:204 +#: inc/property/class-metabox-property-admin.php:181 +#: inc/property/class-metabox-property-admin.php:212 +#: inc/property/class-metabox-property-admin.php:278 +#: inc/property/class-metabox-property-admin.php:448 +#: inc/property/class-metabox-property-admin.php:458 +#: inc/agency/class-opalestate-agency-metabox.php:62 +#: inc/widgets/search-properties.php:147 +#: inc/submission/class-metabox-property-submission.php:394 +#: inc/submission/class-metabox-property-submission.php:474 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:235 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:249 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:273 +#: inc/vendors/opalmembership/free-package.php:35 +msgid "No" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:108 +#: inc/classes/class-opalestate-metabox-user.php:194 +#: inc/classes/class-opalestate-metabox-user.php:205 +#: inc/property/class-metabox-property-admin.php:182 +#: inc/property/class-metabox-property-admin.php:211 +#: inc/property/class-metabox-property-admin.php:279 +#: inc/agency/class-opalestate-agency-metabox.php:63 +#: inc/widgets/search-properties.php:148 +#: inc/submission/class-metabox-property-submission.php:395 +#: inc/submission/class-metabox-property-submission.php:475 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:234 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:248 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:272 +#: inc/vendors/opalmembership/free-package.php:34 +msgid "Yes" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:114 +msgid "Google Captcha page Settings" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:121 +msgid "Site Key" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:122 +#, php-format +msgid "Used for displaying the CAPTCHA. Grab it %s" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:128 +msgid "Secret key" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:129 +msgid "Used for communication between your site and Google. Grab it." +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:135 +msgid "Theme" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:136 +msgid "Display captcha box with color style." +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:140 +msgid "Light" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:141 +msgid "Dark" +msgstr "" + +#: inc/class-no-captcha-recaptcha.php:154 +msgid "Google Captcha" +msgstr "" + +#: inc/template-hook-functions.php:202 inc/template-hook-functions.php:245 +msgid "Request Viewing" +msgstr "" + +#: inc/template-hook-functions.php:242 +msgid "" +"Physical Arrange viewings is always been attractive to property clients. " +"Fill out the form to arrange visualizations around our properties." +msgstr "" + +#: inc/template-hook-functions.php:274 +msgid "User Management" +msgstr "" + +#: inc/template-hook-functions.php:275 +msgid "Opalestate Fullwidth" +msgstr "" + +#: inc/ajax-functions.php:97 inc/taxonomies/class-taxonomy-state.php:108 +#: inc/taxonomies/class-taxonomy-state.php:125 +msgid "Select State" +msgstr "" + +#: inc/ajax-functions.php:139 inc/taxonomies/class-taxonomy-city.php:132 +msgid "Select City" +msgstr "" + +#: inc/ajax-functions.php:213 inc/ajax-functions.php:218 +msgid "Could not set this as featured" +msgstr "" + +#: inc/class-opalestate-html.php:41 +msgid "Enter username" +msgstr "" + +#: inc/class-opalestate-html.php:56 +msgid "Cancel" +msgstr "" + +#: inc/class-opalestate-html.php:222 inc/template-functions.php:301 +#: templates/user/my-properties.php:3 +#: templates/search-box/fields/status-bar.php:9 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:152 +msgid "All" +msgstr "" + +#: inc/class-opalestate-html.php:223 +#: inc/property/class-metabox-property-admin.php:665 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:202 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:280 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:288 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:309 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:280 +msgid "None" +msgstr "" + +#: inc/mixes-functions.php:142 +msgid "Advanced V1 Form" +msgstr "" + +#: inc/mixes-functions.php:143 +msgid "Advanced V2 Form" +msgstr "" + +#: inc/mixes-functions.php:144 +msgid "Advanced V3 Form" +msgstr "" + +#: inc/mixes-functions.php:145 +msgid "Advanced V4 Form" +msgstr "" + +#: inc/mixes-functions.php:146 +msgid "Advanced V5 Form" +msgstr "" + +#: inc/mixes-functions.php:147 +msgid "Advanced V6 Form" +msgstr "" + +#: inc/mixes-functions.php:148 +msgid "Vertical Advanced Form" +msgstr "" + +#: inc/mixes-functions.php:149 +msgid "Vertical Advanced V2 Form" +msgstr "" + +#: inc/mixes-functions.php:150 +msgid "Vertical Advanced V3 Form" +msgstr "" + +#: inc/mixes-functions.php:151 +msgid "Simple City Form" +msgstr "" + +#: inc/mixes-functions.php:152 +msgid "Simple Keyword Form" +msgstr "" + +#: inc/mixes-functions.php:153 +msgid "Collapse City Form" +msgstr "" + +#: inc/mixes-functions.php:154 +msgid "Collapse Keyword Form" +msgstr "" + +#: inc/mixes-functions.php:165 inc/mixes-functions.php:181 +#: inc/template-functions.php:211 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:126 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:117 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:117 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:126 +msgid "Grid" +msgstr "" + +#: inc/mixes-functions.php:166 inc/mixes-functions.php:182 +msgid "Grid v2" +msgstr "" + +#: inc/mixes-functions.php:167 inc/mixes-functions.php:183 +msgid "Grid v3" +msgstr "" + +#: inc/mixes-functions.php:168 inc/mixes-functions.php:195 +#: inc/template-functions.php:215 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:127 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:118 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:118 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:127 +msgid "List" +msgstr "" + +#: inc/mixes-functions.php:169 inc/mixes-functions.php:196 +msgid "List v2" +msgstr "" + +#: inc/mixes-functions.php:170 inc/mixes-functions.php:184 +msgid "Mark hover" +msgstr "" + +#: inc/mixes-functions.php:295 +msgid "Orginal Size" +msgstr "" + +#: inc/mixes-functions.php:386 inc/mixes-functions.php:390 +msgid "Your Location" +msgstr "" + +#: inc/mixes-functions.php:512 +#, php-format +msgid "Placeholder %s" +msgstr "" + +#: inc/mixes-functions.php:545 +msgid "United Arab Emirates dirham" +msgstr "" + +#: inc/mixes-functions.php:546 +msgid "Afghan afghani" +msgstr "" + +#: inc/mixes-functions.php:547 +msgid "Albanian lek" +msgstr "" + +#: inc/mixes-functions.php:548 +msgid "Armenian dram" +msgstr "" + +#: inc/mixes-functions.php:549 +msgid "Netherlands Antillean guilder" +msgstr "" + +#: inc/mixes-functions.php:550 +msgid "Angolan kwanza" +msgstr "" + +#: inc/mixes-functions.php:551 +msgid "Argentine peso" +msgstr "" + +#: inc/mixes-functions.php:552 +msgid "Australian dollar" +msgstr "" + +#: inc/mixes-functions.php:553 +msgid "Aruban florin" +msgstr "" + +#: inc/mixes-functions.php:554 +msgid "Azerbaijani manat" +msgstr "" + +#: inc/mixes-functions.php:555 +msgid "Bosnia and Herzegovina convertible mark" +msgstr "" + +#: inc/mixes-functions.php:556 +msgid "Barbadian dollar" +msgstr "" + +#: inc/mixes-functions.php:557 +msgid "Bangladeshi taka" +msgstr "" + +#: inc/mixes-functions.php:558 +msgid "Bulgarian lev" +msgstr "" + +#: inc/mixes-functions.php:559 +msgid "Bahraini dinar" +msgstr "" + +#: inc/mixes-functions.php:560 +msgid "Burundian franc" +msgstr "" + +#: inc/mixes-functions.php:561 +msgid "Bermudian dollar" +msgstr "" + +#: inc/mixes-functions.php:562 +msgid "Brunei dollar" +msgstr "" + +#: inc/mixes-functions.php:563 +msgid "Bolivian boliviano" +msgstr "" + +#: inc/mixes-functions.php:564 +msgid "Brazilian real" +msgstr "" + +#: inc/mixes-functions.php:565 +msgid "Bahamian dollar" +msgstr "" + +#: inc/mixes-functions.php:566 +msgid "Bitcoin" +msgstr "" + +#: inc/mixes-functions.php:567 +msgid "Bhutanese ngultrum" +msgstr "" + +#: inc/mixes-functions.php:568 +msgid "Botswana pula" +msgstr "" + +#: inc/mixes-functions.php:569 +msgid "Belarusian ruble" +msgstr "" + +#: inc/mixes-functions.php:570 +msgid "Belize dollar" +msgstr "" + +#: inc/mixes-functions.php:571 +msgid "Canadian dollar" +msgstr "" + +#: inc/mixes-functions.php:572 +msgid "Congolese franc" +msgstr "" + +#: inc/mixes-functions.php:573 +msgid "Swiss franc" +msgstr "" + +#: inc/mixes-functions.php:574 +msgid "Chilean peso" +msgstr "" + +#: inc/mixes-functions.php:575 +msgid "Chinese yuan" +msgstr "" + +#: inc/mixes-functions.php:576 +msgid "Colombian peso" +msgstr "" + +#: inc/mixes-functions.php:577 +msgid "Costa Rican colón" +msgstr "" + +#: inc/mixes-functions.php:578 +msgid "Cuban convertible peso" +msgstr "" + +#: inc/mixes-functions.php:579 +msgid "Cuban peso" +msgstr "" + +#: inc/mixes-functions.php:580 +msgid "Cape Verdean escudo" +msgstr "" + +#: inc/mixes-functions.php:581 +msgid "Czech koruna" +msgstr "" + +#: inc/mixes-functions.php:582 +msgid "Djiboutian franc" +msgstr "" + +#: inc/mixes-functions.php:583 +msgid "Danish krone" +msgstr "" + +#: inc/mixes-functions.php:584 +msgid "Dominican peso" +msgstr "" + +#: inc/mixes-functions.php:585 +msgid "Algerian dinar" +msgstr "" + +#: inc/mixes-functions.php:586 +msgid "Egyptian pound" +msgstr "" + +#: inc/mixes-functions.php:587 +msgid "Eritrean nakfa" +msgstr "" + +#: inc/mixes-functions.php:588 +msgid "Ethiopian birr" +msgstr "" + +#: inc/mixes-functions.php:589 +msgid "Euro" +msgstr "" + +#: inc/mixes-functions.php:590 +msgid "Fijian dollar" +msgstr "" + +#: inc/mixes-functions.php:591 +msgid "Falkland Islands pound" +msgstr "" + +#: inc/mixes-functions.php:592 +msgid "Pound sterling" +msgstr "" + +#: inc/mixes-functions.php:593 +msgid "Georgian lari" +msgstr "" + +#: inc/mixes-functions.php:594 +msgid "Guernsey pound" +msgstr "" + +#: inc/mixes-functions.php:595 +msgid "Ghana cedi" +msgstr "" + +#: inc/mixes-functions.php:596 +msgid "Gibraltar pound" +msgstr "" + +#: inc/mixes-functions.php:597 +msgid "Gambian dalasi" +msgstr "" + +#: inc/mixes-functions.php:598 +msgid "Guinean franc" +msgstr "" + +#: inc/mixes-functions.php:599 +msgid "Guatemalan quetzal" +msgstr "" + +#: inc/mixes-functions.php:600 +msgid "Guyanese dollar" +msgstr "" + +#: inc/mixes-functions.php:601 +msgid "Hong Kong dollar" +msgstr "" + +#: inc/mixes-functions.php:602 +msgid "Honduran lempira" +msgstr "" + +#: inc/mixes-functions.php:603 +msgid "Croatian kuna" +msgstr "" + +#: inc/mixes-functions.php:604 +msgid "Haitian gourde" +msgstr "" + +#: inc/mixes-functions.php:605 +msgid "Hungarian forint" +msgstr "" + +#: inc/mixes-functions.php:606 +msgid "Indonesian rupiah" +msgstr "" + +#: inc/mixes-functions.php:607 +msgid "Israeli new shekel" +msgstr "" + +#: inc/mixes-functions.php:608 +msgid "Manx pound" +msgstr "" + +#: inc/mixes-functions.php:609 +msgid "Indian rupee" +msgstr "" + +#: inc/mixes-functions.php:610 +msgid "Iraqi dinar" +msgstr "" + +#: inc/mixes-functions.php:611 +msgid "Iranian rial" +msgstr "" + +#: inc/mixes-functions.php:612 +msgid "Icelandic króna" +msgstr "" + +#: inc/mixes-functions.php:613 +msgid "Jersey pound" +msgstr "" + +#: inc/mixes-functions.php:614 +msgid "Jamaican dollar" +msgstr "" + +#: inc/mixes-functions.php:615 +msgid "Jordanian dinar" +msgstr "" + +#: inc/mixes-functions.php:616 +msgid "Japanese yen" +msgstr "" + +#: inc/mixes-functions.php:617 +msgid "Kenyan shilling" +msgstr "" + +#: inc/mixes-functions.php:618 +msgid "Kyrgyzstani som" +msgstr "" + +#: inc/mixes-functions.php:619 +msgid "Cambodian riel" +msgstr "" + +#: inc/mixes-functions.php:620 +msgid "Comorian franc" +msgstr "" + +#: inc/mixes-functions.php:621 +msgid "North Korean won" +msgstr "" + +#: inc/mixes-functions.php:622 +msgid "South Korean won" +msgstr "" + +#: inc/mixes-functions.php:623 +msgid "Kuwaiti dinar" +msgstr "" + +#: inc/mixes-functions.php:624 +msgid "Cayman Islands dollar" +msgstr "" + +#: inc/mixes-functions.php:625 +msgid "Kazakhstani tenge" +msgstr "" + +#: inc/mixes-functions.php:626 +msgid "Lao kip" +msgstr "" + +#: inc/mixes-functions.php:627 +msgid "Lebanese pound" +msgstr "" + +#: inc/mixes-functions.php:628 +msgid "Sri Lankan rupee" +msgstr "" + +#: inc/mixes-functions.php:629 +msgid "Liberian dollar" +msgstr "" + +#: inc/mixes-functions.php:630 +msgid "Lesotho loti" +msgstr "" + +#: inc/mixes-functions.php:631 +msgid "Libyan dinar" +msgstr "" + +#: inc/mixes-functions.php:632 +msgid "Moroccan dirham" +msgstr "" + +#: inc/mixes-functions.php:633 +msgid "Moldovan leu" +msgstr "" + +#: inc/mixes-functions.php:634 +msgid "Malagasy ariary" +msgstr "" + +#: inc/mixes-functions.php:635 +msgid "Macedonian denar" +msgstr "" + +#: inc/mixes-functions.php:636 +msgid "Burmese kyat" +msgstr "" + +#: inc/mixes-functions.php:637 +msgid "Mongolian tögrög" +msgstr "" + +#: inc/mixes-functions.php:638 +msgid "Macanese pataca" +msgstr "" + +#: inc/mixes-functions.php:639 +msgid "Mauritanian ouguiya" +msgstr "" + +#: inc/mixes-functions.php:640 +msgid "Mauritian rupee" +msgstr "" + +#: inc/mixes-functions.php:641 +msgid "Maldivian rufiyaa" +msgstr "" + +#: inc/mixes-functions.php:642 +msgid "Malawian kwacha" +msgstr "" + +#: inc/mixes-functions.php:643 +msgid "Mexican peso" +msgstr "" + +#: inc/mixes-functions.php:644 +msgid "Malaysian ringgit" +msgstr "" + +#: inc/mixes-functions.php:645 +msgid "Mozambican metical" +msgstr "" + +#: inc/mixes-functions.php:646 +msgid "Namibian dollar" +msgstr "" + +#: inc/mixes-functions.php:647 +msgid "Nigerian naira" +msgstr "" + +#: inc/mixes-functions.php:648 +msgid "Nicaraguan córdoba" +msgstr "" + +#: inc/mixes-functions.php:649 +msgid "Norwegian krone" +msgstr "" + +#: inc/mixes-functions.php:650 +msgid "Nepalese rupee" +msgstr "" + +#: inc/mixes-functions.php:651 +msgid "New Zealand dollar" +msgstr "" + +#: inc/mixes-functions.php:652 +msgid "Omani rial" +msgstr "" + +#: inc/mixes-functions.php:653 +msgid "Panamanian balboa" +msgstr "" + +#: inc/mixes-functions.php:654 +msgid "Peruvian nuevo sol" +msgstr "" + +#: inc/mixes-functions.php:655 +msgid "Papua New Guinean kina" +msgstr "" + +#: inc/mixes-functions.php:656 +msgid "Philippine peso" +msgstr "" + +#: inc/mixes-functions.php:657 +msgid "Pakistani rupee" +msgstr "" + +#: inc/mixes-functions.php:658 +msgid "Polish złoty" +msgstr "" + +#: inc/mixes-functions.php:659 +msgid "Transnistrian ruble" +msgstr "" + +#: inc/mixes-functions.php:660 +msgid "Paraguayan guaraní" +msgstr "" + +#: inc/mixes-functions.php:661 +msgid "Qatari riyal" +msgstr "" + +#: inc/mixes-functions.php:662 +msgid "Romanian leu" +msgstr "" + +#: inc/mixes-functions.php:663 +msgid "Serbian dinar" +msgstr "" + +#: inc/mixes-functions.php:664 +msgid "Russian ruble" +msgstr "" + +#: inc/mixes-functions.php:665 +msgid "Rwandan franc" +msgstr "" + +#: inc/mixes-functions.php:666 +msgid "Saudi riyal" +msgstr "" + +#: inc/mixes-functions.php:667 +msgid "Solomon Islands dollar" +msgstr "" + +#: inc/mixes-functions.php:668 +msgid "Seychellois rupee" +msgstr "" + +#: inc/mixes-functions.php:669 +msgid "Sudanese pound" +msgstr "" + +#: inc/mixes-functions.php:670 +msgid "Swedish krona" +msgstr "" + +#: inc/mixes-functions.php:671 +msgid "Singapore dollar" +msgstr "" + +#: inc/mixes-functions.php:672 +msgid "Saint Helena pound" +msgstr "" + +#: inc/mixes-functions.php:673 +msgid "Sierra Leonean leone" +msgstr "" + +#: inc/mixes-functions.php:674 +msgid "Somali shilling" +msgstr "" + +#: inc/mixes-functions.php:675 +msgid "Surinamese dollar" +msgstr "" + +#: inc/mixes-functions.php:676 +msgid "South Sudanese pound" +msgstr "" + +#: inc/mixes-functions.php:677 +msgid "São Tomé and Príncipe dobra" +msgstr "" + +#: inc/mixes-functions.php:678 +msgid "Syrian pound" +msgstr "" + +#: inc/mixes-functions.php:679 +msgid "Swazi lilangeni" +msgstr "" + +#: inc/mixes-functions.php:680 +msgid "Thai baht" +msgstr "" + +#: inc/mixes-functions.php:681 +msgid "Tajikistani somoni" +msgstr "" + +#: inc/mixes-functions.php:682 +msgid "Turkmenistan manat" +msgstr "" + +#: inc/mixes-functions.php:683 +msgid "Tunisian dinar" +msgstr "" + +#: inc/mixes-functions.php:684 +msgid "Tongan paʻanga" +msgstr "" + +#: inc/mixes-functions.php:685 +msgid "Turkish lira" +msgstr "" + +#: inc/mixes-functions.php:686 +msgid "Trinidad and Tobago dollar" +msgstr "" + +#: inc/mixes-functions.php:687 +msgid "New Taiwan dollar" +msgstr "" + +#: inc/mixes-functions.php:688 +msgid "Tanzanian shilling" +msgstr "" + +#: inc/mixes-functions.php:689 +msgid "Ukrainian hryvnia" +msgstr "" + +#: inc/mixes-functions.php:690 +msgid "Ugandan shilling" +msgstr "" + +#: inc/mixes-functions.php:691 +msgid "United States dollar" +msgstr "" + +#: inc/mixes-functions.php:692 +msgid "Uruguayan peso" +msgstr "" + +#: inc/mixes-functions.php:693 +msgid "Uzbekistani som" +msgstr "" + +#: inc/mixes-functions.php:694 +msgid "Venezuelan bolívar" +msgstr "" + +#: inc/mixes-functions.php:695 +msgid "Vietnamese đồng" +msgstr "" + +#: inc/mixes-functions.php:696 +msgid "Vanuatu vatu" +msgstr "" + +#: inc/mixes-functions.php:697 +msgid "Samoan tālā" +msgstr "" + +#: inc/mixes-functions.php:698 +msgid "Central African CFA franc" +msgstr "" + +#: inc/mixes-functions.php:699 +msgid "East Caribbean dollar" +msgstr "" + +#: inc/mixes-functions.php:700 +msgid "West African CFA franc" +msgstr "" + +#: inc/mixes-functions.php:701 +msgid "CFP franc" +msgstr "" + +#: inc/mixes-functions.php:702 +msgid "Yemeni rial" +msgstr "" + +#: inc/mixes-functions.php:703 +msgid "South African rand" +msgstr "" + +#: inc/mixes-functions.php:704 +msgid "Zambian kwacha" +msgstr "" + +#: inc/template-functions.php:177 +msgid "Featured Desending" +msgstr "" + +#: inc/template-functions.php:178 +msgid "Price Ascending" +msgstr "" + +#: inc/template-functions.php:179 +msgid "Price Desending" +msgstr "" + +#: inc/template-functions.php:180 +msgid "Area Ascending" +msgstr "" + +#: inc/template-functions.php:181 +msgid "Area Desending" +msgstr "" + +#: inc/template-functions.php:185 +msgid "Sort By" +msgstr "" + +#: inc/template-functions.php:261 +msgid "Previous" +msgstr "" + +#: inc/template-functions.php:272 +msgid "Next" +msgstr "" + +#: inc/template-functions.php:381 +msgid "Vesion 2" +msgstr "" + +#: inc/template-functions.php:382 +msgid "Vesion 3" +msgstr "" + +#: inc/template-functions.php:383 +msgid "Vesion 4" +msgstr "" + +#: inc/template-functions.php:384 +msgid "Vesion 5" +msgstr "" + +#: inc/template-functions.php:406 +#: inc/property/class-metabox-property-admin.php:536 +#: inc/admin/settings/general.php:178 +msgid "Inherit" +msgstr "" + +#: inc/template-functions.php:407 +msgid "Gallery Thumb Nav" +msgstr "" + +#: inc/template-functions.php:408 +msgid "Gallery Slider" +msgstr "" + +#: inc/template-functions.php:409 +msgid "Maps" +msgstr "" + +#: inc/template-functions.php:410 +msgid "Tabs - Gallery Active" +msgstr "" + +#: inc/template-functions.php:411 +msgid "Tabs - Map Active" +msgstr "" + +#: inc/template-functions.php:412 +msgid "Tabs - Street Map Active" +msgstr "" + +#: inc/template-functions.php:413 +msgid "Tour 360" +msgstr "" + +#: inc/template-functions.php:414 +msgid "Gallery Metro" +msgstr "" + +#: inc/template-functions.php:415 +msgid "Mark Picture" +msgstr "" + +#: inc/template-functions.php:649 inc/admin/settings/3rd_party.php:129 +msgid "miles" +msgstr "" + +#: inc/template-functions.php:653 +msgid "km" +msgstr "" + +#: inc/template-functions.php:764 +msgid "Similar Properties You May Like" +msgstr "" + +#: inc/template-functions.php:807 +msgid "New Listings Nearby" +msgstr "" + +#. %s: rating +#: inc/template-functions.php:843 inc/template-functions.php:869 +#, php-format +msgid "Rated %s out of 5" +msgstr "" + +#. 1: rating 2: rating count +#: inc/template-functions.php:863 +#, php-format +msgid "Rated %1$s out of 5 based on %2$s customer rating" +msgid_plural "Rated %1$s out of 5 based on %2$s customer ratings" +msgstr[0] "" +msgstr[1] "" + +#. %s number of reviews +#: inc/template-functions.php:975 templates/rating/opalestate-ratings.php:173 +#, php-format +msgctxt "review numbers" +msgid "%s review" +msgid_plural "%s reviews" +msgstr[0] "" +msgstr[1] "" + +#: inc/template-functions.php:1025 inc/template-functions.php:1027 +msgid "Print" +msgstr "" + +#: templates/content-single-property-print.php:50 +#: templates/content-single-property-v2.php:87 +#: templates/content-single-property-v3.php:77 +#: templates/content-single-property-v4.php:57 +#: templates/content-single-property-v5.php:90 +#: templates/content-single-property.php:62 +msgid "Property Description" +msgstr "" + +#: templates/content-single-property-print.php:55 +#: templates/content-single-property-v2.php:93 +#: templates/content-single-property-v3.php:82 +#: templates/content-single-property-v4.php:63 +#: templates/content-single-property-v5.php:96 +#: templates/content-single-property.php:68 +msgid "Property ID: " +msgstr "" + +#. %s: property date +#: templates/content-single-property-v2.php:42 +#: templates/content-single-property-v3.php:66 +#: templates/content-single-property-v4.php:39 +#: templates/content-single-property-v5.php:79 +#: templates/content-single-property.php:37 +#, php-format +msgid "Posted: %s" +msgstr "" + +#: templates/content-single-property-v2.php:67 +#: templates/content-single-property-v5.php:16 +#: templates/content-property-list.php:59 +#: templates/content-single-agency.php:23 +#: templates/content-single-agency.php:44 templates/content-single-agent.php:16 +#: inc/rating/class-opalestate-rating-metabox.php:110 +#: inc/submission/class-metabox-property-submission.php:110 +#: templates/single-property/content.php:2 +msgid "Description" +msgstr "" + +#: templates/content-single-property-v2.php:68 +#: inc/property/class-metabox-property-admin.php:61 +#: inc/agency/class-opalestate-agency-metabox.php:141 +#: inc/agency/class-opalestate-agency-metabox.php:269 +#: inc/agent/class-opalestate-agent-metabox.php:100 +#: inc/submission/class-metabox-property-submission.php:65 +#: templates/search-box/search-form-v3.php:51 +#: templates/search-box/search-form-v2.php:34 +msgid "Information" +msgstr "" + +#: templates/content-single-property-v2.php:69 +#: templates/content-single-property-v5.php:33 +#: inc/submission/class-metabox-property-submission.php:549 +#: templates/single-property/floor-plans.php:15 +msgid "Floor Plans" +msgstr "" + +#: templates/content-single-property-v2.php:70 +msgid "Attachment" +msgstr "" + +#: templates/content-single-property-v2.php:126 +#: inc/property/class-metabox-property-admin.php:303 +#: templates/single-property/features.php:11 +msgid "Property Information" +msgstr "" + +#: templates/content-single-property-v2.php:137 +msgid "Property Attachments" +msgstr "" + +#: templates/fullwidth-page.php:29 templates/content-single-agent.php:63 +#: templates/single-property/content.php:11 +msgid "Pages:" +msgstr "" + +#: templates/fullwidth-page.php:33 +msgid "Page" +msgstr "" + +#: templates/content-agent-list.php:12 templates/content-agent-grid.php:10 +#: templates/content-agent-grid-v2.php:9 templates/content-user-grid.php:42 +#: templates/single-agent/author-box.php:16 +msgid "Featured Agent" +msgstr "" + +#: templates/content-agent-list.php:14 templates/content-agent-grid.php:12 +#: templates/content-agent-grid-v2.php:11 templates/content-user-grid.php:44 +#: templates/content-agency-grid.php:14 templates/content-agency-list.php:15 +#: inc/property/class-metabox-property-admin.php:177 +#: templates/single-agent/author-box.php:18 +#: templates/user/content-property.php:19 +#: templates/single-agency/author-box.php:24 +#: templates/parts/featured-label.php:9 +#: inc/admin/property/class-property.php:99 +msgid "Featured" +msgstr "" + +#: templates/content-agent-list.php:26 templates/content-agent-list.php:27 +#: templates/content-agent-grid.php:17 templates/content-agent-grid.php:17 +#: templates/content-agent-grid-v2.php:17 +#: templates/content-agent-grid-v2.php:17 templates/content-user-grid.php:49 +#: templates/content-user-grid.php:49 templates/content-agency-grid.php:20 +#: templates/content-agency-grid.php:20 templates/content-agency-list.php:28 +#: templates/content-agency-list.php:29 +#: templates/single-agent/author-box.php:24 +#: templates/single-agent/author-box.php:25 +#: templates/single-agency/author-box.php:30 +#: templates/single-agency/author-box.php:30 +#: templates/single-property/user/author-member-box.php:28 +#: templates/single-property/user/author-member-box.php:28 +#: templates/single-property/user/author-user-box.php:66 +#: templates/single-property/user/author-user-box.php:67 +#: templates/single-property/user/author-user-box-list.php:51 +#: templates/single-property/user/author-user-box-list.php:52 +msgid "Trusted Member" +msgstr "" + +#: templates/content-single-property-v5.php:18 +#: inc/property/class-metabox-property-admin.php:228 +#: inc/submission/class-metabox-property-submission.php:203 +#: templates/single-property/video.php:12 +msgid "Video" +msgstr "" + +#: templates/content-single-property-v5.php:21 +#: templates/single-property/map.php:25 templates/single-property/map-v2.php:21 +#: templates/single-property/preview/tabs.php:17 +msgid "Map" +msgstr "" + +#: templates/content-single-property-v5.php:24 +msgid "Scores" +msgstr "" + +#: templates/content-single-property-v5.php:27 +msgid "Statistics" +msgstr "" + +#: templates/content-single-property-v5.php:30 +#: inc/property/class-metabox-property-admin.php:83 +#: inc/submission/class-metabox-property-submission.php:68 +#: inc/submission/class-metabox-property-submission.php:470 +#: templates/single-property/apartments.php:14 +msgid "Apartments" +msgstr "" + +#: templates/content-single-property-v5.php:35 inc/user/functions.php:144 +#: inc/user/functions.php:151 +msgid "Reviews" +msgstr "" + +#: templates/archive-opalestate_agency.php:12 +msgid "Find A Local Real Estate Agencies" +msgstr "" + +#: templates/archive-opalestate_agency.php:13 +msgid "" +"Reality Agencies are local expert who can get you better results for lower " +"fees" +msgstr "" + +#: templates/archive-opalestate_agency.php:38 +#: templates/elementor-templates/opalestate-agency-collection.php:26 +#, php-format +msgid "Found %s Agency" +msgstr "" + +#: templates/content-no-results.php:3 +msgid "Nothing Found" +msgstr "" + +#: templates/content-no-results.php:6 +msgid "" +"It seems we can’t find what you’re looking for. Perhaps " +"searching can help." +msgstr "" + +#: templates/archive-opalestate_agent.php:11 +msgid "Find The Best Real Estate Agent For Your" +msgstr "" + +#: templates/archive-opalestate_agent.php:12 +msgid "" +"Browser home sales, rating and review to find the best agent to sell or " +"lease your home" +msgstr "" + +#: templates/archive-opalestate_agent.php:37 +#: templates/elementor-templates/opalestate-agent-collection.php:29 +#: templates/shortcodes/search-agents.php:15 +#, php-format +msgid "Found %s Agents" +msgstr "" + +#: templates/user-management.php:50 templates/user/read-messages.php:16 +#: templates/user/read-messages.php:28 templates/user/messages.php:16 +msgid "User Avatar" +msgstr "" + +#: templates/user-management.php:117 +msgid "Login to your account" +msgstr "" + +#: templates/user-management.php:118 +msgid "" +"Logining in allows you to edit your property or submit a property, save " +"favorite real estate." +msgstr "" + +#: templates/content-agency-grid.php:13 templates/content-agency-list.php:14 +#: templates/single-agency/author-box.php:22 +#: templates/single-agency/author-box.php:23 +msgid "Featured Agency" +msgstr "" + +#: templates/content-single-agency.php:24 +#: templates/content-single-agency.php:66 +#: inc/classes/class-opalestate-metabox-user.php:110 +#: inc/property/class-metabox-property-admin.php:217 +#: inc/submission/class-metabox-property-submission.php:382 +#: inc/admin/property/class-property.php:101 +msgid "Address" +msgstr "" + +#: templates/content-single-agency.php:26 +msgid "Listing" +msgstr "" + +#: templates/content-single-agency.php:27 +#: templates/content-single-agency.php:101 templates/single-agency/tabs.php:11 +#: inc/admin/agency/class-agency.php:144 +msgid "Team" +msgstr "" + +#. %s: Name of current post +#: templates/content-single-agency.php:50 templates/content-single-agent.php:58 +#, php-format +msgid "Continue reading %s" +msgstr "" + +#: templates/content-single-agency.php:71 +msgid "Head Agency:" +msgstr "" + +#: templates/content-single-agency.php:76 templates/content-single-agent.php:84 +msgid "Location:" +msgstr "" + +#: templates/content-single-agency.php:110 +#: templates/content-single-agent.php:18 +#: inc/property/class-opalestate-posttype.php:41 +#: inc/property/class-opalestate-posttype.php:53 +#: templates/single-agency/tabs.php:6 +msgid "Properties" +msgstr "" + +#: templates/content-single-agency.php:138 +msgid "Contact Us" +msgstr "" + +#: templates/content-single-agency.php:139 +#, php-format +msgid "Hi %s. I saw your profile and wanted to see if you could help me." +msgstr "" + +#: templates/content-single-agent.php:17 templates/single-agency/tabs.php:17 +#: inc/admin/rating/class-rating.php:46 +msgid "Review" +msgstr "" + +#: templates/content-single-agent.php:54 +msgid "About the Agent" +msgstr "" + +#: templates/content-single-agent.php:75 +msgid "My Address" +msgstr "" + +#: templates/content-single-agent.php:79 +msgid "Address:" +msgstr "" + +#: inc/rating/class-opalestate-rating-init.php:96 +msgid "Please rate all features." +msgstr "" + +#: inc/rating/class-opalestate-rating-init.php:102 +msgid "Please rate." +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:52 +msgctxt "Feature plural name" +msgid "Rating Features" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:53 +msgctxt "Feature singular name" +msgid "Rating Feature" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:54 +msgctxt "Admin menu name" +msgid "Rating Features" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:55 +msgid "Add rating feature" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:56 +msgid "Add new rating feature" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:57 +#: templates/user/content-property.php:77 +#: inc/vendors/opalmembership/membership.php:508 +msgid "Edit" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:58 +msgid "Edit rating feature" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:59 +msgid "New rating feature" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:60 +msgid "View rating feature" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:61 +msgid "Query rating features" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:62 +msgid "No rating features found" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:63 +msgid "No rating features found in trash" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:64 +msgid "Parent rating features" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:65 +msgid "Filter rating features" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:66 +msgid "Rating Features navigation" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:67 +msgid "Rating Features List" +msgstr "" + +#: inc/rating/class-opalestate-rating-features-posttype.php:69 +msgid "This is where store rating features are stored." +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:57 +msgid "Rating features" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:57 +msgid "Rating" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:105 +msgid "Data" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:116 +#: inc/taxonomies/class-taxonomy-status.php:87 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:224 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:192 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:213 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:193 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:193 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:224 +msgid "Order" +msgstr "" + +#: inc/rating/class-opalestate-rating-metabox.php:117 +#: inc/taxonomies/class-taxonomy-status.php:88 +msgid "Set a priority to display" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:166 +msgid "Active Life" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:170 +msgid "Arts & Entertainment" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:174 +msgid "Automotive" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:178 +msgid "Beauty & Spas" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:182 +msgid "Education" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:186 +msgid "Event Planning & Services" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:190 +msgid "Financial Services" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:194 +msgid "Food" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:198 +msgid "Health & Medical" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:202 +msgid "Home Services " +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:206 +msgid "Hotels & Travel" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:210 +msgid "Local Flavor" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:214 +msgid "Local Services" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:218 +msgid "Mass Media" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:222 +msgid "Nightlife" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:226 +msgid "Pets" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:230 +msgid "Professional Services" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:234 +msgid "Public Services & Government" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:238 +msgid "Real Estate" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:242 +msgid "Religious Organizations" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:246 +msgid "Restaurants" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:250 +#: templates/single-property/map.php:73 templates/single-property/map-v2.php:75 +#: templates/single-property/preview/tabs.php:69 +#: templates/single-property/preview/map.php:43 +msgid "Shopping" +msgstr "" + +#: inc/classes/class-opalestate-yelp.php:254 +msgid "Transportation" +msgstr "" + +#: inc/classes/class-opalestate-cache.php:150 +#, php-format +msgid "" +"In order for database caching to work with Give you must " +"add %1$s to the \"Ignored query stems\" option in W3 Total " +"Cache settings." +msgstr "" + +#: inc/classes/class-opalestate-cache.php:170 +msgid "Do not pass empty action to generate cache key." +msgstr "" + +#: inc/classes/class-opalestate-cache.php:203 +msgid "Do not pass invalid empty cache key" +msgstr "" + +#: inc/classes/class-opalestate-cache.php:205 +#: inc/classes/class-opalestate-cache.php:246 +#: inc/classes/class-opalestate-cache.php:295 +msgid "Cache key format should be opalestate_cache_*" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:23 +#: inc/classes/class-opalestate-metabox-user.php:32 +#: inc/agency/class-opalestate-agency-metabox.php:100 +#: inc/agency/class-opalestate-agency-metabox.php:311 +#: inc/agency/class-opalestate-agency-metabox.php:321 +#: inc/agent/class-opalestate-agent-metabox.php:157 +#: inc/agent/class-opalestate-agent-metabox.php:167 +msgid "Avatar Picture" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:24 +#: inc/classes/class-opalestate-metabox-user.php:33 +#: inc/classes/class-opalestate-metabox-user.php:74 +#: inc/classes/class-opalestate-metabox-user.php:211 +#: inc/agency/class-opalestate-agency-metabox.php:101 +#: inc/agency/class-opalestate-agency-metabox.php:312 +#: inc/agency/class-opalestate-agency-metabox.php:322 +#: inc/agent/class-opalestate-agent-metabox.php:158 +#: inc/agent/class-opalestate-agent-metabox.php:168 +msgid "This image will display in user detail and profile box information" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:43 +#: inc/agency/class-opalestate-agency-metabox.php:111 +msgid "First Name" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:51 +#: inc/agency/class-opalestate-agency-metabox.php:121 +msgid "Last Name" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:59 +#: inc/agency/class-opalestate-agency-metabox.php:130 +msgid "Biographical Info" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:61 +#: inc/agency/class-opalestate-agency-metabox.php:132 +msgid "" +"Share a little biographical information to fill out your profile. This may " +"be shown publicly." +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:73 +#: inc/classes/class-opalestate-metabox-user.php:210 +msgid "Avatar Pictures" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:86 +#: inc/property/class-metabox-property-admin.php:194 +#: inc/submission/class-metabox-property-submission.php:64 +#: templates/search-box/search-form-v3.php:28 +#: templates/search-box/fields/search-city-text.php:23 +#: templates/search-box/fields/location.php:1 +#: templates/search-box/fields/location.php:2 +msgid "Location" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:87 +#: inc/agency/class-opalestate-agency-metabox.php:37 +#: inc/agency/class-opalestate-agency-metabox.php:280 +#: inc/agency/class-opalestate-agency-metabox.php:332 +#: inc/agent/class-opalestate-agent-metabox.php:65 +#: inc/agent/class-opalestate-agent-metabox.php:111 +#: inc/admin/agency/class-agency.php:73 +msgid "Select one, to add new you create in location of estate panel" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:95 +#: inc/taxonomies/class-taxonomy-city.php:96 +msgid "State / Province" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:96 +msgid "Select one, to add new you create in state of estate panel" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:102 +#: inc/submission/class-metabox-property-submission.php:369 +msgid "City / Town" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:103 +msgid "Select one, to add new you create in city of estate panel" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:119 +msgid "Map Location" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:133 +msgid "Job" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:139 +msgid "Company" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:160 +#: inc/classes/class-opalestate-metabox-user.php:225 +#: inc/agency/class-opalestate-agency-metabox.php:344 +#: inc/agent/class-opalestate-agent-metabox.php:183 +msgid "Website" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:165 +#: inc/classes/class-opalestate-metabox-user.php:230 +#: inc/agency/class-opalestate-agency-metabox.php:159 +#: inc/agency/class-opalestate-agency-metabox.php:349 +#: inc/message/class-opalestate-message.php:539 +#: inc/message/class-opalestate-message.php:641 +#: inc/message/class-opalestate-message.php:716 +#: inc/agent/class-opalestate-agent-metabox.php:188 +msgid "Phone" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:171 +#: inc/classes/class-opalestate-metabox-user.php:236 +#: inc/agency/class-opalestate-agency-metabox.php:355 +#: inc/agent/class-opalestate-agent-metabox.php:194 +msgid "Mobile" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:177 +#: inc/classes/class-opalestate-metabox-user.php:242 +#: inc/agency/class-opalestate-agency-metabox.php:361 +#: inc/agent/class-opalestate-agent-metabox.php:200 +msgid "Fax" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:189 +#: inc/agency/class-opalestate-agency-metabox.php:58 +msgid "Is Featured" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:191 +msgid "Set member as featured" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:200 +msgid "Trusted" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:202 +msgid "Set this member as Trusted Member" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:253 +msgid "Twitter" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:260 +#: inc/agency/class-opalestate-agency-metabox.php:181 +#: inc/vendors/social-login/class-opalestate-social-login.php:93 +#: templates/user/social-login/facebook-button.php:19 +msgid "Facebook" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:266 +#: inc/vendors/social-login/class-opalestate-social-login.php:57 +#: templates/user/social-login/google-button.php:19 +msgid "Google" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:272 +msgid "LinkedIn" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:278 +msgid "Pinterest" +msgstr "" + +#: inc/classes/class-opalestate-metabox-user.php:283 +msgid "Instagram" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:38 +msgid "Search Properties Result" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:39 +#: inc/widgets/search-properties.php:57 +msgid "Search Properties" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:40 +msgid "Search Properties Vertical" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:42 +msgid "Search Map Properties" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:43 +#: inc/property/class-opalestate-shortcodes.php:44 +msgid "Ajax Search Map Properties" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:45 +msgid "Register User Form" +msgstr "" + +#: inc/property/class-opalestate-shortcodes.php:46 +msgid "Login Form" +msgstr "" + +#: inc/property/class-opalestate-search.php:392 +msgid "Bed Rooms" +msgstr "" + +#: inc/property/class-opalestate-search.php:393 +#: inc/property/class-metabox-property-admin.php:309 +#: inc/submission/class-metabox-property-submission.php:247 +msgid "Parking" +msgstr "" + +#: inc/property/class-opalestate-search.php:394 +msgid "Bath Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:28 +msgid "Property Metabox" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:47 +#: inc/admin/register-settings.php:110 inc/admin/class-user.php:105 +#: inc/submission/class-metabox-property-submission.php:61 +#: inc/admin/settings/property.php:21 inc/admin/agency/class-agency.php:129 +#: inc/admin/agent/class-agent.php:80 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:212 +msgid "General" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:54 +msgid "Prices" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:68 +msgid "Facility" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:76 +msgid "Floor Plan" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:91 +#: inc/agency/class-opalestate-agency-metabox.php:331 +#: templates/single-agency/gallery.php:10 inc/admin/agency/class-agency.php:72 +#: templates/single-property/preview/tabs.php:15 +msgid "Gallery" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:95 +#: inc/submission/class-metabox-property-submission.php:195 +msgid "Images Gallery" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:97 +#: inc/property/class-metabox-property-admin.php:111 +#: inc/agency/class-opalestate-agency-metabox.php:307 +#: inc/agent/class-opalestate-agent-metabox.php:153 +#: inc/submission/class-metabox-property-submission.php:188 +#: inc/submission/class-metabox-property-submission.php:197 +msgid "Select one or more images to show as gallery" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:104 +msgid "Virtual Tour 360" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:109 +msgid "Manual Images 360 " +msgstr "" + +#: inc/property/class-metabox-property-admin.php:115 +msgid "Or 360° Virtual Tour" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:117 +#: inc/property/class-metabox-property-admin.php:606 +#: inc/submission/class-metabox-property-submission.php:212 +#: inc/submission/class-metabox-property-submission.php:605 +msgid "Input iframe to show 360° Virtual Tour." +msgstr "" + +#: inc/property/class-metabox-property-admin.php:126 +#: inc/property/class-metabox-property-admin.php:130 +#: inc/submission/class-metabox-property-submission.php:217 +#: templates/single-property/attachments.php:12 +msgid "Attachments" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:135 +#: inc/submission/class-metabox-property-submission.php:225 +msgid "Select one or more files to allow download" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:143 +msgid "Contact Member" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:150 +msgid "User Assignment" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:156 +#: inc/widgets/search-properties.php:74 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:97 +msgid "Layout" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:187 +msgid "Property SKU" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:190 +msgid "Please Enter Your Property SKU" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:201 +#: inc/submission/class-metabox-property-submission.php:375 +msgid "Postal Code / Zip" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:207 +#: inc/submission/class-metabox-property-submission.php:390 +msgid "Google Map View" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:230 +#: inc/submission/class-metabox-property-submission.php:206 +msgid "" +"Input for videos, audios from Youtube, Vimeo and all supported sites by " +"WordPress. It has preview feature." +msgstr "" + +#: inc/property/class-metabox-property-admin.php:248 +#: inc/submission/class-metabox-property-submission.php:119 +msgid "Regular Price" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:250 +#: inc/property/class-metabox-property-admin.php:258 +#: inc/submission/class-metabox-property-submission.php:121 +#: inc/submission/class-metabox-property-submission.php:129 +msgid "Enter amount without currency" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:252 +#: inc/property/class-metabox-property-admin.php:570 +#: inc/submission/class-metabox-property-submission.php:567 +#: templates/search-box/search-form-v3.php:56 +#: templates/search-box/search-form-v2.php:39 +#: templates/search-box/fields/price.php:20 +msgid "Price" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:256 +#: inc/submission/class-metabox-property-submission.php:127 +#: templates/parts/mortgage-calculator.php:152 +msgid "Sale Price" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:262 +#: inc/submission/class-metabox-property-submission.php:133 +msgid "Before Price Label (optional)" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:264 +#: inc/submission/class-metabox-property-submission.php:135 +msgid "Before Price Label (e.g. \"from\")" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:268 +#: inc/submission/class-metabox-property-submission.php:139 +msgid "After Price Label (optional)" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:270 +#: inc/submission/class-metabox-property-submission.php:141 +msgid "After Price Label (e.g. \"per month\")" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:274 +msgid "Is Price On Call" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:298 +#: inc/submission/class-metabox-property-submission.php:239 +msgid "Built year" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:301 +#: inc/submission/class-metabox-property-submission.php:242 +msgid "Enter built year" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:316 +#: inc/submission/class-metabox-property-submission.php:256 +msgid "Enter number of Parking" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:320 +#: inc/submission/class-metabox-property-submission.php:259 +msgid "Bedrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:327 +#: inc/submission/class-metabox-property-submission.php:268 +msgid "Enter number of bedrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:330 +#: inc/submission/class-metabox-property-submission.php:271 +msgid "Bathrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:337 +#: inc/submission/class-metabox-property-submission.php:280 +msgid "Enter number of bathrooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:340 +#: inc/submission/class-metabox-property-submission.php:283 +msgid "Plot Size" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:343 +#: inc/submission/class-metabox-property-submission.php:286 +msgid "Enter size of Plot as 20x30, 20x30x40, 20x30x40x50" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:346 +#: inc/submission/class-metabox-property-submission.php:289 +msgid "Area Size" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:349 +#: inc/submission/class-metabox-property-submission.php:298 +msgid "Enter size of area in sqft" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:352 +#: inc/submission/class-metabox-property-submission.php:301 +msgid "Orientation" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:355 +#: inc/submission/class-metabox-property-submission.php:304 +msgid "Enter Orientation of property" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:359 +#: inc/submission/class-metabox-property-submission.php:307 +msgid "Living Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:366 +#: inc/submission/class-metabox-property-submission.php:316 +msgid "Enter Number of Living Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:370 +#: inc/submission/class-metabox-property-submission.php:320 +msgid "Kitchens" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:377 +#: inc/submission/class-metabox-property-submission.php:329 +msgid "Enter Number of Kitchens" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:381 +#: inc/property/class-metabox-property-admin.php:581 +#: inc/submission/class-metabox-property-submission.php:333 +#: inc/submission/class-metabox-property-submission.php:578 +msgid "Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:388 +#: inc/submission/class-metabox-property-submission.php:342 +msgid "Enter Number of Amount Rooms" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:410 +#: inc/taxonomies/class-taxonomy-labels.php:38 +#: inc/taxonomies/class-taxonomy-labels.php:48 +#: inc/submission/class-metabox-property-submission.php:444 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:169 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:249 +msgid "Label" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:415 +#: inc/property/class-metabox-property-admin.php:592 +#: inc/submission/class-metabox-property-submission.php:449 +#: inc/submission/class-metabox-property-submission.php:589 +msgid "Content" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:420 +#: inc/submission/class-metabox-property-submission.php:454 +msgid "Facility {#}" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:421 +#: inc/property/class-metabox-property-admin.php:611 +#: inc/property/class-metabox-property-admin.php:680 +#: inc/submission/class-metabox-property-submission.php:455 +#: inc/submission/class-metabox-property-submission.php:534 +#: inc/submission/class-metabox-property-submission.php:610 +msgid "Add more" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:422 +#: inc/property/class-metabox-property-admin.php:612 +#: inc/property/class-metabox-property-admin.php:681 +#: inc/submission/class-metabox-property-submission.php:456 +#: inc/submission/class-metabox-property-submission.php:535 +#: inc/submission/class-metabox-property-submission.php:611 +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:64 +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:76 +msgid "Remove" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:440 +msgid "Hide Author Information" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:441 +msgid "User Author Information" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:442 +msgid "Agent Information" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:443 +#: inc/agency/class-opalestate-agency-metabox.php:378 +msgid "Agency Information" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:469 +msgid "Author Information" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:476 +#: inc/user/class-opalestate-user.php:284 +msgid "Agent" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:482 +#: inc/user/class-opalestate-user.php:285 +#: templates/parts/search-agency-form.php:20 +msgid "Agency" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:501 +msgid "Default User" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:512 +msgid "User" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:515 +msgid "" +"Change to new owner of this property, which be listed in That user dashboard" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:533 +msgid "Layout Display" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:537 +#: inc/property/class-metabox-property-admin.php:545 +msgid "Select a layout to display full information of this property" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:541 +msgid "Preview Display" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:564 +#: inc/message/class-opalestate-message.php:521 +#: inc/message/class-opalestate-message.php:624 +#: inc/submission/class-metabox-property-submission.php:561 +#: templates/rating/opalestate-ratings.php:237 +#: templates/user/share-search-form.php:35 +#: templates/user-search/content-savedsearch.php:12 +#: templates/user-search/render-form.php:29 +#: templates/user/agency/agency-team.php:21 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:184 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:184 +msgid "Name" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:576 +#: inc/submission/class-metabox-property-submission.php:573 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:370 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:432 +msgid "Size" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:586 +#: inc/submission/class-metabox-property-submission.php:583 +msgid "Baths" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:597 +#: inc/submission/class-metabox-property-submission.php:594 +msgid "Image Preview" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:610 +#: inc/submission/class-metabox-property-submission.php:609 +msgid "Floor {#}" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:634 +#: inc/submission/class-metabox-property-submission.php:487 +#: templates/single-property/apartments.php:22 +msgid "Plot" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:641 +#: inc/submission/class-metabox-property-submission.php:495 +#: templates/single-property/apartments.php:23 +msgid "Beds" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:646 +#: inc/submission/class-metabox-property-submission.php:500 +msgid "Price from" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:651 +#: inc/submission/class-metabox-property-submission.php:505 +#: templates/single-property/apartments.php:25 +msgid "Floor" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:657 +#: inc/submission/class-metabox-property-submission.php:511 +#: templates/single-property/apartments.php:26 +msgid "Building / Address" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:662 +#: inc/taxonomies/class-taxonomy-status.php:35 +#: inc/taxonomies/class-taxonomy-status.php:45 +#: inc/taxonomies/class-taxonomy-status.php:153 +#: inc/submission/class-metabox-property-submission.php:516 +#: templates/single-property/features.php:40 +#: templates/single-property/apartments.php:27 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:253 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:274 +msgid "Status" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:666 +#: inc/submission/class-metabox-property-submission.php:519 +msgid "Available" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:667 +#: inc/submission/class-metabox-property-submission.php:520 +msgid "Unavailable" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:673 +#: inc/submission/class-metabox-property-submission.php:526 +msgid "Link" +msgstr "" + +#: inc/property/class-metabox-property-admin.php:679 +#: inc/submission/class-metabox-property-submission.php:533 +msgid "Apartment {#}" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:42 +#: inc/agency/class-opalestate-agency-posttype.php:44 +#: inc/admin/register-settings.php:112 +#: inc/agent/class-opalestate-agent-posttype.php:37 +msgid "Property" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:43 +#: inc/property/class-opalestate-posttype.php:44 +#: templates/shortcodes/submission-form.php:30 +#: templates/submission/submission-form.php:16 +msgid "Add New Property" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:45 +#: templates/shortcodes/submission-form.php:32 +#: templates/submission/submission-form.php:19 +msgid "Edit Property" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:46 +msgid "New Property" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:47 +msgid "All Properties" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:48 +#: templates/user/dashboard.php:130 templates/user/property-ratings.php:91 +msgid "View Property" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:49 +msgid "Search Property" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:50 +msgid "No Properties found" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:51 +msgid "No Properties found in Trash" +msgstr "" + +#: inc/property/class-opalestate-posttype.php:73 +msgctxt "property slug" +msgid "property" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:43 +#: inc/agency/class-opalestate-agency-posttype.php:55 +msgid "Agencies" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:45 +#: inc/agency/class-opalestate-agency-posttype.php:46 +msgid "Add New Agency" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:47 +msgid "Edit Agency" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:48 +msgid "New Agency" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:49 +msgid "All Agencies" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:50 +msgid "View Agency" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:51 +msgid "Search Agency" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:52 +msgid "No Agencies found" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:53 +msgid "No Agencies found in Trash" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:69 +msgctxt "agency slug" +msgid "agency" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:75 +#: inc/agency/class-opalestate-agency-posttype.php:85 +msgid "Agency Categories" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:76 +msgid "Category" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:77 +msgid "Search Category" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:78 +msgid "All Categories" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:79 +msgid "Parent Category" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:80 +msgid "Parent Category:" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:81 +msgid "Edit Category" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:82 +msgid "Update Category" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:83 +#: inc/taxonomies/class-taxonomy-categories.php:46 +msgid "Add New Category" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:84 +msgid "New Category Name" +msgstr "" + +#: inc/agency/class-opalestate-agency-posttype.php:97 +msgctxt "agency category slug" +msgid "agency-category" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:84 +msgid "Agency Profile" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:90 +#: templates/user/agency/agency-team.php:36 +msgid "Agency Team" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:293 +#: inc/user/class-opalestate-user.php:338 +#: inc/agent/class-opalestate-agent-front.php:199 +msgid "The data updated successful, please wait for redirecting" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:295 +#: inc/agency/class-opalestate-agency-front.php:302 +#: inc/user/class-opalestate-user.php:340 +#: inc/agent/class-opalestate-agent-front.php:201 +#: inc/agent/class-opalestate-agent-front.php:209 +msgid "Update Information" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:301 +#: inc/agent/class-opalestate-agent-front.php:208 +msgid "Currently, The data could not save!" +msgstr "" + +#: inc/agency/class-opalestate-agency-front.php:458 +#: inc/agent/class-opalestate-agent-front.php:484 +msgid "User ID" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:30 +msgid "Link To User ID" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:32 +msgid "" +"Set relationship to existed user, allow user can edit Agency profile in " +"front-end and show account info in each property." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:36 +msgid "Agent Team" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:60 +msgid "Set this agent as featured" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:83 +#: inc/user/class-opalestate-user.php:562 +#: inc/user/class-opalestate-user.php:575 +#: inc/submission/class-metabox-property-submission.php:45 +msgid "Name and Description" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:138 +msgid "Title/Job" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:140 +msgid "Please enter position or job in your company." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:146 +msgid "company" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:148 +msgid "Please enter company name." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:152 +msgid "Contact email" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:154 +msgid "" +"Enter contact name that allow user contact you via the contact form of " +"website." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:161 +msgid "Enter your home phone." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:166 +msgid "Skype" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:168 +msgid "Input for skype account." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:173 +msgid "Website URL" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:175 +msgid "Link to your website" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:183 +msgid "Enter your facebook profile or facebook newfeed" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:184 +msgid "Social" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:189 +msgid "Linkedin URL" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:191 +msgid "Input for linked in profile." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:195 +msgid "Instagram URL" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:197 +msgid "Input for instagram profile." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:201 +msgid "Pinterest Url" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:203 +msgid "Input for pinterest feed" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:208 +msgid "Google Plus Url" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:210 +msgid "Input for goolge plus profile or your newfeed." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:215 +msgid "Youtube Url" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:217 +msgid "Input for your channel youtube." +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:222 +msgid "Vimeo Url" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:224 +msgid "Input for your channel Vimeo" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:255 +msgid "Title / Name" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:264 +#: inc/admin/agency/class-agency.php:79 +msgid "slogan" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:279 +#: inc/agent/class-opalestate-agent-metabox.php:64 +#: inc/agent/class-opalestate-agent-metabox.php:110 +#: inc/taxonomies/class-taxonomy-types.php:75 +#: inc/taxonomies/class-taxonomy-types.php:85 +#: inc/submission/class-metabox-property-submission.php:155 +#: templates/search-box/search-form-v3.php:46 +#: templates/search-box/search-form-v2.php:29 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:233 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:254 +msgid "Types" +msgstr "" + +#: inc/agency/class-opalestate-agency-metabox.php:302 +#: inc/agent/class-opalestate-agent-metabox.php:148 +msgid "Banner" +msgstr "" + +#: inc/admin/functions.php:198 +msgid "Global Default" +msgstr "" + +#: inc/admin/functions.php:288 +msgid "Save Settings" +msgstr "" + +#: inc/admin/functions.php:327 +msgid "Deactivate License" +msgstr "" + +#: inc/admin/functions.php:365 +msgid "Search Key" +msgstr "" + +#: inc/admin/functions.php:372 +#, php-format +msgid "" +"API keys allow users to use the Opalestate REST API to " +"retrieve donation data in JSON or XML for external applications or devices, " +"such as Zapi_keyser." +msgstr "" + +#: inc/admin/functions.php:563 +msgid "No users found" +msgstr "" + +#: inc/admin/functions.php:586 +msgid "We could find this user" +msgstr "" + +#: inc/admin/functions.php:590 +msgid "We could not find this user" +msgstr "" + +#: inc/admin/register-settings.php:79 +msgid "Settings" +msgstr "" + +#: inc/admin/register-settings.php:84 +msgid "Addons" +msgstr "" + +#: inc/admin/register-settings.php:115 +msgid "Add-ons" +msgstr "" + +#: inc/admin/register-settings.php:119 +msgid "Licenses" +msgstr "" + +#: inc/admin/register-settings.php:122 inc/admin/settings/api_keys.php:28 +#: inc/admin/settings/api_keys.php:34 +msgid "API" +msgstr "" + +#: inc/admin/register-settings.php:123 +msgid "3rd Party" +msgstr "" + +#: inc/admin/register-settings.php:280 +msgid "Settings updated." +msgstr "" + +#: inc/admin/class-user.php:49 +#, php-format +msgid "" +"This user has role Opal Estate Agency and click here to update Agency profile" +msgstr "" + +#: inc/admin/class-user.php:59 +#, php-format +msgid "" +"This user has role Opal Estate Agent and click here to update Agent profile" +msgstr "" + +#: inc/admin/class-user.php:87 inc/admin/agency/class-agency.php:110 +#: inc/admin/agent/class-agent.php:62 +msgid "Metabox" +msgstr "" + +#: inc/admin/class-user.php:112 inc/admin/agency/class-agency.php:136 +#: inc/admin/agent/class-agent.php:87 +msgid "Socials" +msgstr "" + +#: inc/admin/class-user.php:168 +msgid "Block Submssion" +msgstr "" + +#: inc/admin/class-user.php:170 +msgid "Disable Submssion Functions to not allow submit property" +msgstr "" + +#: inc/admin/class-user.php:176 +msgid "Block Submssion Message" +msgstr "" + +#: inc/admin/class-user.php:178 +msgid "Show message for disabled user" +msgstr "" + +#: inc/admin/class-api-keys-table.php:54 +msgid "API Key" +msgstr "" + +#: inc/admin/class-api-keys-table.php:55 +msgid "API Keys" +msgstr "" + +#: inc/admin/class-api-keys-table.php:143 +msgid "View API Log" +msgstr "" + +#: inc/admin/class-api-keys-table.php:154 +msgid "Reissue" +msgstr "" + +#: inc/admin/class-api-keys-table.php:163 +msgid "Revoke" +msgstr "" + +#: inc/admin/class-api-keys-table.php:180 templates/user/register-form.php:43 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:512 +msgid "Username" +msgstr "" + +#: inc/admin/class-api-keys-table.php:181 +msgid "Public Key" +msgstr "" + +#: inc/admin/class-api-keys-table.php:182 +msgid "Token" +msgstr "" + +#: inc/admin/class-api-keys-table.php:183 +msgid "Secret Key" +msgstr "" + +#: inc/admin/class-api-keys-table.php:235 +msgid "Generate New API Keys" +msgstr "" + +#: inc/message/class-opalestate-request-reviewing.php:94 +#: inc/message/class-opalestate-message.php:234 +#: inc/message/class-opalestate-message.php:284 +msgid "Unable to send a message." +msgstr "" + +#: inc/message/class-opalestate-message.php:162 +#: inc/email/class-opalestate-email-notifycation.php:38 +msgid "You got a message contact" +msgstr "" + +#: inc/message/class-opalestate-message.php:229 +msgid "Email Sent successful" +msgstr "" + +#: inc/message/class-opalestate-message.php:230 +#: inc/message/class-opalestate-message.php:234 +msgid "Sending Message" +msgstr "" + +#: inc/message/class-opalestate-message.php:498 +#: inc/message/class-opalestate-message.php:564 +#: inc/message/class-opalestate-message.php:603 +#: inc/message/class-opalestate-message.php:680 +#: inc/taxonomies/class-taxonomy-types.php:123 +#: templates/user/register-form.php:69 +#: templates/single-property/features.php:28 +msgid "Type" +msgstr "" + +#: inc/message/class-opalestate-message.php:505 +#: inc/message/class-opalestate-message.php:610 +#: inc/message/class-opalestate-message.php:687 +msgid "Property ID" +msgstr "" + +#: inc/message/class-opalestate-message.php:513 +#: inc/message/class-opalestate-message.php:617 +#: inc/message/class-opalestate-message.php:694 +#: templates/user/agency/agency-team.php:14 +msgid "Sender ID" +msgstr "" + +#: inc/message/class-opalestate-message.php:547 +#: inc/message/class-opalestate-message.php:571 +#: inc/message/class-opalestate-message.php:649 +#: inc/message/class-opalestate-message.php:724 +#: templates/user/share-search-form.php:45 +msgid "Message" +msgstr "" + +#: inc/message/class-opalestate-message.php:701 +msgid "Schedule" +msgstr "" + +#: inc/message/class-opalestate-message.php:709 +msgid "Time" +msgstr "" + +#: inc/user/functions.php:123 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:549 +msgid "Dashboard" +msgstr "" + +#: inc/user/functions.php:130 +msgid "Personal Information" +msgstr "" + +#: inc/user/functions.php:137 +msgid "Favorite" +msgstr "" + +#: inc/user/functions.php:159 +msgid "Messages" +msgstr "" + +#: inc/user/functions.php:167 +msgid "Submit Property" +msgstr "" + +#: inc/user/functions.php:174 inc/submission/class-opalestate-submission.php:97 +#: templates/single-agent/properties.php:11 templates/user/dashboard.php:12 +#: templates/single-agency/properties.php:16 +msgid "My Properties" +msgstr "" + +#: inc/user/functions.php:196 +msgid "Log out" +msgstr "" + +#: inc/user/functions.php:223 +msgid "An account is already registered with your email address. Please login." +msgstr "" + +#: inc/user/functions.php:228 +msgid "Please enter a valid account username." +msgstr "" + +#: inc/user/functions.php:232 +msgid "Username is already exists." +msgstr "" + +#: inc/user/functions.php:237 +msgid "Password is requried." +msgstr "" + +#: inc/user/class-opalestate-user.php:57 +msgid "User Profile" +msgstr "" + +#: inc/user/class-opalestate-user.php:168 +#, php-format +msgid "" +"This user has role Opal Estate Agency and click here to update Agency profile" +msgstr "" + +#: inc/user/class-opalestate-user.php:179 +#, php-format +msgid "" +"This user has role Opal Estate Agent and click here to update Agent profile" +msgstr "" + +#: inc/user/class-opalestate-user.php:258 +msgid "" +"Your account was blocked to use the submission form, so you could not submit " +"any property." +msgstr "" + +#: inc/user/class-opalestate-user.php:270 +msgid "Your account is blocked, you could not complete this action" +msgstr "" + +#: inc/user/class-opalestate-user.php:283 +msgid "Subscriber" +msgstr "" + +#: inc/user/class-opalestate-user.php:490 +msgid "Found a problem while updating" +msgstr "" + +#: inc/user/class-opalestate-user.php:501 +msgid "Passwords fields are not empty" +msgstr "" + +#: inc/user/class-opalestate-user.php:507 +msgid "New password is not same confirm password" +msgstr "" + +#: inc/user/class-opalestate-user.php:517 +msgid "Password Updated" +msgstr "" + +#: inc/user/class-opalestate-user.php:519 +msgid "Old password is not correct" +msgstr "" + +#: inc/user/class-opalestate-user.php:584 +msgid "Old Password" +msgstr "" + +#: inc/user/class-opalestate-user.php:589 +msgid "Please enter your old password" +msgstr "" + +#: inc/user/class-opalestate-user.php:593 +msgid "New Password" +msgstr "" + +#: inc/user/class-opalestate-user.php:598 +msgid "Please enter your new password." +msgstr "" + +#: inc/user/class-opalestate-user.php:602 +msgid "Confirm Password" +msgstr "" + +#: inc/user/class-opalestate-user.php:607 +msgid "Please enter your confirm password." +msgstr "" + +#: inc/user/class-opalestate-user-search.php:142 +msgid "Saved this search successful." +msgstr "" + +#: inc/user/class-opalestate-user-search.php:144 +msgid "You saved this search" +msgstr "" + +#: inc/user/class-opalestate-user-search.php:147 +msgid "Please sign in to save this search." +msgstr "" + +#: inc/user/class-opalestate-user-search.php:191 +msgid "Saved Search" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:46 +#: inc/user/class-opalestate-user-form-handler.php:51 +#: inc/user/class-opalestate-user-form-handler.php:60 +#: inc/user/class-opalestate-user-form-handler.php:70 +#: inc/user/class-opalestate-user-form-handler.php:160 +#: inc/user/class-opalestate-user-form-handler.php:165 +#: inc/user/class-opalestate-user-form-handler.php:172 +#: inc/user/class-opalestate-user-form-handler.php:179 +#: inc/user/class-opalestate-user-form-handler.php:182 +#: inc/user/class-opalestate-user-form-handler.php:191 +msgid "ERROR" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:51 +#: inc/user/class-opalestate-user-form-handler.php:165 +msgid "Username is required." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:60 +msgid "A user could not be found with this email address." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:70 +#: inc/user/class-opalestate-user-form-handler.php:179 +msgid "Password is required." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:96 +msgid "Logged successfully, welcome back!" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:172 +msgid "Email is required." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:182 +msgid "Re-Password is not match." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:251 +msgid "Enter an username or e-mail address." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:257 +msgid "There is no user registered with that email address." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:263 +msgid "There is no user registered with that username." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:266 +msgid "Invalid username or e-mail address." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:289 +msgid "Your new password" +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:292 +msgid "Your new password is: " +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:301 +msgid "Check your email address for you new password." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:303 +msgid "System is unable to send you mail containg your new password." +msgstr "" + +#: inc/user/class-opalestate-user-form-handler.php:305 +msgid "Oops! Something went wrong while updating your account." +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:45 +msgid "Link to User" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:47 +msgid "Enter User ID to show information without using user info" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:52 +#: inc/agent/class-opalestate-agent-metabox.php:119 +msgid "Target Min Price" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:54 +#: inc/agent/class-opalestate-agent-metabox.php:121 +msgid "Enter min price of property which is for sale/rent..." +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:59 +#: inc/agent/class-opalestate-agent-metabox.php:126 +msgid "Target Max Price" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:61 +#: inc/agent/class-opalestate-agent-metabox.php:128 +msgid "Enter max price of property which is for sale/rent..." +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:91 +msgid "Title/Name" +msgstr "" + +#: inc/agent/class-opalestate-agent-metabox.php:215 +msgid "Agent Information" +msgstr "" + +#: inc/agent/class-opalestate-agent-front.php:81 +#: inc/agent/class-opalestate-agent-front.php:308 +msgid "Agent Profile" +msgstr "" + +#: inc/agent/class-opalestate-agent-front.php:309 +msgid "Search Agents" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:36 +#: inc/agent/class-opalestate-agent-posttype.php:48 +msgid "Agents" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:38 +#: inc/agent/class-opalestate-agent-posttype.php:39 +msgid "Add New Agent" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:40 +msgid "Edit Agent" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:41 +msgid "New Agent" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:42 +msgid "All Agents" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:43 +msgid "View Agent" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:44 +msgid "Search Agent" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:45 +msgid "No Agents found" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:46 +msgid "No Agents found in Trash" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:62 +msgctxt "agent slug" +msgid "agent" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:75 +#: inc/agent/class-opalestate-agent-posttype.php:85 +msgid "Agent Levels" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:76 +msgid "Level" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:77 +msgid "Search Level" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:78 +msgid "All Levels" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:79 +msgid "Parent Level" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:80 +msgid "Parent Level:" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:81 +msgid "Edit Level" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:82 +msgid "Update Level" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:83 +msgid "Add New Level" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:84 +msgid "New Level Name" +msgstr "" + +#: inc/agent/class-opalestate-agent-posttype.php:97 +msgctxt "agent level slug" +msgid "agent-level" +msgstr "" + +#: inc/api/class-opalestate-api.php:423 +msgid "You must specify both a token and API key!" +msgstr "" + +#: inc/api/class-opalestate-api.php:440 +msgid "Your request could not be authenticated!" +msgstr "" + +#: inc/api/class-opalestate-api.php:457 +msgid "Invalid API key!" +msgstr "" + +#: inc/api/class-opalestate-api.php:473 +msgid "Invalid API version!" +msgstr "" + +#: inc/api/class-opalestate-api.php:601 +msgid "Invalid query!" +msgstr "" + +#. %s: property +#: inc/api/class-opalestate-api.php:678 inc/api/class-opalestate-api.php:769 +#: inc/api/class-opalestate-api.php:821 +#, php-format +msgid "Form %s not found!" +msgstr "" + +#: inc/api/class-opalestate-api.php:1053 +msgid "Opalestate API Keys" +msgstr "" + +#: inc/api/class-opalestate-api.php:1062 +msgid "Generate API Key" +msgstr "" + +#: inc/api/class-opalestate-api.php:1064 +msgid "Public key:" +msgstr "" + +#: inc/api/class-opalestate-api.php:1067 +msgid "Secret key:" +msgstr "" + +#: inc/api/class-opalestate-api.php:1070 +msgid "Token:" +msgstr "" + +#: inc/api/class-opalestate-api.php:1074 +msgid "Revoke API Keys" +msgstr "" + +#: inc/api/class-opalestate-api.php:1097 +msgid "Nonce verification failed." +msgstr "" + +#: inc/api/class-opalestate-api.php:1097 inc/api/class-opalestate-api.php:1102 +#: inc/api/class-opalestate-api.php:1120 inc/api/class-opalestate-api.php:1130 +msgid "Error" +msgstr "" + +#: inc/api/class-opalestate-api.php:1102 +msgid "User ID Required." +msgstr "" + +#. %s: process +#: inc/api/class-opalestate-api.php:1117 inc/api/class-opalestate-api.php:1127 +#, php-format +msgid "You do not have permission to %s API keys for this user." +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:36 +#: inc/taxonomies/class-taxonomy-locations.php:46 +msgid "Countries" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:37 +msgid "Properties By Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:38 +msgid "Search Countries" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:39 +msgid "All Countries" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:40 +msgid "Parent Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:41 +msgid "Parent Country:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:42 +msgid "Edit Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:43 +msgid "Update Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:44 +msgid "Add New Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:45 +msgid "New Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:53 +msgid "location" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:77 +msgid "Country Metabox" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:84 +#: inc/taxonomies/class-taxonomy-categories.php:76 +#: inc/taxonomies/class-taxonomy-state.php:79 +#: inc/taxonomies/class-taxonomy-city.php:75 +#: inc/taxonomies/class-taxonomy-types.php:58 +msgid "Image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:85 +msgid "Country image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:108 +#: inc/taxonomies/class-taxonomy-locations.php:128 +msgid "Select Country" +msgstr "" + +#: inc/taxonomies/class-taxonomy-locations.php:142 +#: inc/taxonomies/class-taxonomy-state.php:91 +#: inc/taxonomies/class-taxonomy-city.php:87 +#: inc/submission/class-metabox-property-submission.php:356 +msgid "Country" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:34 +#: inc/taxonomies/class-taxomony-amenities.php:44 +#: inc/submission/class-metabox-property-submission.php:66 +#: inc/submission/class-metabox-property-submission.php:417 +msgid "Amenities" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:35 +msgid "Properties By Amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:36 +msgid "Search Amenities" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:37 +msgid "All Amenities" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:38 +msgid "Parent Amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:39 +msgid "Parent Amenity:" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:40 +msgid "Edit Amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:41 +msgid "Update Amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:42 +msgid "Add New Amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:43 +msgid "New Amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:51 +msgctxt "slug" +msgid "amenity" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:68 +#: inc/taxonomies/class-taxonomy-neighborhood.php:42 +#: inc/taxonomies/class-taxonomy-types.php:40 +msgid "Type Metabox" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:74 +msgid "Image Icon" +msgstr "" + +#: inc/taxonomies/class-taxomony-amenities.php:75 +msgid "Select an image icon (SVG, PNG or JPEG)." +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:49 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:284 +msgid "Icon" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:50 +#: inc/taxonomies/class-taxonomy-types.php:48 +msgid "This image will display in google map" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:66 +#: inc/taxonomies/class-taxonomy-neighborhood.php:76 +msgid "Neighborhoods" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:67 +msgid "Properties By Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:68 +msgid "Search Neighborhoods" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:69 +msgid "All Neighborhoods" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:70 +msgid "Parent Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:71 +msgid "Parent Neighborhood:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:72 +msgid "Edit Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:73 +msgid "Update Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:74 +msgid "Add New Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:75 +msgid "New Neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:83 +msgid "property-neighborhood" +msgstr "" + +#: inc/taxonomies/class-taxonomy-neighborhood.php:98 +msgid "Select Neighborhoods" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:45 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:237 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:205 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:226 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:206 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:206 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:237 +msgid "Categories" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:47 +msgid "New Category" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:53 +msgctxt "slug" +msgid "property-category" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:69 +#: inc/taxonomies/class-taxonomy-labels.php:76 +#: inc/taxonomies/class-taxonomy-status.php:69 +msgid "Category Metabox" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:77 +msgid "Category image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-categories.php:100 +msgid "Select category" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:34 +#: inc/taxonomies/class-taxonomy-state.php:44 +msgid "States / Provinces" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:35 +msgid "Properties By State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:36 +msgid "Search States" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:37 +msgid "All States / Province" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:38 +msgid "Parent State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:39 +msgid "Parent State:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:40 +msgid "Edit State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:41 +msgid "Update State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:42 +msgid "Add New State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:43 +msgid "New State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:51 +msgid "state" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:72 +msgid "State Metabox" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:80 +msgid "State image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:92 +#: inc/taxonomies/class-taxonomy-city.php:88 +msgid "Select one, to add new you create in countries of estate panel" +msgstr "" + +#: inc/taxonomies/class-taxonomy-state.php:139 +msgid "State" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:39 +msgid "Properties By Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:40 +msgid "Search Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:41 +msgid "All Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:42 +msgid "Parent Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:43 +msgid "Parent Label:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:44 +msgid "Edit Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:45 +msgid "Update Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:46 +msgid "Add New Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:47 +msgid "New Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:55 +msgid "property-label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:82 +#: inc/taxonomies/class-taxonomy-status.php:75 +msgid "Background" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:83 +#: inc/taxonomies/class-taxonomy-status.php:76 +msgid "Set background of label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:88 +#: inc/taxonomies/class-taxonomy-status.php:81 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:390 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:452 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:186 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:215 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:241 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:306 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:347 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:257 +msgid "Color" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:89 +msgid "Set color of text" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:95 +msgid "Image Logo" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:96 +msgid "Or Using Image Logo without using text" +msgstr "" + +#: inc/taxonomies/class-taxonomy-labels.php:135 +msgid "Select Label" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:35 +#: inc/taxonomies/class-taxonomy-city.php:45 +msgid "Cities / Towns" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:36 +msgid "Properties By City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:37 +msgid "Search Cities / Towns" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:38 +msgid "All Cities / Town" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:39 +msgid "Parent City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:40 +msgid "Parent City:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:41 +msgid "Edit City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:42 +msgid "Update City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:43 +msgid "Add New City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:44 +msgid "New City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:52 +msgid "city" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:69 +msgid "City Metabox" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:76 +msgid "City image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:97 +msgid "Select one, to add new you create in City/Town of estate panel" +msgstr "" + +#: inc/taxonomies/class-taxonomy-city.php:146 +msgid "City" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:47 +msgid "Custom Icon Marker" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:59 +msgid "Type image" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:76 +msgid "Properties By Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:77 +msgid "Search Types" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:78 +msgid "All Types" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:79 +msgid "Parent Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:80 +msgid "Parent Type:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:81 +msgid "Edit Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:82 +msgid "Update Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:83 +msgid "Add New Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:84 +msgid "New Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:92 +msgid "type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-types.php:111 +msgid "Select Type" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:36 +msgid "Properties By Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:37 +msgid "Search Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:38 +msgid "All Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:39 +msgid "Parent Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:40 +msgid "Parent Status:" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:41 +msgid "Edit Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:42 +msgid "Update Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:43 +msgid "Add New Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:44 +msgid "New Status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:51 +msgid "status" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:82 +msgid "Set background of text" +msgstr "" + +#: inc/taxonomies/class-taxonomy-status.php:141 +msgid "Select Status" +msgstr "" + +#: inc/email/class-opalestate-email-notifycation.php:34 +msgid "You got a message enquiry" +msgstr "" + +#: inc/email/class-opalestate-request-viewing.php:31 +#, php-format +msgid "You have a message request reviewing: %s at" +msgstr "" + +#: inc/email/class-opalestate-abs-email-template.php:43 +msgid "Admin Notice of Expiring Job Listings" +msgstr "" + +#: inc/email/class-opalestate-abs-email-template.php:53 +msgid "Send notices to the site administrator before a job listing expires." +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/featured-properties.php:22 +msgid "Estate: Featured Properties" +msgstr "" + +#: inc/widgets/featured-properties.php:24 +msgid "Featured Properties widget." +msgstr "" + +#: inc/widgets/featured-properties.php:52 +#: templates/single-agent/featured-properties.php:19 +#: templates/user/dashboard.php:19 +msgid "Featured Properties" +msgstr "" + +#: inc/widgets/featured-properties.php:57 +#: inc/widgets/sameprice-properties.php:58 +#: inc/widgets/similar-properties.php:56 inc/widgets/profile-info.php:80 +#: inc/widgets/search-properties.php:68 inc/widgets/mortgage-calculator.php:53 +msgid "Title:" +msgstr "" + +#: inc/widgets/featured-properties.php:62 +#: inc/widgets/sameprice-properties.php:63 +#: inc/widgets/similar-properties.php:61 +msgid "Limit:" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/sameprice-properties.php:22 +msgid "Estate: Same Price" +msgstr "" + +#: inc/widgets/sameprice-properties.php:24 +msgid "Similar Properties By Same Price with configured range and Status" +msgstr "" + +#: inc/widgets/sameprice-properties.php:52 +msgid "Same Price" +msgstr "" + +#: inc/widgets/sameprice-properties.php:69 +msgid "Range Price:" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/similar-properties.php:22 +msgid "Estate: Similar Properties" +msgstr "" + +#: inc/widgets/similar-properties.php:24 +msgid "Similar Properties By Same Types and Status Of the post" +msgstr "" + +#: inc/widgets/similar-properties.php:51 +msgid "Similar Properties" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/profile-info.php:22 +msgid "Estate: User Menu Profile" +msgstr "" + +#: inc/widgets/profile-info.php:24 +msgid "Display Profile information in box and menu." +msgstr "" + +#: inc/widgets/profile-info.php:76 +msgid "My Profile" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/search-properties.php:23 +msgid "Estate: Search Properties" +msgstr "" + +#: inc/widgets/search-properties.php:25 +msgid "Search Properties widget." +msgstr "" + +#: inc/widgets/search-properties.php:83 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:107 +msgid "Disable Labels" +msgstr "" + +#: inc/widgets/search-properties.php:92 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:116 +msgid "Disable Search button" +msgstr "" + +#: inc/widgets/search-properties.php:101 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:124 +msgid "Display Country select" +msgstr "" + +#: inc/widgets/search-properties.php:110 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:136 +msgid "Display State select" +msgstr "" + +#: inc/widgets/search-properties.php:119 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:147 +msgid "Display City select" +msgstr "" + +#. Widget name will appear in UI +#: inc/widgets/mortgage-calculator.php:25 +msgid "Estate: Mortgage Calculator" +msgstr "" + +#: inc/widgets/mortgage-calculator.php:27 +msgid "Mortgage Calculator widget." +msgstr "" + +#: inc/widgets/mortgage-calculator.php:49 +msgid "Mortgage Calculator" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:93 +msgid "Submission Form" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:110 +msgid "Submission Page" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:125 +msgid "Submission Page Settings" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:132 +msgid "" +"This is the submission page. The [opalestate_submission] " +"shortcode should be on this page." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:142 +msgid "Show Content Use Not Login" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:143 +msgid "Show Login/Register form and submission form if user not logined" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:148 +msgid "Show Login Form" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:149 +msgid "Show Login Form and Submission Form" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:154 +msgid "Enable Admin Approve" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:155 +msgid "" +"the Property will be auto approve when user submit, if you do not enable it." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:160 +msgid "Enable Require Price" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:161 +msgid "Enable or Disable require user enter price and price label." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:167 +msgid "Submission Tab Settings" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:174 +#: inc/submission/class-opalestate-submission.php:175 +msgid "Enable Media tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:184 +#: inc/submission/class-opalestate-submission.php:185 +msgid "Enable Location tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:194 +#: inc/submission/class-opalestate-submission.php:195 +msgid "Enable Information tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:204 +#: inc/submission/class-opalestate-submission.php:205 +msgid "Enable Amenities tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:214 +#: inc/submission/class-opalestate-submission.php:215 +msgid "Enable Facilities tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:224 +#: inc/submission/class-opalestate-submission.php:225 +msgid "Enable Apartments tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:234 +#: inc/submission/class-opalestate-submission.php:235 +msgid "Enable Floor plans tab" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:267 +msgid "Edit My Property" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:333 +msgid "A metabox with the specified 'metabox_id' doesn't exist." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:460 +msgid "Please enter data for all require fields before submitting" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:462 +#: inc/submission/class-opalestate-submission.php:527 +#: inc/submission/class-opalestate-submission.php:534 +#: inc/submission/class-opalestate-submission.php:541 +#: inc/vendors/opalmembership/membership.php:426 +msgid "Submission Information" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:501 +msgid "Property has been successfully updated." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:507 +msgid "The property has updated completed with new information" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:511 +msgid "You have submitted the property successful" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:533 +msgid "" +"Currently, your account was blocked, please keep contact admin to resolve " +"this!." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:540 +msgid "Sorry! Your submitted datcould not save a at this time" +msgstr "" + +#: inc/submission/class-opalestate-submission.php:680 +msgid "Property has been successfully removed." +msgstr "" + +#: inc/submission/class-opalestate-submission.php:682 +msgid "An error occured when removing an item." +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:63 +msgid "Media" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:67 +msgid "Facilities" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:69 +msgid "Floor plans" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:100 +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:87 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:214 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:182 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:203 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:214 +msgid "Title" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:144 +msgid "Statuses" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:163 +#: inc/submission/class-metabox-property-submission.php:227 +#: inc/submission/class-metabox-property-submission.php:344 +#: inc/submission/class-metabox-property-submission.php:406 +#: inc/submission/class-metabox-property-submission.php:422 +#: inc/submission/class-metabox-property-submission.php:440 +#: inc/submission/class-metabox-property-submission.php:483 +#: inc/submission/class-metabox-property-submission.php:675 +msgid "Next Step" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:184 +msgid "Featured Image" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:210 +#: templates/single-property/virtualtour.php:8 +msgid "360° Virtual Tour" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:226 +msgid "Previous Step " +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:343 +#: inc/submission/class-metabox-property-submission.php:405 +#: inc/submission/class-metabox-property-submission.php:421 +#: inc/submission/class-metabox-property-submission.php:439 +#: inc/submission/class-metabox-property-submission.php:482 +#: inc/submission/class-metabox-property-submission.php:557 +#: inc/submission/class-metabox-property-submission.php:674 +msgid "Previous Step" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:363 +msgid "States / Province" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:397 +msgid "Enable Google Map" +msgstr "" + +#: inc/submission/class-metabox-property-submission.php:401 +msgid "Google Map" +msgstr "" + +#: templates/messages/request-reviewing-form.php:10 +#: templates/messages/request-reviewing-form.php:11 +msgid "Send now" +msgstr "" + +#: templates/messages/enquiry-form.php:4 +#, php-format +msgid "Hi, I am interested in %s (Property ID: %s)" +msgstr "" + +#: templates/messages/enquiry-form.php:7 +msgid "Enquire about property" +msgstr "" + +#: templates/messages/enquiry-form.php:23 +#: templates/messages/enquiry-form.php:38 +#: templates/messages/contact-form.php:37 +#: templates/user/share-search-form.php:50 +#: templates/user-search/render-form.php:33 +msgid " Processing" +msgstr "" + +#: templates/messages/enquiry-form.php:23 +#: templates/messages/enquiry-form.php:38 +#: templates/messages/contact-form.php:37 +#: templates/user/share-search-form.php:50 +#: templates/user/agency/agency-team.php:45 +msgid "Send message" +msgstr "" + +#: templates/messages/contact-form.php:13 +msgid "Contact Me" +msgstr "" + +#: templates/rating/opalestate-ratings.php:64 +msgid "Ratings & Reviews" +msgstr "" + +#: templates/rating/opalestate-ratings.php:79 +msgid "star" +msgstr "" + +#: templates/rating/opalestate-ratings.php:106 +msgid "Overall rating" +msgstr "" + +#. %s number of ratings +#: templates/rating/opalestate-ratings.php:118 +#, php-format +msgctxt "rating numbers" +msgid "%s rating" +msgid_plural "%s ratings" +msgstr[0] "" +msgstr[1] "" + +#: templates/rating/opalestate-ratings.php:132 +msgid "based on all ratings" +msgstr "" + +#: templates/rating/opalestate-ratings.php:207 +msgid "There are no reviews yet." +msgstr "" + +#. %s is property title +#: templates/rating/opalestate-ratings.php:230 +msgid "Add a review" +msgstr "" + +#: templates/rating/opalestate-ratings.php:230 +#, php-format +msgid "Be the first to review “%s”" +msgstr "" + +#. %s is property title +#: templates/rating/opalestate-ratings.php:232 +#, php-format +msgid "Leave a Reply to %s" +msgstr "" + +#: templates/rating/opalestate-ratings.php:242 +msgid "Submit" +msgstr "" + +#: templates/rating/opalestate-ratings.php:251 +#: templates/rating/opalestate-ratings.php:263 +msgid "Rate…" +msgstr "" + +#: templates/rating/opalestate-ratings.php:252 +#: templates/rating/opalestate-ratings.php:264 +msgid "Perfect" +msgstr "" + +#: templates/rating/opalestate-ratings.php:253 +#: templates/rating/opalestate-ratings.php:265 +msgid "Good" +msgstr "" + +#: templates/rating/opalestate-ratings.php:254 +#: templates/rating/opalestate-ratings.php:266 +msgid "Average" +msgstr "" + +#: templates/rating/opalestate-ratings.php:255 +#: templates/rating/opalestate-ratings.php:267 +msgid "Not that bad" +msgstr "" + +#: templates/rating/opalestate-ratings.php:256 +#: templates/rating/opalestate-ratings.php:268 +msgid "Very poor" +msgstr "" + +#: templates/rating/opalestate-ratings.php:262 +msgid "Your rating" +msgstr "" + +#: templates/rating/opalestate-ratings.php:272 +msgid "Your review" +msgstr "" + +#: templates/rating/opalestate-ratings.php:280 +msgid "Your review already exists!" +msgstr "" + +#: templates/rating/opalestate-ratings.php:283 +msgid "You cannot write review on your own post." +msgstr "" + +#: templates/rating/opalestate-ratings.php:287 +msgid "You must be logged in to review." +msgstr "" + +#: templates/rating/opalestate-ratings.php:288 +msgid "Click here to login" +msgstr "" + +#: templates/rating/review-meta.php:14 +msgid "Your review is awaiting approval" +msgstr "" + +#: templates/single-agent/author-box.php:34 +msgid "Agent details" +msgstr "" + +#: templates/single-agent/author-box.php:125 +msgid "View Profile" +msgstr "" + +#: templates/emails/publish_property.php:14 +msgid "URL" +msgstr "" + +#: templates/elementor-templates/opalestate-split-maps-search.php:12 +msgid "Loading map..." +msgstr "" + +#: templates/elementor-templates/opalestate-office-agent-search.php:14 +msgid "Find An Agent" +msgstr "" + +#: templates/elementor-templates/opalestate-office-agent-search.php:19 +msgid "Find An Agency" +msgstr "" + +#: templates/user/share-search-form.php:8 +#: templates/user-search/render-form.php:8 +#, php-format +msgid "" +"Hey there! I saved this search on %s, please check out these homes that are " +"listed. Remember to save this search to be first to catch any new listings." +msgstr "" + +#: templates/user/share-search-form.php:14 +msgid "Share this Search" +msgstr "" + +#: templates/user/share-search-form.php:23 +msgid "Are you searching with anyone? Share this search." +msgstr "" + +#: templates/user/share-search-form.php:31 +msgid "Friend Email" +msgstr "" + +#: templates/user/share-search-form.php:40 +msgid "E-mail" +msgstr "" + +#: templates/user/dashboard.php:26 +msgid "Pending Properties" +msgstr "" + +#: templates/user/dashboard.php:57 templates/user/property-ratings.php:11 +msgid "You have not written any reviews yet." +msgstr "" + +#: templates/user/content-property.php:71 +msgid "Set Featured" +msgstr "" + +#: templates/user/content-property.php:87 +msgid "Are you sure you wish to delete?" +msgstr "" + +#: templates/user/content-property.php:88 +msgid "Delete Property" +msgstr "" + +#: templates/user/my-account-popup.php:4 templates/user/my-account.php:4 +#: templates/user/login-form.php:16 templates/user/login-form.php:51 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:531 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:532 +msgid "Login" +msgstr "" + +#: templates/user/my-account-popup.php:5 templates/user/register-form.php:31 +#: templates/user/register-form.php:93 templates/user/my-account.php:5 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:504 +msgid "Register" +msgstr "" + +#: templates/user/favorite-properties.php:24 +msgid "You have not added any property as favorite." +msgstr "" + +#: templates/user/favorite-button.php:12 +msgid "Add To Favorite" +msgstr "" + +#: templates/user/read-messages.php:7 +msgid "Inbox" +msgstr "" + +#: templates/user/read-messages.php:45 +msgid "Reply" +msgstr "" + +#: templates/user/register-form.php:22 templates/user/login-form.php:7 +msgid "You are currently logged in." +msgstr "" + +#: templates/user/register-form.php:50 +msgid "Email address" +msgstr "" + +#: templates/user/register-form.php:57 templates/user/login-form.php:34 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:516 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:517 +msgid "Password" +msgstr "" + +#: templates/user/register-form.php:62 +msgid "Repeat-Password" +msgstr "" + +#: templates/user/register-form.php:80 +msgid "I agree with" +msgstr "" + +#: templates/user/register-form.php:81 +msgid "terms & conditions" +msgstr "" + +#: templates/user/profile.php:22 +msgid "Edit User Profile" +msgstr "" + +#: templates/user/profile.php:30 templates/user/profile.php:50 +#: templates/user/agency/profile-agency.php:32 +#: templates/user/agent/profile-agent.php:16 +msgid "Save Change" +msgstr "" + +#: templates/user/profile.php:41 +msgid "Change Password" +msgstr "" + +#: templates/user/my-properties.php:4 +msgid "Published" +msgstr "" + +#: templates/user/my-properties.php:5 +msgid "Pending" +msgstr "" + +#: templates/user/my-properties.php:6 +#: inc/vendors/opalmembership/membership.php:594 +#: inc/vendors/opalmembership/membership.php:603 +msgid "Expired" +msgstr "" + +#: templates/user/my-properties.php:47 +msgid "You have not submited any property." +msgstr "" + +#: templates/user/messages.php:9 +msgid "Messages for you" +msgstr "" + +#: templates/user/login-form.php:27 +msgid "Username or email address" +msgstr "" + +#: templates/user/login-form.php:42 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:523 +msgid "Remember me" +msgstr "" + +#: templates/user/login-form.php:52 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:542 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:542 +msgid "Lost your password?" +msgstr "" + +#: templates/user/login-form.php:56 +msgid "Register now!" +msgstr "" + +#: templates/shortcodes/ajax-map-quick-search.php:23 +#: templates/parts/search-agents-form-address.php:36 +#: templates/parts/search-agents-form.php:55 +#: templates/parts/search-agency-form-address.php:37 +#: templates/parts/search-agency-form.php:28 +#: templates/search-box/fields/submit-button.php:2 +msgid "Search" +msgstr "" + +#: templates/shortcodes/search-properties-result.php:28 +#: templates/shortcodes/ajax-map-search-result.php:19 +#: templates/parts/archive-simple-bars.php:6 +#, php-format +msgid "Found %s Properties" +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:35 +msgid "More" +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:44 +msgid "Any" +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:63 +#: templates/single-property/meta.php:13 templates/single-property/price.php:9 +#: templates/single-property/floor-plans.php:42 +#: templates/parts/search-agents-form.php:46 +msgid "Price:" +msgstr "" + +#: templates/shortcodes/ajax-map-search.php:76 +msgid "Apply" +msgstr "" + +#: templates/shortcodes/submission-form.php:52 +#: templates/submission/submission-form.php:39 +#: templates/submission/submission-form.php:40 +msgid "Save property" +msgstr "" + +#: templates/single-property/sharebox.php:28 +msgid "Share on facebook" +msgstr "" + +#: templates/single-property/sharebox.php:35 +msgid "Share on Twitter" +msgstr "" + +#: templates/single-property/sharebox.php:42 +msgid "Share on LinkedIn" +msgstr "" + +#: templates/single-property/sharebox.php:49 +msgid "Share on Tumblr" +msgstr "" + +#: templates/single-property/sharebox.php:57 +msgid "Share on Google plus" +msgstr "" + +#: templates/single-property/sharebox.php:65 +msgid "Share on Pinterest" +msgstr "" + +#: templates/single-property/sharebox.php:72 +msgid "Email to a Friend" +msgstr "" + +#: templates/single-property/map.php:16 +msgid "Property on Map" +msgstr "" + +#: templates/single-property/map.php:28 templates/single-property/map-v2.php:25 +#: templates/single-property/preview/tabs.php:20 +msgid "Street View" +msgstr "" + +#: templates/single-property/map.php:47 templates/single-property/map-v2.php:49 +#: templates/single-property/preview/tabs.php:43 +#: templates/single-property/preview/map.php:17 +msgid "Hospital" +msgstr "" + +#: templates/single-property/map.php:53 templates/single-property/map-v2.php:55 +#: templates/single-property/preview/tabs.php:49 +#: templates/single-property/preview/map.php:23 +msgid "Library" +msgstr "" + +#: templates/single-property/map.php:59 templates/single-property/map-v2.php:61 +#: templates/single-property/preview/tabs.php:55 +#: templates/single-property/preview/map.php:29 +msgid "Pharmacy" +msgstr "" + +#: templates/single-property/map.php:66 templates/single-property/map-v2.php:68 +#: templates/single-property/preview/tabs.php:62 +#: templates/single-property/preview/map.php:36 +msgid "School" +msgstr "" + +#: templates/single-property/map.php:79 templates/single-property/map-v2.php:81 +#: templates/single-property/preview/tabs.php:75 +#: templates/single-property/preview/map.php:49 +msgid "Trainstation" +msgstr "" + +#: templates/single-property/attachments.php:21 +msgid "Download" +msgstr "" + +#. %s: Name of current post +#: templates/single-property/content.php:6 +#, php-format +msgid "Continue reading %s " +msgstr "" + +#: templates/single-property/sameagent.php:8 +#, php-format +msgid "Properties by %s" +msgstr "" + +#: templates/single-property/information.php:9 +msgid "Quick Information" +msgstr "" + +#: templates/single-property/information.php:15 +msgid "Type:" +msgstr "" + +#: templates/single-property/price.php:12 +msgid "Sale Price:" +msgstr "" + +#: templates/single-property/map-v2.php:20 +msgid "Picture" +msgstr "" + +#: templates/single-property/walkscore.php:12 +#: templates/single-property/walkscore.php:22 +msgid "Walk Scores" +msgstr "" + +#: templates/single-property/walkscore.php:25 +#: templates/single-property/walkscore.php:38 +msgid "more details here" +msgstr "" + +#: templates/single-property/walkscore.php:35 +msgid "Transit Scores" +msgstr "" + +#: templates/single-property/walkscore.php:48 +msgid "Bikeable Scores" +msgstr "" + +#: templates/single-property/walkscore.php:51 +msgid "More details here" +msgstr "" + +#: templates/single-property/floor-plans.php:22 +#: templates/single-property/floor-plans.php:34 +#, php-format +msgid "Plan %s" +msgstr "" + +#: templates/single-property/floor-plans.php:49 +msgid "Size:" +msgstr "" + +#: templates/single-property/floor-plans.php:56 +msgid "Rooms:" +msgstr "" + +#: templates/single-property/floor-plans.php:63 +msgid "Baths:" +msgstr "" + +#: templates/single-property/views-statistics.php:16 +#: templates/single-property/views-statistics.php:28 +msgid "Page Views Statistics" +msgstr "" + +#: templates/single-property/nearby.php:27 +msgid "What's nearby" +msgstr "" + +#: templates/single-property/apartments.php:24 +msgid "Price From" +msgstr "" + +#: templates/single-property/apartments.php:43 +msgid "view" +msgstr "" + +#: templates/user-search/content-savedsearch.php:9 +msgid "My Saved Searches" +msgstr "" + +#: templates/user-search/content-savedsearch.php:12 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:211 +msgid "View" +msgstr "" + +#: templates/user-search/content-savedsearch.php:12 +msgid "Delete" +msgstr "" + +#: templates/user-search/content-savedsearch.php:22 +msgid "Are you sure to delete this?" +msgstr "" + +#: templates/user-search/content-savedsearch.php:37 +msgid "No Item In Saved Searches" +msgstr "" + +#: templates/user-search/content-savedsearch.php:38 +msgid "You have not added any search data." +msgstr "" + +#: templates/user-search/render-form.php:12 +msgid "Save search" +msgstr "" + +#: templates/user-search/render-form.php:21 +msgid "Name this search." +msgstr "" + +#: templates/user-search/render-form.php:33 +msgid "Save" +msgstr "" + +#: templates/single-agency/properties.php:28 +msgid "Load More" +msgstr "" + +#: templates/single-agency/properties.php:35 +msgid "My Agency has not any property yet." +msgstr "" + +#: templates/single-agency/author-box.php:41 +msgid "Agency avatar" +msgstr "" + +#: templates/parts/membership-pricing-info.php:12 +#: templates/parts/membership-pricing-info.php:14 +msgid " Listings" +msgstr "" + +#: templates/parts/membership-pricing-info.php:14 +#: templates/parts/membership-pricing-info.php:23 +#: inc/vendors/opalmembership/membership.php:493 +#: inc/vendors/opalmembership/membership.php:494 +msgid "Unlimited" +msgstr "" + +#: templates/parts/membership-pricing-info.php:21 +#: templates/parts/membership-pricing-info.php:23 +msgid " Featured" +msgstr "" + +#: templates/parts/not-allowed.php:8 +msgid "You are not allowed to access this page." +msgstr "" + +#: templates/parts/search-agents-form-address.php:16 +#: templates/parts/search-agents-form.php:20 +#: templates/parts/search-agency-form-address.php:16 +msgid "Find an experienced agent with:" +msgstr "" + +#: templates/parts/search-agents-form-address.php:19 +#: templates/parts/search-agents-form.php:23 +#: templates/parts/search-agency-form-address.php:19 +msgid "Who sale between:" +msgstr "" + +#: templates/parts/membership-warning.php:3 +msgid "" +"Your package has 0 left listing, you could not add any more. Please upgrade " +"now" +msgstr "" + +#: templates/parts/membership-warning.php:4 +msgid "Click to this link to see plans" +msgstr "" + +#: templates/parts/property-loop-price.php:15 +msgid "Call to Price" +msgstr "" + +#: templates/parts/property-loop-price.php:34 +msgid "Contact Property" +msgstr "" + +#: templates/parts/property-types.php:4 +msgid "Types:" +msgstr "" + +#: templates/parts/has-warning.php:3 +msgid "" +"Hi! you could not edit/create a property at this time, you have not " +"permission to do." +msgstr "" + +#: templates/parts/mortgage-calculator.php:23 +#: templates/parts/mortgage-calculator.php:132 +msgid "Loan Amount" +msgstr "" + +#: templates/parts/mortgage-calculator.php:24 +#: templates/parts/mortgage-calculator.php:125 +msgid "Your payment" +msgstr "" + +#: templates/parts/mortgage-calculator.php:104 +msgid "Mortgage Payment Calculator" +msgstr "" + +#: templates/parts/mortgage-calculator.php:129 +msgid "month" +msgstr "" + +#: templates/parts/mortgage-calculator.php:139 +msgid "Your price" +msgstr "" + +#: templates/parts/mortgage-calculator.php:140 +msgid "Your deposit" +msgstr "" + +#: templates/parts/mortgage-calculator.php:141 +msgid "Your interest" +msgstr "" + +#: templates/parts/mortgage-calculator.php:157 +msgid "Deposit" +msgstr "" + +#: templates/parts/mortgage-calculator.php:163 +msgid "Annual Interest" +msgstr "" + +#: templates/parts/mortgage-calculator.php:169 +msgid "Years" +msgstr "" + +#: templates/parts/mortgage-calculator.php:174 +msgid "" +"All calculation are based on tentative and estimated figure and shall not " +"replace any financial advice" +msgstr "" + +#: templates/parts/property-categories.php:4 +msgid "Categories:" +msgstr "" + +#: templates/parts/search-agency-form.php:21 +msgid "Enter Agency Name" +msgstr "" + +#: templates/submission/submission-completed.php:8 +#: templates/submission/require-login.php:8 +msgid "" +"Login in allowing you to edit your property or submit a property, save " +"favorite real estate." +msgstr "" + +#: templates/submission/submission-completed.php:9 +#: templates/submission/require-login.php:9 +msgid "Login Now" +msgstr "" + +#: templates/submission/completed.php:11 templates/submission/completed.php:19 +#, php-format +msgid "Click to %s here %s to back to your listing or %s edit %s this." +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:49 +msgid "Social Login" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:64 +#: inc/vendors/social-login/class-opalestate-social-login.php:65 +msgid "Enable Google login" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:75 +msgid "Google Client ID" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:76 +msgid "Google Client ID is required for Google Login." +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:81 +msgid "Google Client Secret" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:82 +msgid "Google Client Secret is required for Google Login." +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:87 +msgid "Google API key" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:88 +msgid "Google API key is required for Google Login." +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:101 +#: inc/vendors/social-login/class-opalestate-social-login.php:102 +msgid "Enable Facebook login" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:112 +msgid "Facebook Application ID" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:113 +msgid "Facebook Application ID is required for Facebook login." +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:118 +msgid "Facebook Secret" +msgstr "" + +#: inc/vendors/social-login/class-opalestate-social-login.php:119 +msgid "Facebook Secret is required for Facebook login." +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:154 +msgid "Carousel Options" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:167 +msgid "Slides to Show" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:170 +msgid "Default" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:179 +msgid "Slides to Scroll" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:181 +msgid "Set how many slides are scrolled per swipe." +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:195 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:333 +msgid "Navigation" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:199 +msgid "Arrows and Dots" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:200 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:342 +msgid "Arrows" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:201 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:404 +msgid "Dots" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:222 +msgid "Carousel Additional Options" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:230 +msgid "Pause on Hover" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:244 +msgid "Autoplay" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:258 +msgid "Autoplay Speed" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:268 +msgid "Infinite Loop" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:282 +msgid "Effect" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:286 +msgid "Slide" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:287 +msgid "Fade" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:299 +msgid "Animation Speed" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:309 +msgid "Direction" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:313 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:349 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:357 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:378 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:224 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:349 +msgid "Left" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:314 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:357 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:365 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:386 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:232 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:357 +msgid "Right" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:354 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:416 +msgid "Position" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:358 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:421 +msgid "Inside" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:359 +#: inc/vendors/elementor/class-opalestate-elementor-widget-base.php:420 +msgid "Outside" +msgstr "" + +#: inc/vendors/elementor/class-opalestate-elementor-extended.php:78 +msgid "Opal Estate" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:179 +msgid "Could not allow uploading image" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:207 +#: inc/vendors/opalmembership/membership.php:568 +msgid "Number Of Properties" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:216 +#: inc/vendors/opalmembership/membership.php:577 +msgid "" +"Number of properties with this package. If not set it will be unlimited." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:220 +#: inc/vendors/opalmembership/membership.php:581 +msgid "Number Of Featured Properties" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:229 +#: inc/vendors/opalmembership/membership.php:590 +msgid "Number of properties can make featured with this package." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:233 +msgid " Unlimited listings ?" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:237 +msgid "" +"No, it is not unlimited, If not set it will be unlimited. Number of " +"properties can make featured with this package." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:252 +msgid "My Membership" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:259 +msgid "My Invoices" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:266 +msgid "Renew membership" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:424 +msgid "" +"Your membership package is expired or Your package has 0 left listing, " +"please upgrade now." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:493 +#: inc/vendors/opalmembership/membership.php:497 +msgid "(Package) Listings Included:" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:494 +#: inc/vendors/opalmembership/membership.php:498 +msgid "(Package) Featured Included:" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:500 +msgid "Listings Remaining:" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:501 +msgid "Featured Remaining:" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:546 +msgid "Membership Package" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:553 +msgid "Package" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:562 +msgid "Set package ID with -1 as free package." +msgstr "" + +#: inc/vendors/opalmembership/membership.php:563 +msgid "Membership Information" +msgstr "" + +#: inc/vendors/opalmembership/membership.php:599 +#: inc/vendors/opalmembership/membership.php:607 +msgid "Show expired time in double format." +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:22 +msgid "Free Submission" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:29 +msgid "Enable Free Submission" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:30 +msgid "Allow set automatic a free package." +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:39 +msgid "Number Free Listing" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:40 +msgid "Maximum number of Free Listing that users can submit." +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:49 +msgid "Number Free Featured" +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:50 +msgid "Maximum number of Free Featured that users can set." +msgstr "" + +#: inc/vendors/opalmembership/free-package.php:90 +msgid "Free membership" +msgstr "" + +#: inc/admin/settings/email.php:28 inc/admin/settings/general.php:28 +#: inc/admin/settings/general.php:42 +msgid "General Settings" +msgstr "" + +#: inc/admin/settings/property.php:22 +msgid "Search Page" +msgstr "" + +#: inc/admin/settings/property.php:23 +msgid "Single Page" +msgstr "" + +#: inc/admin/settings/property.php:50 +msgid "Property Settings" +msgstr "" + +#: inc/admin/settings/property.php:60 +msgid "Enable User Submission" +msgstr "" + +#: inc/admin/settings/property.php:61 +msgid "Enable to allow user post/submit properties in front-end" +msgstr "" + +#: inc/admin/settings/property.php:82 +msgid "Show Meta Information in Grid and Single Page" +msgstr "" + +#: inc/admin/settings/property.php:89 +msgid "Archive Grid layout" +msgstr "" + +#: inc/admin/settings/property.php:96 +msgid "Archive List layout" +msgstr "" + +#: inc/admin/settings/property.php:118 +msgid "User Share Search" +msgstr "" + +#: inc/admin/settings/property.php:119 +msgid "Display Share Search Link Management" +msgstr "" + +#: inc/admin/settings/property.php:129 +msgid "User Saved Search" +msgstr "" + +#: inc/admin/settings/property.php:130 +msgid "Display Save Search Link Management" +msgstr "" + +#: inc/admin/settings/property.php:141 +msgid "Search Properties Page" +msgstr "" + +#: inc/admin/settings/property.php:142 +msgid "" +"This is page to display result of properties after user searching via form." +msgstr "" + +#: inc/admin/settings/property.php:154 +msgid "Properties Per Page" +msgstr "" + +#: inc/admin/settings/property.php:155 +msgid "Enter min of properties display in search page" +msgstr "" + +#: inc/admin/settings/property.php:166 +msgid "Show Featured First" +msgstr "" + +#: inc/admin/settings/property.php:168 +msgid "Show featured first in page result, as default Newest is showed" +msgstr "" + +#: inc/admin/settings/property.php:177 +msgid "Minimum of Search Price" +msgstr "" + +#: inc/admin/settings/property.php:178 +msgid "Enter minimum of price for starting search" +msgstr "" + +#: inc/admin/settings/property.php:187 +msgid "Maximum of Search Price" +msgstr "" + +#: inc/admin/settings/property.php:188 +msgid "Enter maximum of price for starting search" +msgstr "" + +#: inc/admin/settings/property.php:199 +msgid "Minimum of Search Aea" +msgstr "" + +#: inc/admin/settings/property.php:200 +msgid "Enter minimum of area for starting search" +msgstr "" + +#: inc/admin/settings/property.php:209 +msgid "Maximum of Search Aea" +msgstr "" + +#: inc/admin/settings/property.php:210 +msgid "Enter maximum of area for starting search" +msgstr "" + +#: inc/admin/settings/property.php:220 +msgid "Search Grid layout" +msgstr "" + +#: inc/admin/settings/property.php:227 +msgid "Search List layout" +msgstr "" + +#: inc/admin/settings/property.php:234 +msgid "Horizontal Search Fields" +msgstr "" + +#: inc/admin/settings/property.php:235 +msgid "Disable or enable fields appearing in search form" +msgstr "" + +#: inc/admin/settings/property.php:243 inc/admin/settings/property.php:273 +msgid "Show Price" +msgstr "" + +#: inc/admin/settings/property.php:265 +msgid "Vertical Search Fields" +msgstr "" + +#: inc/admin/settings/property.php:306 +msgid "Show Amenities tab" +msgstr "" + +#: inc/admin/settings/property.php:307 +msgid "Show Amenities tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:317 +msgid "Show Facilities tab" +msgstr "" + +#: inc/admin/settings/property.php:318 +msgid "Show Facilities tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:328 +msgid "Show Attachments tab" +msgstr "" + +#: inc/admin/settings/property.php:329 +msgid "Show Attachments tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:339 +msgid "Show Video tab" +msgstr "" + +#: inc/admin/settings/property.php:340 +msgid "Show Video tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:350 +msgid "Show Map tab" +msgstr "" + +#: inc/admin/settings/property.php:351 +msgid "Show Map tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:361 +msgid "Show Nearby tab" +msgstr "" + +#: inc/admin/settings/property.php:362 +msgid "Show Nearby tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:372 +msgid "Show Walk Scores tab" +msgstr "" + +#: inc/admin/settings/property.php:373 +msgid "Show Walk Scores tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:383 +msgid "Show Apartments tab" +msgstr "" + +#: inc/admin/settings/property.php:384 +msgid "Show Apartments tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:394 +msgid "Show Floor Plans tab" +msgstr "" + +#: inc/admin/settings/property.php:395 +msgid "Show Floor Plans tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:405 +msgid "Show Views Statistics tab" +msgstr "" + +#: inc/admin/settings/property.php:406 +msgid "Show Views Statistics tab in the single property page." +msgstr "" + +#: inc/admin/settings/property.php:416 +msgid "Views Statistics time limit (days)" +msgstr "" + +#: inc/admin/settings/property.php:417 +msgid "The number of days will be saved to the database." +msgstr "" + +#: inc/admin/settings/property.php:429 +msgid "Related properties layout" +msgstr "" + +#: inc/admin/settings/property.php:430 +msgid "Select a layout for related properties." +msgstr "" + +#: inc/admin/settings/property.php:437 +msgid "Nearby properties layout" +msgstr "" + +#: inc/admin/settings/property.php:438 +msgid "Select a layout for nearby properties." +msgstr "" + +#: inc/admin/settings/general.php:51 +msgid "User Management Page" +msgstr "" + +#: inc/admin/settings/general.php:52 +msgid "" +"This is page use User Management Page using for show content of management " +"page such as profile, my properties" +msgstr "" + +#: inc/admin/settings/general.php:58 +msgid "My Account Page" +msgstr "" + +#: inc/admin/settings/general.php:59 +msgid "This is page use User login and register an account, or reset password." +msgstr "" + +#: inc/admin/settings/general.php:65 +msgid "Enable Message Database" +msgstr "" + +#: inc/admin/settings/general.php:66 +msgid "" +"Allow User send message Contact/Equire via email and saved into database to " +"exchange theirs message direct in User Message Management" +msgstr "" + +#: inc/admin/settings/general.php:77 +msgid "Maximun Upload Image Size" +msgstr "" + +#: inc/admin/settings/general.php:78 inc/admin/settings/general.php:86 +msgid "Set maximun volumn size having < x MB" +msgstr "" + +#: inc/admin/settings/general.php:85 +msgid "Maximun Upload Image Files" +msgstr "" + +#: inc/admin/settings/general.php:93 +msgid "Maximun Upload Other Size" +msgstr "" + +#: inc/admin/settings/general.php:94 inc/admin/settings/general.php:102 +msgid "Set maximun volumn size having < x MB for upload docx, pdf..." +msgstr "" + +#: inc/admin/settings/general.php:101 +msgid "Maximun Upload Other Files" +msgstr "" + +#: inc/admin/settings/general.php:110 inc/admin/settings/general.php:121 +msgid "Agent Image Size" +msgstr "" + +#: inc/admin/settings/general.php:111 inc/admin/settings/general.php:122 +msgid "" +"The Loop Image is an Agent that is chosen as the representative Agent in " +"grid and list." +msgstr "" + +#: inc/admin/settings/general.php:133 +msgid "Loop Image Size" +msgstr "" + +#: inc/admin/settings/general.php:134 +msgid "" +"The Loop Image is an image that is chosen as the representative image in " +"grid and list." +msgstr "" + +#: inc/admin/settings/general.php:144 +msgid "Featured Image Size" +msgstr "" + +#: inc/admin/settings/general.php:145 +msgid "" +"The Featured Image is an image that is chosen as the representative image in " +"single page. ." +msgstr "" + +#: inc/admin/settings/general.php:150 +msgid "" +"To generate images with new image sizes, you can use this Force Regenerate Thumbnails" +msgstr "" + +#: inc/admin/settings/general.php:154 +msgid "Minimum of Target Price For Agent" +msgstr "" + +#: inc/admin/settings/general.php:155 +msgid "Enter minimum of price for starting search agent by target" +msgstr "" + +#: inc/admin/settings/general.php:164 +msgid "Maximum of Target Price For Agent" +msgstr "" + +#: inc/admin/settings/general.php:165 +msgid "Enter maximum of price for starting search agent by target" +msgstr "" + +#: inc/admin/settings/general.php:174 +msgid "Single Layout Page" +msgstr "" + +#: inc/admin/settings/general.php:175 +msgid "Choose layout for single property." +msgstr "" + +#: inc/admin/settings/general.php:183 +msgid "Currency Settings" +msgstr "" + +#: inc/admin/settings/general.php:191 +msgid "Currency" +msgstr "" + +#: inc/admin/settings/general.php:199 +msgid "Currency Position" +msgstr "" + +#: inc/admin/settings/general.php:204 +msgid "Before - $10" +msgstr "" + +#: inc/admin/settings/general.php:205 +msgid "After - 10$" +msgstr "" + +#: inc/admin/settings/general.php:210 +msgid "Thousands Separator" +msgstr "" + +#: inc/admin/settings/general.php:211 +msgid "The symbol (typically , or .) to separate thousands" +msgstr "" + +#: inc/admin/settings/general.php:217 +msgid "Decimal Separator" +msgstr "" + +#: inc/admin/settings/general.php:218 +msgid "The symbol (usually , or .) to separate decimal points" +msgstr "" + +#: inc/admin/settings/general.php:224 +msgid "Number of Decimals" +msgstr "" + +#: inc/admin/settings/general.php:225 +msgid "This sets the number of decimal points shown in displayed prices." +msgstr "" + +#: inc/admin/settings/general.php:234 inc/admin/settings/general.php:235 +msgid "Measurement Unit" +msgstr "" + +#: inc/admin/settings/general.php:239 +msgid "sq ft" +msgstr "" + +#: inc/admin/settings/general.php:240 +msgid "sq m" +msgstr "" + +#: inc/admin/settings/general.php:241 +msgid "mq" +msgstr "" + +#: inc/admin/settings/general.php:242 +msgid "m2" +msgstr "" + +#: inc/admin/settings/general.php:247 +msgid "Google Map API" +msgstr "" + +#: inc/admin/settings/general.php:248 +msgid "" +"You need to register Google API " +"Key, then put the key in this setting." +msgstr "" + +#: inc/admin/settings/3rd_party.php:49 +msgid "3rd Party Settings" +msgstr "" + +#: inc/admin/settings/3rd_party.php:58 +msgid "Walk Score" +msgstr "" + +#: inc/admin/settings/3rd_party.php:66 +msgid "Walk Score APi Key" +msgstr "" + +#: inc/admin/settings/3rd_party.php:67 +msgid "" +"Add Walk Score API key. To get your Walk Score API key, go to your Walk " +"Score Account." +msgstr "" + +#: inc/admin/settings/3rd_party.php:77 +msgid "Yelp" +msgstr "" + +#: inc/admin/settings/3rd_party.php:85 +msgid "Yelp API Client ID" +msgstr "" + +#: inc/admin/settings/3rd_party.php:86 +msgid "" +"Add Yelp client ID. To get your Yelp Api Client ID, go to your Yelp Account. " +"Register here" +msgstr "" + +#: inc/admin/settings/3rd_party.php:92 +msgid "Yelp API Secret" +msgstr "" + +#: inc/admin/settings/3rd_party.php:93 +msgid "" +"Add Yelp API Secret. Register here" +msgstr "" + +#: inc/admin/settings/3rd_party.php:99 +msgid "Yelp App key" +msgstr "" + +#: inc/admin/settings/3rd_party.php:100 +msgid "" +"You can find it in your Yelp Application Dashboard. Register here" +msgstr "" + +#: inc/admin/settings/3rd_party.php:106 +msgid "Yelp Categories" +msgstr "" + +#: inc/admin/settings/3rd_party.php:107 +msgid "Yelp Categories to show on front page" +msgstr "" + +#: inc/admin/settings/3rd_party.php:113 +msgid "Yelp - Number of results" +msgstr "" + +#: inc/admin/settings/3rd_party.php:114 +msgid "Number of results to show on listing page for each category." +msgstr "" + +#: inc/admin/settings/3rd_party.php:124 inc/admin/settings/3rd_party.php:125 +msgid "Yelp Distance Measurement Unit" +msgstr "" + +#: inc/admin/settings/3rd_party.php:130 +msgid "kilometers" +msgstr "" + +#: inc/admin/rating/class-rating.php:54 inc/admin/rating/class-rating.php:58 +msgid "Review Settings" +msgstr "" + +#: inc/admin/rating/class-rating.php:64 inc/admin/rating/class-rating.php:65 +msgid "Enable property reviews" +msgstr "" + +#: inc/admin/rating/class-rating.php:74 inc/admin/rating/class-rating.php:75 +msgid "Enable agency reviews" +msgstr "" + +#: inc/admin/rating/class-rating.php:84 inc/admin/rating/class-rating.php:85 +msgid "Enable agent reviews" +msgstr "" + +#: inc/admin/property/class-property.php:100 +msgid "Sku" +msgstr "" + +#: inc/admin/property/class-property.php:103 +msgid "Author" +msgstr "" + +#: inc/admin/property/class-property.php:104 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:213 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:181 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:202 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:213 +msgid "Date" +msgstr "" + +#: inc/admin/agent/class-agent.php:94 +msgid "Target Search" +msgstr "" + +#: templates/user/social-login/google-button.php:20 +msgid "Connect with Google" +msgstr "" + +#: templates/user/social-login/facebook-button.php:20 +msgid "Connect with Facebook" +msgstr "" + +#: templates/user/agency/agency-team.php:45 +msgid "Processing" +msgstr "" + +#: templates/user/agency/profile-agency.php:23 +msgid "Edit Agency Profile" +msgstr "" + +#: templates/user/agent/profile-agent.php:7 +msgid "Edit Agent Profile" +msgstr "" + +#: templates/user/agent/profile-agent.php:23 +msgid "Agent edit profile form is not avariable" +msgstr "" + +#: templates/search-box/fields/search-text.php:1 +msgid "Keyword" +msgstr "" + +#: templates/search-box/fields/search-text.php:2 +msgid "Type keyword" +msgstr "" + +#: templates/search-box/fields/more-options.php:19 +msgid "More Search Options" +msgstr "" + +#: templates/search-box/fields/radius.php:14 +msgid "Radius:" +msgstr "" + +#: templates/search-box/fields/search-city-text.php:24 +msgid "Type City or Area" +msgstr "" + +#: templates/search-box/fields/search-city-text.php:35 +msgid "Show with in." +msgstr "" + +#: templates/search-box/fields/search-city-text.php:37 +msgid "Radius" +msgstr "" + +#: templates/search-box/fields/search-city-text.php:38 +msgid "Of My Location" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:40 +msgid "Search: Form Builder" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:80 +msgid "Agency/Agent Tab Form Search" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:95 +msgid "Brand Items" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:100 +msgid "Field" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-form-builder.php:108 +msgid "Column" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:54 +msgid "Block: Agent Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:94 +msgid "Agents Search Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:101 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:101 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:87 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:101 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:87 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:80 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:87 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:101 +msgid "Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:105 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:105 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:91 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:105 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:91 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:105 +msgid "Advanded" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:106 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:106 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:92 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:106 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:92 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:106 +msgid "Search By Address" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:114 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:114 +msgid "Enable Sortable Bar" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:122 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:113 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:113 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:122 +msgid "Item Layout" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:134 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:106 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:111 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:114 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:125 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:114 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:125 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:97 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:134 +msgid "Columns" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:150 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:117 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:125 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:130 +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:141 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:130 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:141 +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:112 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:150 +msgid "Columns Gap" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:182 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:151 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:172 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:163 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:163 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:182 +msgid "Query" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:190 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:159 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:180 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:190 +msgid "Posts Per Page" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:201 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:169 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:190 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:171 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:171 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:201 +msgid "Advanced" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:209 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:177 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:198 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:179 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:179 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:209 +msgid "Order By" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:215 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:183 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:204 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:215 +msgid "Menu Order" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:216 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:184 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:205 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:216 +msgid "Random" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:228 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:196 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:217 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:197 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:197 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:228 +msgid "ASC" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:229 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:197 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:218 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:198 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:198 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:229 +msgid "DESC" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:247 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:215 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:236 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:247 +msgid "Category Operator" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:251 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:219 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:240 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:251 +msgid "AND" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:252 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:220 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:241 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:252 +msgid "IN" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:253 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:221 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:242 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:253 +msgid "NOT IN" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:266 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:276 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:277 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:284 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:298 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:305 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:266 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:276 +msgid "Pagination" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:281 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:283 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:289 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:291 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:310 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:312 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:281 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:283 +msgid "Numbers" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:282 +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:283 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:290 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:291 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:311 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:312 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:282 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:283 +msgid "Previous/Next" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:291 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:299 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:320 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:291 +msgid "Page Limit" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:302 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:310 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:331 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:302 +msgid "Shorten" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:317 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:325 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:346 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:317 +msgid "Previous Label" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:318 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:326 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:347 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:318 +msgid "« Previous" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:331 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:339 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:360 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:331 +msgid "Next Label" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:332 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:340 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:361 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:332 +msgid "Next »" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:345 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:353 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:374 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:220 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:345 +msgid "Alignment" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agent-collection.php:353 +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:361 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:382 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:228 +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:353 +msgid "Center" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:40 +msgid "Search: Property Results" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:80 +msgid "Show Collection as Default Results" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:87 +msgid "" +"This is often used for building seach page, it combines with block => Search:" +" Property Form, Search:Map Preview." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:96 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:101 +msgid "Style Item Layout" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:138 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:159 +#: inc/vendors/elementor/widgets/opalestate-category-list.php:152 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:152 +msgid "Enable Carousel" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:243 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:264 +msgid "Lables" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-property-results.php:263 +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:284 +msgid "Cities" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:53 +msgid "Block: Property Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:93 +msgid "Property Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:146 +msgid "Show" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:150 +msgid "Featured only" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-property-collection.php:151 +msgid "Without Featured" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:41 +msgid "Search: Property Form " +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:81 +msgid "Property Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:88 +msgid "" +"This is often used for building seach page, it combines with block => Search:" +" Map Preview, Search: Property Results." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:158 +msgid "Display More Options" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:179 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:299 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:293 +msgid "Normal" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:208 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:340 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:383 +msgid "Hover" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:233 +msgid "Input" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:253 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:318 +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:359 +msgid "Background color" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:265 +msgid "Border color" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-searchbox.php:289 +msgid "Button" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:54 +msgid "Block: Category Listing" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:94 +msgid "Category Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:183 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:183 +msgid "ID" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:185 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:185 +msgid "Count" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:216 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:216 +msgid "Limit" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-category-list.php:217 +#: inc/vendors/elementor/widgets/opalestate-city-list.php:217 +msgid "Maximum number of terms to return." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:40 +msgid "Block: Agency - Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:80 +msgid "Agency Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:100 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:100 +msgid "Target Submit Page" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:104 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:104 +msgid "Current Page" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agency.php:105 +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:105 +msgid "Global Agent Search Page" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:40 +msgid "Search: Maps Preview" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:80 +msgid "Map Preview Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:89 +msgid "" +"This is often used for building seach page, it combines with block => Search:" +" Property Form, Search: Property Results." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:99 +msgid "Enable Static Map" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:108 +msgid "Map On Right?" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:121 +msgid "Map Width %" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-map-top-search.php:144 +msgid "Map Height" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-city-list.php:54 +msgid "Block: City Listing" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-city-list.php:94 +msgid "City Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:40 +msgid "Block: Agents - Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-search-agents.php:80 +msgid "Agents Search Form" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-split-maps-search.php:40 +msgid "Block: Split Maps Property Search" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:44 +msgid "Block: Account Button" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:96 +msgid "Not logged in" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:103 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:157 +msgid "Choose Icon" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:112 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:166 +msgid "Enable Label" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:120 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:174 +msgid "Label Text" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:122 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:176 +msgid "Account" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:133 +msgid "Logged in" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:140 +msgid "Enable Avatar" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:149 +msgid "Enable Notification" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:187 +msgid "Use Custom Dashboard Menu" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:195 +msgid "Menu" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:201 +#, php-format +msgid "" +"Go to the Menus screen to manage your " +"menus." +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:300 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:390 +msgid "Icon Color" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:316 +#: inc/vendors/elementor/widgets/opalestate-account-button.php:402 +msgid "Background Color" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:328 +msgid "Icon Font Size" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:357 +msgid "Border Radius" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:369 +msgid "Padding" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:501 +msgid "Sign in" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:504 +msgid "Create an Account" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-account-button.php:511 +msgid "Username or email" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:54 +msgid "Block: Agencies Collection" +msgstr "" + +#: inc/vendors/elementor/widgets/opalestate-agency-collection.php:94 +msgid "Agencies Search/Collection" +msgstr "" + +#: inc/vendors/cmb2-plugins/uploader/uploader.php:154 +#, php-format +msgid "Allow upload file have size < %s MB and maximum number of files: %s" +msgstr "" + +#: inc/admin/views/addons/list.php:2 +msgid "Opal Estate Add-ons" +msgstr "" + +#: inc/admin/views/addons/list.php:4 +msgid "The following Add-ons extend the functionality of Opal Estate." +msgstr "" + +#: inc/admin/views/addons/list.php:345 +msgid "" +"There was an error retrieving the Opalestate Add-ons list from the server. " +"Please try again later." +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:44 +msgid "As an author, you can add other users to your agency." +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:46 +msgid "" +"Add someone to your agency, please enter extractly username in below input:" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:51 +msgid "add" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:64 +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/user/user.php:76 +msgid "Are you sure to delete this" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:46 +msgid "Map Address" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:54 +msgid "Latitude" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:64 +msgid "Longitude" +msgstr "" + +#: inc/vendors/cmb2-plugins/cmb2/custom-fields/map/map.php:73 +msgid "" +"You need to register Google API " +"Key, then put the key in plugin setting." +msgstr "" + +#. Name of the plugin +msgid "Opal Estate Pro" +msgstr "" + +#. Description of the plugin +msgid "" +"Opal Real Estate Plugin is an ideal solution and brilliant choice for you to " +"set up a professional estate website." +msgstr "" + +#. URI of the plugin +msgid "http://www.wpopal.com/product/opal-estate-wordpress-plugin/" +msgstr "" + +#. Author of the plugin +msgid "WPOPAL" +msgstr "" + +#. Author URI of the plugin +msgid "http://www.wpopal.com" +msgstr "" diff --git a/license.txt b/license.txt new file mode 100755 index 00000000..85e5a0c4 --- /dev/null +++ b/license.txt @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/opal-estate-pro.php b/opal-estate-pro.php new file mode 100755 index 00000000..5cf35eb6 --- /dev/null +++ b/opal-estate-pro.php @@ -0,0 +1,491 @@ +setup_constants(); + + register_activation_hook( OPALESTATE_PLUGIN_FILE, [ 'Opalestate_Install', 'install' ] ); + add_action( 'plugins_loaded', [ self::$instance, 'load_textdomain' ] ); + self::$instance->setup(); + self::$instance->roles = new Opalestate_Roles(); + self::$instance->html = new Opalestate_HTML_Elements(); + self::$instance->api = new Opalestate_API(); + self::$instance->session = new Opalestate_Session(); + + /** + * + */ + add_filter( 'opalestate_google_map_api', [ __CLASS__, 'load_google_map_api' ] ); + add_action( 'cli_init', [ self::$instance, 'init_cli' ] ); + } + + return self::$instance; + } + + public static function load_google_map_api( $key ) { + if ( opalestate_options( 'google_map_api_keys' ) ) { + $key = '//maps.googleapis.com/maps/api/js?sensor=false&libraries=places&key=' . opalestate_options( 'google_map_api_keys' ); + } + + return $key; + } + + public function init_cli() { + $this->includes( + [ + 'cli/export.php', + ] + ); + } + + /** + * Throw error on object clone + * + * The whole idea of the singleton design pattern is that there is a single + * object, therefore we don't want the object to be cloned. + * + * @return void + * @access protected + */ + public function __clone() { + // Cloning instances of the class is forbidden + _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'opalestate-pro' ), '1.0.1' ); + } + + /** + * + */ + public function setup_constants() { + // Plugin version + if ( ! defined( 'OPALESTATE_VERSION' ) ) { + define( 'OPALESTATE_VERSION', '1.0.1' ); + } + + // Plugin Folder Path + if ( ! defined( 'OPALESTATE_PLUGIN_DIR' ) ) { + define( 'OPALESTATE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); + } + + // Plugin Folder URL + if ( ! defined( 'OPALESTATE_PLUGIN_URL' ) ) { + define( 'OPALESTATE_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); + } + + // Plugin Root File + if ( ! defined( 'OPALESTATE_PLUGIN_FILE' ) ) { + define( 'OPALESTATE_PLUGIN_FILE', __FILE__ ); + } + + // Plugin Root File + if ( ! defined( 'OPALESTATE_THEMER_WIDGET_TEMPLATES' ) ) { + define( 'OPALESTATE_THEMER_WIDGET_TEMPLATES', get_stylesheet_directory() . '/' ); + } + + if ( ! defined( 'OPALMEMBERSHIP_PACKAGES_PREFIX' ) ) { + define( 'OPALMEMBERSHIP_PACKAGES_PREFIX', 'opalestate_package_' ); + } + + if ( ! defined( "OPALESTATE_CLUSTER_ICON_URL" ) ) { + define( 'OPALESTATE_CLUSTER_ICON_URL', apply_filters( 'opalestate_cluster_icon_url', OPALESTATE_PLUGIN_URL . 'assets/cluster-icon.png' ) ); + } + + /// define; + define( 'OPALESTATE_AGENT_PREFIX', 'opalestate_agt_' ); + define( 'OPALESTATE_PROPERTY_PREFIX', 'opalestate_ppt_' ); + define( 'OPALESTATE_AGENCY_PREFIX', 'opalestate_ofe_' ); + } + + + public function setup() { + global $opalestate_options; + + /** + * Get the CMB2 bootstrap! + * + * @description: Checks to see if CMB2 plugin is installed first the uses included CMB2; we can still use it even it it's not active. This prevents fatal error conflicts with other themes and users of the CMB2 WP.org plugin + * + */ + require_once OPALESTATE_PLUGIN_DIR . 'inc/vendors/cmb2-plugins/init.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/admin/register-settings.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/admin/functions.php'; + + if ( is_admin() ) { + require_once OPALESTATE_PLUGIN_DIR . 'inc/admin/class-admin.php'; + } + + $opalestate_options = opalestate_get_settings(); + + $this->includes( + [ + 'class-template-loader.php', + 'query-functions.php', + 'mixes-functions.php', + 'class-opalestate-roles.php', + 'classes/class-opalestate-session.php', + 'classes/class-opalestate-abs-query.php', + 'classes/class-opalestate-metabox-user.php', + 'classes/class-opalestate-geolocation.php', + 'classes/class-opalestate-yelp.php', + 'classes/class-opalestate-walkscore.php', + 'classes/class-opalestate-multilingual.php', + //'classes/metabox/class-metabox-agency.php', + ] + ); + + // rating + $this->includes( + [ + 'rating/class-opalestate-rating.php', + ] + ); + + // message + $this->includes( + [ + 'message/class-opalestate-message.php', + 'message/class-opalestate-request-reviewing.php', + 'message/functions.php', + ] + ); + + // agent + $this->includes( + [ + 'agent/class-opalestate-agent-posttype.php', + 'agent/class-opalestate-agent.php', + 'agent/class-opalestate-agent-query.php', + 'agent/class-opalestate-agent-front.php', + 'agent/class-opalestate-agent-metabox.php', + ] + ); + + // agent + $this->includes( + [ + 'agency/class-opalestate-agency-posttype.php', + 'agency/class-opalestate-agency.php', + 'agency/class-opalestate-agency-query.php', + 'agency/class-opalestate-agency-front.php', + 'agency/class-opalestate-agency-metabox.php', + ] + ); + + /// property /// + $this->includes( + [ + 'property/class-metabox-property-admin.php', + 'property/class-opalestate-posttype.php', + 'property/class-opalestate-property-query.php', + 'property/class-opalestate-query.php', + 'property/class-opalestate-favorite.php', + 'property/class-opalestate-property.php', + 'property/class-opalestate-shortcodes.php', + 'property/class-opalestate-search.php', + 'property/class-opalestate-view-stats.php', + 'property/functions.php', + ] + ); + + + /// user /// + $this->includes( + [ + 'user/functions.php', + 'user/class-opalestate-user.php', + 'user/class-opalestate-user-form-handler.php', + 'user/class-opalestate-user-search.php', + 'user/class-user-statistics.php', + ] + ); + + $this->includes( + [ + 'taxonomies/class-taxonomy-categories.php', + 'taxonomies/class-taxomony-amenities.php', + 'taxonomies/class-taxonomy-labels.php', + 'taxonomies/class-taxonomy-status.php', + 'taxonomies/class-taxonomy-types.php', + 'taxonomies/class-taxonomy-neighborhood.php', + 'taxonomies/class-taxonomy-locations.php', + 'taxonomies/class-taxonomy-city.php', + 'taxonomies/class-taxonomy-state.php', + ] + ); + + require_once OPALESTATE_PLUGIN_DIR . 'inc/api/class-opalestate-api.php'; + + $this->includes( + [ + 'template-functions.php', + ] + ); + + /// + $this->includes( + [ + 'class-opalestate-enqueue.php', + ] + ); + + //// enable or disable submission //// + if ( opalestate_options( 'enable_submission', 'on' ) == 'on' ) { + $this->includes( + [ + 'submission/class-metabox-property-submission.php', + 'submission/class-opalestate-submission.php', + ] + ); + + } + + $this->includes( + [ + 'class-no-captcha-recaptcha.php', + 'class-opalestate-email.php', + ] + ); + + require_once OPALESTATE_PLUGIN_DIR . 'inc/class-opalestate-install.php'; + + require_once OPALESTATE_PLUGIN_DIR . 'inc/class-opalestate-html.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/function-search-fields.php'; + + add_action( 'widgets_init', [ $this, 'widgets_init' ] ); + + add_action( 'init', [ $this, 'set_location_actived' ] ); + + require_once OPALESTATE_PLUGIN_DIR . 'inc/ajax-functions.php'; + require_once OPALESTATE_PLUGIN_DIR . 'inc/template-hook-functions.php'; + + add_action( 'plugins_loaded', [ $this, 'load_exts' ] ); + $this->load_vendors(); + } + + /** + * Include list of collection files + * + * @var array $files + */ + public function load_vendors() { + if ( defined( "ELEMENTOR_VERSION" ) ) { + require_once OPALESTATE_PLUGIN_DIR . 'inc/vendors/elementor/class-opalestate-elementor-extended.php'; + } + + require_once OPALESTATE_PLUGIN_DIR . 'inc/vendors/social-login/class-opalestate-social-login.php'; + } + + /** + * Include list of collection files + * + * @var array $files + */ + public function includes( $files ) { + foreach ( $files as $file ) { + $this->_include( $file ); + } + } + + /** + * include single file if found + * + * @var string $file + */ + private function _include( $file = '' ) { + $file = OPALESTATE_PLUGIN_DIR . 'inc/' . $file; + //if ( file_exists( $file ) ) { + include_once $file; + //} + } + + /** + * Load extensions. + */ + public function load_exts() { + if ( class_exists( 'OpalMembership' ) ) { + require_once OPALESTATE_PLUGIN_DIR . 'inc/vendors/opalmembership/membership.php'; + } + } + + /** + * Set location actived. + */ + public static function set_location_actived() { + if ( isset( $_GET['set_location'] ) && ! empty( $_GET['set_location'] ) ) { + $_SESSION['set_location'] = trim( $_GET['set_location'] ); + wp_redirect( home_url( '/' ) ); + exit; + } + if ( isset( $_GET['clear_location'] ) && ! empty( $_GET['clear_location'] ) ) { + $_SESSION['set_location'] = null; + wp_redirect( home_url( '/' ) ); + exit; + } + if ( isset( $_SESSION['set_location'] ) && ! empty( $_SESSION['set_location'] ) ) { + Opalestate_Query::$LOCATION = $_SESSION['set_location']; + } + + if ( get_current_user_id() > 0 ) { + do_action( "opalestate_user_init" ); + } + } + + /** + * Load plugin textdomain. + */ + public function load_textdomain() { + // Set filter for Opalestate's languages directory + $lang_dir = dirname( plugin_basename( OPALESTATE_PLUGIN_FILE ) ) . '/languages/'; + $lang_dir = apply_filters( 'opalestate_languages_directory', $lang_dir ); + + // Traditional WordPress plugin locale filter + $locale = apply_filters( 'plugin_locale', get_locale(), 'opalestate-pro' ); + $mofile = sprintf( '%1$s-%2$s.mo', 'opalestate-pro', $locale ); + + // Setup paths to current locale file + $mofile_local = $lang_dir . $mofile; + $mofile_global = WP_LANG_DIR . '/opalestate/' . $mofile; + + if ( file_exists( $mofile_global ) ) { + // Look in global /wp-content/languages/opalestate folder + load_textdomain( 'opalestate-pro', $mofile_global ); + } elseif ( file_exists( $mofile_local ) ) { + // Look in local /wp-content/plugins/opalestate/languages/ folder + load_textdomain( 'opalestate-pro', $mofile_local ); + } else { + // Load the default language files + load_plugin_textdomain( 'opalestate-pro', false, $lang_dir ); + } + } + + public function widgets_init() { + opalestate_includes( OPALESTATE_PLUGIN_DIR . 'inc/widgets/*.php' ); + } + } +} + +if ( ! function_exists( 'OpalEstate' ) ) { + function OpalEstate() { + return OpalEstate::get_instance(); + } + + // Constructor. + OpalEstate(); +} diff --git a/project.json b/project.json new file mode 100755 index 00000000..5bd75c7d --- /dev/null +++ b/project.json @@ -0,0 +1,54 @@ +{ + "name" : "latehome", + "version": "1.0", + "plugin" : "opal-estate-pro", + "theme" : "wpopalbootstrap", + "domain" : "latehome", + "server" : "http://dev.wpopal.com/latehome", + "server_source": "http://source.wpopal.com/opal-estate-pro-source", + "folder_source":"sample", + "description":"Single Property WordPress Theme comes with the modern & luxury design is a perfect theme for any businesses, agencies & websites about properties, houses, business spaces, apartment & building complexes and more others. The theme is built with the powerful page builder Elementor, One Click Import and other great features needed for any successful property websites.", + "author" : "ThemeLexus", + "author_uri" :"http://www.themelexus.com/", + "themeuri" : "http://demo2.themelexus.com/latehome/", + "themeinfo":{ + "document" : "http://wpopal.com/guides/latehome", + "support" : "https://themelexus.ticksy.com/", + "envato" : "https://themeforest.net/user/themelexus/portfolio", + "facebook" : "https://www.facebook.com/themelexus/", + "twitter" : "https://twitter.com/opalwordpress", + "youtube" : "https://www.youtube.com/channel/UCEVKfaT81jFq4HE1Yky99GA", + "email" : "themelexus@gmail.com", + "sample_link" : "http://source.wpopal.com/latehome-source/samples.json" + }, + + "oldurl": "http://localhost/wordpress/latehome", + "newurl": "http://localhost/wordpress/latehome", + "subpath": "/wordpress/latehome", + "prefix": "n-", + "blogs": "244,2573,2575,2578", + "single":{ + "name": "Demo latehome", + "active": { + "header": "header-1", + "footer": "footer-1", + "page": "home-1" + }, + "plugins": { + "contact-form-7": "1600" + }, + "sliders": [ + "Slider-1.zip", + "slider-3.zip" + ], + "options": {}, + "plugins":{ + "contact-form-7": "contact-form-7", + "opal-widgets-for-elementor": "opal-widgets-for-elementor", + "wpopal-medical": "wpopal-medical", + "opal-service": "opal-service" + } + }, + "niches": [ + ] +} diff --git a/readme.txt b/readme.txt new file mode 100755 index 00000000..05d8cc3b --- /dev/null +++ b/readme.txt @@ -0,0 +1,96 @@ +=== Plugin Name === +Contributors: wpopal +Donate link: http://www.wpopal.com/product/opal-estate-wordpress-plugin/ +Tags: estate, property, opalestate, house for rent, agency for lease, estate submission, agents estate property +Requires at least: 4.6 +Tested up to: 5.2.2 +Stable tag: 1.0.1 +License: GPLv3 +License URI: http://www.gnu.org/licenses/gpl-3.0.html + +Opal Real Estate Plugin is an ideal solution and brilliant choice for you to set up a professional estate website + +== Description == + +Whether you want to create a website for your real estate business and you are meeting difficulties to pick a suitable real estate plugin to install in your property site. Opal real estate plugin Pro will be your best choice to help you control your site in a perfect way. + +The plugin will not make you disappointed with ease of use, friendly & flexible with users, high advanced functions and a range of powerful feature updated insight. They are created for selling, buying or renting an apartment, villa, house, flat, etc. Scroll down to see how awesome it is! + +[youtube https://www.youtube.com/watch?v=B7UrfNzPkFg] + += Features Include: = + +* - Potential Real Estate Listing to the website - + +* 100% Responsive and Mobile Ready +* Easily integrated to any WordPress website. +* Quick to set up, publish and update +* Easy to use and customize +* Display property listings in a responsive list or grid format +* Compatible with all kinds of Themes and Frameworks +* Start up with the Free version with menu plugin +* Easy to sort, search and manage properties listings +* Available for kinds of property listing such as property, rental, land, rural, business, commercial, commercial land. +* SEO friendly URL’s, mobile friendly design layout +* Facebook and Google + login in: Clients can log into the website with via social accounts! + +* - Easy for Developer to design and customize - + +* Excellent, clean & clear, extensible code +* Powerful plugin to match with your design +* Customize Css, HTML..easily and exactly +* Add new templates in seconds and use with shortcodes. +* Easy and Quick to understand API’s with detailed documentation +* Developer friendly with dozens of actions and filters. +* Custom labels for everything and full translation support. +* Hundreds of filters to modify the default behaviour of the plugin. +* Powerful Shortcodes and Widgets +* API Support allow display properties, agents on any applications + += More Features = + +* Search properties: Properties List, List Sidebar, Grid, Grid Sidebar, Search result, Category, Location, Type, Submit Properties.. +* Support Membership Packages: There are many different packages with specific features suitable for users to choose the best one for their business goal. +* Search Agents: This plugin supports filter function for selecting location, type and price of experienced agents conveniently +* Quick Search: Users can quickly search properties or agents based on filter location, type, packing,bathroom, bedroom.. +* Search Google Map +* Revolution Sliders +* Multilingual Support + + += WHAT IS NEW IN PRO VERSION = + +* Agency Agency and allow edit profile with user having Opal Estate Agency Role. Display Properties and members of agency +* Implement Google Capcha for all Email Form +* Implement Saved Search Form allowing user save theirs result as loved collection. They are managed with Saved Search Menu of user dashboard +* Supported Widgets working with Elementor page builder +* Implement Share Search Link for friend +* Implement property labels and allow customize color, background of label +* Improve Custom upload Marker icon for property types +* Improve free package for new registered user +* Create Shortcode ajax search + += Third party = +* Our plugin gets property scores via [WalkScore](https://www.walkscore.com/ "WalkScore"), you can visit [Walk Score Terms of Use](https://www.walkscore.com/terms-of-use.shtml "WalkScore term +page") for more information. +* Our plugin gets nearby properties via [Yelp](https://www.yelp.com/ "Yelp"), you can visit [Yelp Terms of Use](https://www.yelp.com/static?p=tos "Yelp term +page") for more information. +* Our plugin use [Facebook Social login](https://developers.facebook.com/docs/facebook-login/ "Facebook login") and [Google Social login](https://auth0.com/docs/connections/social/google "Google") + +== Installation == + +This section describes how to install the plugin and get it working. + + +1. Upload the plugin files to the `/wp-content/plugins/opal-estate-pro directory, or install the plugin through the WordPress plugins screen directly. +2. Activate the plugin through the 'Plugins' screen in WordPress +3. Use the Properties->Settings screen to configure the plugin + + +== Frequently Asked Questions == + +* Detailed guide to install and customize: [documentation](http://www.wpopal.com/guides/plugin/opalestate-pro/ "Visit the Plugin docs") +* Video guide and tutorials how to set up +* Images and refer links +* Easy for user to follow up +* System tickets support 24/7 available : [free support](https://wpopal.ticksy.com/ "Visit the Plugin support Page") diff --git a/templates/.DS_Store b/templates/.DS_Store new file mode 100755 index 00000000..af43a319 Binary files /dev/null and b/templates/.DS_Store differ diff --git a/templates/archive-opalestate_agency.php b/templates/archive-opalestate_agency.php new file mode 100755 index 00000000..96c90ef1 --- /dev/null +++ b/templates/archive-opalestate_agency.php @@ -0,0 +1,82 @@ + + +
            +
            + +
            +

            +

            +
            + +
            + true ] ); ?> +
            +
            +
            + +
            +
            +
            ' ); + the_archive_description( '
            ', '
            ' ); + ?> + + + + +
            +
            +
            +
            + found_posts ): ?> + found_posts ); ?> + +
            +
            + +
            +
            + +
            + +
            +
            +
            + +
            + +
            + +
            + +
            + + + + + + + + + + + diff --git a/templates/archive-opalestate_agent.php b/templates/archive-opalestate_agent.php new file mode 100755 index 00000000..5ef6aca0 --- /dev/null +++ b/templates/archive-opalestate_agent.php @@ -0,0 +1,70 @@ + +
            +
            +
            +

            +

            +
            + +
            + true ] ); ?> +
            +
            +
            + +
            +
            +
            ' ); + the_archive_description( '
            ', '
            ' ); + ?> + + + + +
            +
            +
            +
            + found_posts ): ?> + found_posts ); ?> + +
            +
            + +
            +
            + +
            + +
            +
            +
            + +
            + +
            + +
            + +
            + + + + + + + + + + diff --git a/templates/archive-opalestate_property.php b/templates/archive-opalestate_property.php new file mode 100755 index 00000000..0bbf432b --- /dev/null +++ b/templates/archive-opalestate_property.php @@ -0,0 +1,65 @@ + + +
            +
            + +
            ' ); + the_archive_description( '
            ', '
            ' ); + ?> + + +
            + + + +
            +
            + + +
            + +
            + + + +
            + +
            + + +
            +
            +
            + + + + + + + + + + + + diff --git a/templates/content-agency-grid.php b/templates/content-agency-grid.php new file mode 100755 index 00000000..c6633116 --- /dev/null +++ b/templates/content-agency-grid.php @@ -0,0 +1,69 @@ + +
            > +
            +
            + + is_featured() ): ?> +
            + + + +
            + + + get_trusted() ): ?> + + + + + +
            + +
            +
            + +
            +
            + +
            +

            +

            + +

            +
            +
            + +
            + + + +
            + + + + +
            + + + +
            + + + + +
            + +
            +
            +
            +
            diff --git a/templates/content-agency-list.php b/templates/content-agency-list.php new file mode 100755 index 00000000..db47eeaf --- /dev/null +++ b/templates/content-agency-list.php @@ -0,0 +1,65 @@ + +
            > +
            +
            + + + is_featured() ): ?> +
            + + + +
            + +
            + +
            +
            +
            +

            + +

            + get_trusted() ): ?> + + + + +

            +

            +
            + +
            +
            + + +
            + + + + +
            + + + +
            + + + + +
            + +
            +
            +
            +
            diff --git a/templates/content-agent-grid-v2.php b/templates/content-agent-grid-v2.php new file mode 100755 index 00000000..cd7375b1 --- /dev/null +++ b/templates/content-agent-grid-v2.php @@ -0,0 +1,33 @@ + +
            > +
            +
            + + is_featured() ): ?> + + + + + + + + get_trusted() ): ?> + + + + +
            +
            + +
            +
            + +
            + +

            +
            +
            +
            +
            diff --git a/templates/content-agent-grid.php b/templates/content-agent-grid.php new file mode 100755 index 00000000..94f688eb --- /dev/null +++ b/templates/content-agent-grid.php @@ -0,0 +1,115 @@ + +
            > +
            +
            + + render_level(); ?> + is_featured() ): ?> + + + + + + + get_trusted() ): ?> + + + + +
            +
            + +
            +
            + +
            +

            + get_meta( 'job' ); ?> + +

            + +
            + +
            + get_meta( 'email' ); ?> + +
            + + + + +
            + + + get_meta( 'phone' ); ?> + +
            + + + + +
            + + + get_meta( 'mobile' ); ?> + +
            + + + + +
            + + + get_meta( 'fax' ); ?> + +
            + +
            + + + get_meta( 'web' ); ?> + +
            + + + + +
            + + + get_socials(); ?> + + +
            + + + + + + + + + + + + + + + + + + + + + + + +
            + +
            +
            +
            +
            diff --git a/templates/content-agent-list.php b/templates/content-agent-list.php new file mode 100755 index 00000000..d7b05b59 --- /dev/null +++ b/templates/content-agent-list.php @@ -0,0 +1,78 @@ + +
            > +
            +
            +
            +
            + + render_level(); ?> + is_featured() ): ?> + + + + + + +
            +
            +
            +
            +
            +

            + + get_trusted() ): ?> + + + + +

            + +

            + get_meta( 'job' ); ?> + +

            + +
            +
            + + get_socials(); ?> + + +
            + + + + + + + + + + + + + + + + + + + + + + + +
            + +
            +
            +

            + +

            +
            +
            +
            +
            diff --git a/templates/content-no-results.php b/templates/content-no-results.php new file mode 100755 index 00000000..b9d06029 --- /dev/null +++ b/templates/content-no-results.php @@ -0,0 +1,8 @@ +
            + +
            +

            +
            +
            diff --git a/templates/content-property-featured-v1.php b/templates/content-property-featured-v1.php new file mode 100755 index 00000000..88a3c40d --- /dev/null +++ b/templates/content-property-featured-v1.php @@ -0,0 +1,67 @@ + +
            > +
            ' ); ?> + +
            +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +

            + +

            +
            + + + +
            + +
            + + + + + + + diff --git a/templates/content-property-grid-v2.php b/templates/content-property-grid-v2.php new file mode 100755 index 00000000..de650d45 --- /dev/null +++ b/templates/content-property-grid-v2.php @@ -0,0 +1,52 @@ + +
            > +
            +
            + ', '' ); ?> + +
            +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            +
            +
            +
            + +
            + +
            + +
            + +
            + + + +
            +
            + +
            + render_author_link() ); ?> + +
            + + +
            + +
            diff --git a/templates/content-property-grid-v3.php b/templates/content-property-grid-v3.php new file mode 100755 index 00000000..483fe795 --- /dev/null +++ b/templates/content-property-grid-v3.php @@ -0,0 +1,52 @@ + +
            > +
            +
            +
            + +
            + +
            + +
            + + +
            + +
            +
            +
            + + ', '' ); ?> + +
            +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            + +
            + +
            + render_author_link() ); ?> + +
            + + +
            + +
            diff --git a/templates/content-property-grid.php b/templates/content-property-grid.php new file mode 100755 index 00000000..9c4d99e7 --- /dev/null +++ b/templates/content-property-grid.php @@ -0,0 +1,61 @@ + +
            > + +
            +
            + + ', '' ); ?> + +
            + +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            +
            + +
            +
            + +
            + +
            + +
            + + render_author_link() ); ?> + +
            + get_gallery_count() ) && $count > 1 ) : ?> + + +
            +
            + + + +
            +
            + +
            + + +
            +
            + + +
            diff --git a/templates/content-property-list-v2.php b/templates/content-property-list-v2.php new file mode 100755 index 00000000..69f15ced --- /dev/null +++ b/templates/content-property-list-v2.php @@ -0,0 +1,37 @@ + +
            > +
            +
            +
            + +
            + +
            + +
            + +
            + +
            +
            + + ', '' ); ?> + +
            + get_address() ); ?> +
            + + +
            + +
            +
            + + +
            diff --git a/templates/content-property-list.php b/templates/content-property-list.php new file mode 100755 index 00000000..ec1943dc --- /dev/null +++ b/templates/content-property-list.php @@ -0,0 +1,68 @@ + +
            > +
            +
            +
            + +
            + +
            + +
            + +
            + +
            render_author_link() ); ?>
            +
            + +
            +
            + + + +
            + +
            +
            + + ', '' ); ?> + +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            + + + +
            + + +
            + +
            +
            + +
            +
            + + + + + +
            diff --git a/templates/content-property-mark-hover.php b/templates/content-property-mark-hover.php new file mode 100755 index 00000000..8c0303fa --- /dev/null +++ b/templates/content-property-mark-hover.php @@ -0,0 +1,26 @@ + +
            > +
            +
            > +
            + ', '' ); ?> +
            +
            +
            get_metabox_value( 'areasize' ) ); ?>
            +
            + +
            +
            + + +
            + +
            \ No newline at end of file diff --git a/templates/content-property.php b/templates/content-property.php new file mode 100755 index 00000000..544f2dbc --- /dev/null +++ b/templates/content-property.php @@ -0,0 +1,18 @@ +
            > + + + +
            + ', '' ); ?> +
            + +
            + + +
            + + + + + +
            diff --git a/templates/content-single-agency.php b/templates/content-single-agency.php new file mode 100755 index 00000000..b8c3fab2 --- /dev/null +++ b/templates/content-single-agency.php @@ -0,0 +1,148 @@ +get_meta( 'map' ); +$address = $agency->get_meta( 'address' ); +$rowcls = apply_filters( 'opalestate_row_container_class', 'opal-row' ); +$id = time(); +?> + +
            > +
            +
            +
            + + +
            + + [ 'enable' => 1, 'name' => esc_html__( 'Description', 'opalestate-pro' ) ], + 'address' => [ 'enable' => 1, 'name' => esc_html__( 'Address', 'opalestate-pro' ) ], + + 'properties' => [ 'enable' => ! empty( $properties ), 'name' => esc_html__( 'Listing', 'opalestate-pro' ) ], + 'team' => [ 'enable' => ! empty( $team ), 'name' => esc_html__( 'Team', 'opalestate-pro' ) ], + ]; + ?> +
            +
            + +
            +
            +
            +

            +
            +
            + ', '', false ) + ) ); + + $end = 4; + ?> +
            + + + +
            +
            +
            +
            + +
            +

            +
            +
            + +

            + . + ' . esc_html__( 'Location:', 'opalestate-pro' ) . ''; + + $output = ''; + foreach ( $terms as $term ) { + $output .= $term->name; + } + $output .= ''; + echo wp_kses_post( $output ); + } + ?> +

            + +
            +
            +
            +
            + +
            + + +
            +
            +

            + +
            +
            + + + +
            +
            +

            +
            + +
            +
            +
            + +
            +
            +
            + + + +
            + +
            + + +
            + +
            +
            + get_meta( 'email' ); + $args = [ + 'post_id' => get_the_ID(), + 'id' => get_the_ID(), + 'email' => $email, + 'heading' => esc_html__( 'Contact Us', 'opalestate-pro' ), + 'message' => sprintf( esc_html__( 'Hi %s. I saw your profile and wanted to see if you could help me.', 'opalestate-pro' ), get_the_title() ), + 'type' => 'agency', + ]; + echo apply_filters( 'opalestate_render_contact_form', opalestate_load_template_path( 'messages/contact-form', $args ), $args ); + ?> +
            +
            +
            +
            + diff --git a/templates/content-single-agent.php b/templates/content-single-agent.php new file mode 100755 index 00000000..de91594d --- /dev/null +++ b/templates/content-single-agent.php @@ -0,0 +1,112 @@ +get_meta( 'map' ); +$address = $agent->get_meta( 'address' ); +$id = time(); +?> +
            +
            +
            +
            +
            +
            +
              +
            • +
            • +
            • +
            +
            +
            +
            +
            +
            +
            +
            > +
            +
            +
            + +
            + get_meta( 'email' ); + $args = [ + 'post_id' => get_the_ID(), + 'id' => get_the_ID(), + 'email' => $email, + 'message' => '', + 'type' => 'agent', + ]; + echo apply_filters( 'opalestate_render_contact_form', opalestate_load_template_path( 'messages/contact-form', $args ), $args ); + ?> +
            +
            + + +
            +
            +
            + ', '' ); ?> +
            +
            +
            +
            + ', '', false ) + ) ); + + wp_link_pages( [ + 'before' => '', + 'link_before' => '', + 'link_after' => '', + ] ); + ?> +
            +
            + +
            + +
            +
            +
            + +

            + . + ' . esc_html__( 'Location:', 'opalestate-pro' ) . ''; + + $output = ''; + foreach ( $terms as $term ) { + $output .= $term->name; + } + $output .= ''; + echo $output; + } + ?> +

            + +
            +
            +
            + +
            + + + + + + +
            +
            +
            +
            diff --git a/templates/content-single-property-print.php b/templates/content-single-property-print.php new file mode 100755 index 00000000..80b55af5 --- /dev/null +++ b/templates/content-single-property-print.php @@ -0,0 +1,83 @@ + + +
            +
            +
            +
            +
            +

            + + + +
            +
            + + +
            + +
            +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            +
            +
            + +
            +
            +
            + + + +
            +
            + +
            +
            > +
            +

            +
            +
            +
            + get_sku() ) : ?> + + get_sku() ); ?> + +
            +
            + + +
            + +
            +
            +
            +
            + diff --git a/templates/content-single-property-v2.php b/templates/content-single-property-v2.php new file mode 100755 index 00000000..7aeff6da --- /dev/null +++ b/templates/content-single-property-v2.php @@ -0,0 +1,166 @@ +get_floor_plans(); +$floors_enabled = $property->get_block_setting( 'floor_plans' ); +$attachments = $property->get_attachments(); +$attachments_enabled = $property->get_block_setting( 'attachments' ); +$header = apply_filters( 'opalestate_single_show_heading', true ); +?> + +
            +
            > + +
            +
            +
            + ', '' ); ?> + + + +
            +
            + + +
            + +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            + get_posted() ) + ); + ?> +
            +
            +
            +
            +
            +
            + +
            +
            + + + +
            + + [ 'enable' => 1, 'name' => esc_html__( 'Description', 'opalestate-pro' ) ], + 'information' => [ 'enable' => 1, 'name' => esc_html__( 'Information', 'opalestate-pro' ) ], + 'floors' => [ 'enable' => $floors_enabled && $floors, 'name' => esc_html__( 'Floor Plans', 'opalestate-pro' ) ], + 'attachment' => [ 'enable' => $attachments_enabled && $attachments, 'name' => esc_html__( 'Attachment', 'opalestate-pro' ) ], + ]; ?> + +
            + + +
            +
            +
            +

            +
            +
            +
              + get_sku() ) : ?> +
            • + + get_sku() ); ?> +
            • + +
            • + +
            • +
            • + get_id() ); ?> +
            • +
            • + +
            • +
            +
            + +
            + +
            + +
            +
            +
            +
            +
            + +
            +
            +

            +
            + + + +
            +
            +
            + +
            +
            +

            +
            + +
            +
            +
            + + +
            + +
            + +
            +
            +
            + + +
            +
            +
            + +
            +
            +
            +
            diff --git a/templates/content-single-property-v3.php b/templates/content-single-property-v3.php new file mode 100755 index 00000000..362c57fd --- /dev/null +++ b/templates/content-single-property-v3.php @@ -0,0 +1,113 @@ + +
            + + +
            +
            +
              +
            • + +
            • + +
            • + get_id() ); ?> +
            • + +
            • + +
            • +
            +
            +
            +
            + +
            +
            > +
            +
            + +
            +
            +
            +
            + ', '' ); ?> + + + +
            +
            + + +
            + +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            + get_posted() ) + ); + ?> +
            +
            +
            +
            +
            + +
            +

            +
            +
            +
            + get_sku() ) : ?> + + get_sku() ); ?> + +
            +
            + +
            + +
            +
            +
            + + + +
            +
            + +
            +
            +
            +
            +
            diff --git a/templates/content-single-property-v4.php b/templates/content-single-property-v4.php new file mode 100755 index 00000000..1e42955f --- /dev/null +++ b/templates/content-single-property-v4.php @@ -0,0 +1,108 @@ + +
            +
            > +
            +
            + +
            +
            +
            + ', '' ); ?> + + + +
            +
            + + +
            + +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            + get_posted() ) + ); + ?> +
            +
            +
            +
            +
            +
            + + +
            +

            +
            +
            +
              + get_sku() ) : ?> +
            • + + get_sku() ); ?> +
            • + +
            • + +
            • +
            • + get_id() ); ?> +
            • +
            • + +
            • +
            +
            + + +
            + +
            +
            +
            + + + +
            +
            + +
            +
            + +
            +
            +
            +
            +
            diff --git a/templates/content-single-property-v5.php b/templates/content-single-property-v5.php new file mode 100755 index 00000000..da758115 --- /dev/null +++ b/templates/content-single-property-v5.php @@ -0,0 +1,136 @@ + +
            + +
            +
            +
              +
            • + get_block_setting( 'video' ) ) : ?> +
            • + + get_block_setting( 'map' ) && apply_filters( 'opalestate_single_show_map', true ) ) : ?> +
            • + + get_block_setting( 'walkscores' ) ) : ?> +
            • + + get_block_setting( 'views_statistics' ) ) : ?> +
            • + + get_block_setting( 'apartments' ) && $property->get_apartments() ) : ?> +
            • + + get_block_setting( 'floor_plans' ) && $property->get_floor_plans() ) : ?> +
            • + +
            • +
            • + +
            • +
            +
            +
            +
            + +
            +
            > + +
            +
            + +
            +
            +
            +
            + ', '' ); ?> + + + +
            +
            + + +
            + +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            + get_posted() ) + ); + ?> +
            +
            +
            +
            +
            + +
            +

            +
            +
            +
              + get_sku() ) : ?> +
            • + + get_sku() ); ?> +
            • + +
            • + get_id() ); ?> +
            • +
            • + +
            • +
            +
            + + +
            + +
            +
            +
            + +
            +
            + +
            +
            + +
            +
            +
            +
            +
            diff --git a/templates/content-single-property.php b/templates/content-single-property.php new file mode 100755 index 00000000..3916c401 --- /dev/null +++ b/templates/content-single-property.php @@ -0,0 +1,112 @@ + + +
            +
            +
            +
            +
            + ', '' ); ?> + + + +
            +
            + + +
            + +
            + latitude && $property->longitude ) : ?> + + + + + + get_address() ) : ?> + get_address() ); ?> + +
            +
            + get_posted() ) + ); + ?> +
            +
            +
            + +
            +
            +
            + +
            +
            + +
            +
            > +
            +
            +
            +

            +
            +
            +
              + get_sku() ) : ?> +
            • + + get_sku() ); ?> +
            • + +
            • + +
            • +
            • + get_id() ); ?> +
            • +
            • + +
            • +
            +
            + + +
            + +
            +
            +
            + + + +
            +
            +
            +
            + +
            +
            +
            +
            +
            diff --git a/templates/content-user-grid.php b/templates/content-user-grid.php new file mode 100755 index 00000000..fa8bc26f --- /dev/null +++ b/templates/content-user-grid.php @@ -0,0 +1,148 @@ +data; +$picture = OpalEstate_User::get_author_picture( $user_id ); + +if ( $agent_id ) { + $agent = opalesetate_agent( $agent_id ); + $post = get_post( $agent_id ); + $facebook = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'facebook', true ); + $twitter = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'twitter', true ); + $pinterest = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'pinterest', true ); + $google = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'google', true ); + $instagram = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'instagram', true ); + $linkedIn = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'linkedIn', true ); + $job = get_post_meta( $agent_id, OPALESTATE_AGENT_PREFIX . 'job', true ); + $title = $post->post_title; + $author_link = get_permalink( $agent_id ); + wp_reset_query(); +} else { + $title = $user->display_name; + $facebook = get_post_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'facebook', true ); + $twitter = get_post_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'twitter', true ); + $pinterest = get_post_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'pinterest', true ); + $google = get_post_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'google', true ); + $instagram = get_post_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'instagram', true ); + $linkedIn = get_post_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'linkedIn', true ); + $job = get_post_meta( $user_id, OPALESTATE_USER_PROFILE_PREFIX . 'job', true ); + $author_link = get_author_posts_url( $user_id ); +} +?> +
            > +
            +
            +
            + user image +
            + + + render_level(); ?> + is_featured() ): ?> + + + + + + + get_trusted() ): ?> + + + + + +
            +
            +
            +
            + +
            + + +

            + + + +

            + +
            +
            + + + get_meta( 'email' ); ?> + +
            + + + + +
            + + + get_meta( 'phone' ); ?> + +
            + + + + +
            + + + get_meta( 'mobile' ); ?> + +
            + + + + +
            + + + get_meta( 'fax' ); ?> + +
            + +
            + + + get_meta( 'web' ); ?> + +
            + + + + +
            + + + +
            + + + + + + + + + + + + + + + + + + + + + + + +
            +
            +
            +
            +
            diff --git a/templates/elementor-templates/opalestate-agency-collection.php b/templates/elementor-templates/opalestate-agency-collection.php new file mode 100755 index 00000000..fb8fd4a9 --- /dev/null +++ b/templates/elementor-templates/opalestate-agency-collection.php @@ -0,0 +1,59 @@ + get_settings_for_display(); + $layout = $settings['item_layout']; + $attrs = $this->get_render_attribute_string( 'wrapper-style' ); + if( isset($_GET['display']) && $_GET['display'] == 'grid' ){ + $layout = 'grid'; + + }else if( isset($_GET['display']) && $_GET['display'] == 'list' ){ + $layout = 'list'; + $attrs = 'class="column-list"'; + } + $onlyfeatured = 0; + if( isset($_GET['s_agents']) ) { + $query = Opalestate_Query::get_agencies( array("posts_per_page"=>$limit, 'paged' => $paged), $onlyfeatured ); + } else { + $query = OpalEstate_Search::get_search_agencies_query(); + } + + $rowcls = apply_filters('opalestate_row_container_class', 'opal-row'); +?> + + +
            +
            +
            + '.$query->found_posts.'' ) ?> +
            +
            +
            +
            + +
            + +
            +
            + +
            + have_posts() ): ?> +
            +
            > + have_posts() ): $query->the_post(); ?> +
            + +
            + +
            +
            + max_num_pages ): ?> +
            + max_num_pages ); ?> +
            + + +
            + +
            + +
            + diff --git a/templates/elementor-templates/opalestate-agent-collection.php b/templates/elementor-templates/opalestate-agent-collection.php new file mode 100755 index 00000000..4453299e --- /dev/null +++ b/templates/elementor-templates/opalestate-agent-collection.php @@ -0,0 +1,62 @@ + get_settings_for_display(); + $layout = $settings['item_layout']; + $attrs = $this->get_render_attribute_string( 'wrapper-style' ); + if( isset($_GET['display']) && $_GET['display'] == 'grid' ){ + $layout = 'grid'; + + }else if( isset($_GET['display']) && $_GET['display'] == 'list' ){ + $layout = 'list'; + $attrs = 'class="column-list"'; + } + + $onlyfeatured = 0 ; + + if( isset($_GET['s_agents']) ) { + $query = Opalestate_Query::get_agents( array("posts_per_page"=>$limit, 'paged' => $paged), $onlyfeatured ); + } else { + $query = OpalEstate_Search::get_search_agents_query(); + } + + $form = $settings['search_form'] ? "search-agents-form-".$settings['search_form']: "search-agents-form"; + $rowcls = apply_filters('opalestate_row_container_class', 'opal-row'); +?> + + +
            +
            +
            + '.$query->found_posts.'' ) ?> +
            +
            +
            +
            + +
            + +
            +
            + +
            + have_posts() ): ?> +
            +
            > + have_posts() ): $query->the_post(); ?> +
            + +
            + +
            +
            + max_num_pages ): ?> +
            + max_num_pages ); ?> +
            + + +
            + +
            + +
            + diff --git a/templates/elementor-templates/opalestate-category-list.php b/templates/elementor-templates/opalestate-category-list.php new file mode 100755 index 00000000..d1830f92 --- /dev/null +++ b/templates/elementor-templates/opalestate-category-list.php @@ -0,0 +1,66 @@ + $settings['limit'], + 'orderby' => $settings['orderby'], + 'order' => $settings['order'], +]; + +if ( $settings['categories'] ) { + $args['slug'] = $settings['categories']; +} + +$terms = Opalestate_Taxonomy_Categories::get_list( $args ); + +$attrs = $this->get_render_attribute_string( 'wrapper-style' ); + +?> +
            +
            > + + term_id ); + $image = wp_get_attachment_image_url( get_term_meta( $category->term_id, 'opalestate_category_image_id', true ), 'full' ); + ?> +
            + + + +
            > +
            +
            +
            + name ) : ?> +

            + name ); ?> +

            + + + count ) : ?> +
            + count, + 'opalestate-pro' + ), + number_format_i18n( $category->count ) + ); + ?> +
            + +
            +
            +
            + +
            +
            diff --git a/templates/elementor-templates/opalestate-city-list.php b/templates/elementor-templates/opalestate-city-list.php new file mode 100755 index 00000000..07d38e6f --- /dev/null +++ b/templates/elementor-templates/opalestate-city-list.php @@ -0,0 +1,66 @@ + $settings['limit'], + 'orderby' => $settings['orderby'], + 'order' => $settings['order'], +]; + +if ( $settings['categories'] ) { + $args['slug'] = $settings['categories']; +} + +$terms = Opalestate_Taxonomy_City::get_list( $args ); + +$attrs = $this->get_render_attribute_string( 'wrapper-style' ); + +?> +
            +
            > + + term_id ); + $image = wp_get_attachment_image_url( get_term_meta( $city->term_id, 'opalestate_city_image_id', true ), 'full' ); + ?> +
            + + + +
            > +
            +
            +
            + name ) : ?> +

            + name ); ?> +

            + + + count ) : ?> +
            + count, + 'opalestate-pro' + ), + number_format_i18n( $city->count ) + ); + ?> +
            + +
            +
            +
            + +
            +
            diff --git a/templates/elementor-templates/opalestate-form-builder.php b/templates/elementor-templates/opalestate-form-builder.php new file mode 100755 index 00000000..fd5615d6 --- /dev/null +++ b/templates/elementor-templates/opalestate-form-builder.php @@ -0,0 +1,30 @@ + +
            + +
            + + +
            + +
            + + +
            + + + +
            + +
            + +
            + diff --git a/templates/elementor-templates/opalestate-map-top-search.php b/templates/elementor-templates/opalestate-map-top-search.php new file mode 100755 index 00000000..3e44e42c --- /dev/null +++ b/templates/elementor-templates/opalestate-map-top-search.php @@ -0,0 +1,18 @@ + +
            + +
            + +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            \ No newline at end of file diff --git a/templates/elementor-templates/opalestate-office-agent-search.php b/templates/elementor-templates/opalestate-office-agent-search.php new file mode 100755 index 00000000..9c548e34 --- /dev/null +++ b/templates/elementor-templates/opalestate-office-agent-search.php @@ -0,0 +1,34 @@ + + +
            + + + +
            + +
            +
            + +
            +
            + +
            +
            +
            + + + diff --git a/templates/elementor-templates/opalestate-property-collection.php b/templates/elementor-templates/opalestate-property-collection.php new file mode 100755 index 00000000..1f3a63c0 --- /dev/null +++ b/templates/elementor-templates/opalestate-property-collection.php @@ -0,0 +1,54 @@ + 5, + 'column' => 3, + 'paged' => 1, + 'showsortby' => false, + 'style' => 'grid', +], $settings ); +extract( $settings ); + +if ( is_front_page() ) { + $paged = ( get_query_var( 'page' ) ) ? get_query_var( 'page' ) : 1; +} else { + $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1; +} + +$args = [ + 'posts_per_page' => $posts_per_page, + 'paged' => $paged, + 'cities' => $cities, + 'categories' => $categories, + 'operator' => $cat_operator, + 'types' => $types, + 'statuses' => $statuses, + 'showmode' => $showmode, + 'labels' => $labels, +]; + +$query = Opalestate_Query::get_property_query( $args ); + +$class = 'column-item'; +?> + + 'list' ] ); ?> + +
            + + have_posts() ): ?> +
            get_render_attribute_string( 'wrapper-style' ); ?>> + have_posts() ) : $query->the_post(); ?> +
            + +
            + +
            + + +
            + + + + +
            + diff --git a/templates/elementor-templates/opalestate-search-agency.php b/templates/elementor-templates/opalestate-search-agency.php new file mode 100755 index 00000000..6617f7fd --- /dev/null +++ b/templates/elementor-templates/opalestate-search-agency.php @@ -0,0 +1,11 @@ + get_settings_for_display(); + $layout = $settings['item_layout']; + $form = $settings['search_form'] ? "search-agency-form-".$settings['search_form']: "search-agency-form"; + + +?> +
            + $settings['current_uri'] ) ); ?> +
            + \ No newline at end of file diff --git a/templates/elementor-templates/opalestate-search-agents.php b/templates/elementor-templates/opalestate-search-agents.php new file mode 100755 index 00000000..dee32701 --- /dev/null +++ b/templates/elementor-templates/opalestate-search-agents.php @@ -0,0 +1,10 @@ + get_settings_for_display(); + $layout = $settings['item_layout']; + $form = $settings['search_form'] ? "search-agents-form-".$settings['search_form']: "search-agents-form"; + +?> +
            + $settings['current_uri'] ) ); ?> +
            + \ No newline at end of file diff --git a/templates/elementor-templates/opalestate-search-property-results.php b/templates/elementor-templates/opalestate-search-property-results.php new file mode 100755 index 00000000..a274e664 --- /dev/null +++ b/templates/elementor-templates/opalestate-search-property-results.php @@ -0,0 +1,14 @@ + $settings['style'], + 'column' => $settings['column'] + ); +// echo time().'
             ha congtein' . print_r( $display ,1 ).'
            '; + + +?> +
            + + + +
            \ No newline at end of file diff --git a/templates/elementor-templates/opalestate-searchbox.php b/templates/elementor-templates/opalestate-searchbox.php new file mode 100755 index 00000000..304aa38f --- /dev/null +++ b/templates/elementor-templates/opalestate-searchbox.php @@ -0,0 +1,9 @@ + +
            + +
            diff --git a/templates/elementor-templates/opalestate-split-maps-search.php b/templates/elementor-templates/opalestate-split-maps-search.php new file mode 100755 index 00000000..3e34fee7 --- /dev/null +++ b/templates/elementor-templates/opalestate-split-maps-search.php @@ -0,0 +1,37 @@ + +
            +
            + +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            + +
            +
            +
            + true ] ); ?> +
            + +
            + 2 ] ); ?> +
            +
            +
            +
            +
            +
            diff --git a/templates/emails/contact.php b/templates/emails/contact.php new file mode 100755 index 00000000..4667d52a --- /dev/null +++ b/templates/emails/contact.php @@ -0,0 +1,11 @@ +Hi {receiver_name},
            +You have got message from {name} with email {email} and phone number {phone} +
            +
            Here is detail: +
            +
            +{message} +

            +
            +This message was sent by {site_link} on {current_time}. \ No newline at end of file diff --git a/templates/emails/enquiry.php b/templates/emails/enquiry.php new file mode 100755 index 00000000..2e5db06f --- /dev/null +++ b/templates/emails/enquiry.php @@ -0,0 +1,12 @@ +Hi {receiver_name},
            +You have got message from {name} with email {email} and phone number {phone} +
            +At Property {property_link} +
            Here is detail: +
            +
            +{message} +

            +
            +This message was sent by {site_link} on {current_time}. \ No newline at end of file diff --git a/templates/emails/publish_property.php b/templates/emails/publish_property.php new file mode 100755 index 00000000..12808acd --- /dev/null +++ b/templates/emails/publish_property.php @@ -0,0 +1,15 @@ + +Hi first_name . ' ' . $user->last_name; ?>, + +Your property have published. + +
            + +ID ); ?> + + :
            + \ No newline at end of file diff --git a/templates/emails/request-reviewing.php b/templates/emails/request-reviewing.php new file mode 100755 index 00000000..6ca3afae --- /dev/null +++ b/templates/emails/request-reviewing.php @@ -0,0 +1,15 @@ +Hi {receiver_name},
            +You have got message request reviewing from {name} with email {email} and phone number {phone} +
            +At Property {property_name} ( {property_link} ) +
            Here is detail: +
            +
            +Schedule Date At: {schedule_time} - {schedule_date} +
            + +{message} +

            +
            +This message was sent by {site_link} on {current_time}. \ No newline at end of file diff --git a/templates/fullwidth-page.php b/templates/fullwidth-page.php new file mode 100755 index 00000000..16d8d4fb --- /dev/null +++ b/templates/fullwidth-page.php @@ -0,0 +1,47 @@ + +
            + +
            +
            +
            +
            + +
            > +
            + '', + 'link_before' => '', + 'link_after' => '', + 'pagelink' => '' . esc_html__( 'Page', 'opalestate-pro' ) . ' %', + 'separator' => ', ', + ) + ); + ?> +
            +
            + +
            +
            +
            +
            +
            + + diff --git a/templates/messages/contact-form.php b/templates/messages/contact-form.php new file mode 100755 index 00000000..6a633850 --- /dev/null +++ b/templates/messages/contact-form.php @@ -0,0 +1,44 @@ +get_contact_form_fields(); +$form = OpalEstate()->html->render_form( $fields ); + +$id = 'send-contact-form' +?> + +
            + +
            + +
            +
            +
            + + + + + + + +
            +
            +
            + + +
            + diff --git a/templates/messages/enquiry-form.php b/templates/messages/enquiry-form.php new file mode 100755 index 00000000..76164fd4 --- /dev/null +++ b/templates/messages/enquiry-form.php @@ -0,0 +1,45 @@ +get_equiry_form_fields( $message ); +$form = OpalEstate()->html->render_form( $fields ); + +$id = 'send-enquiry-form'; +?> + + +
            + + + + + + + +
            + +
            +
            +
            +
            +
            +
            + + + + + + + +
            +
            +
            + +
            +
            + diff --git a/templates/messages/request-reviewing-form.php b/templates/messages/request-reviewing-form.php new file mode 100755 index 00000000..6f966ab6 --- /dev/null +++ b/templates/messages/request-reviewing-form.php @@ -0,0 +1,14 @@ +
            +

            +

            + '; ?> + + + + + + + '; ?> +
            diff --git a/templates/notices/error.php b/templates/notices/error.php new file mode 100755 index 00000000..b3f07e6a --- /dev/null +++ b/templates/notices/error.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (C) 2016 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +if ( ! $messages ) return; + +?> +
              + +
            • + +
            • + +
            \ No newline at end of file diff --git a/templates/notices/success.php b/templates/notices/success.php new file mode 100755 index 00000000..4ae1459f --- /dev/null +++ b/templates/notices/success.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (C) 2016 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +if ( ! $messages ) return; + +foreach ( $messages as $message ) : ?> +
            + +
            + \ No newline at end of file diff --git a/templates/notices/warning.php b/templates/notices/warning.php new file mode 100755 index 00000000..64014ba7 --- /dev/null +++ b/templates/notices/warning.php @@ -0,0 +1,24 @@ + + * @copyright Copyright (C) 2016 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} +if ( ! $messages ) return; +?> + +
            + +
            + diff --git a/templates/parts/archive-search-block.php b/templates/parts/archive-search-block.php new file mode 100755 index 00000000..d1867d43 --- /dev/null +++ b/templates/parts/archive-search-block.php @@ -0,0 +1,12 @@ + +
            +
            +
            + +
            + +
            +
            \ No newline at end of file diff --git a/templates/parts/archive-simple-bars.php b/templates/parts/archive-simple-bars.php new file mode 100755 index 00000000..b55a1204 --- /dev/null +++ b/templates/parts/archive-simple-bars.php @@ -0,0 +1,17 @@ + +
            +
            +
            + found_posts ): ?> + found_posts ); ?> + +
            +
            + +
            +
            + +
            + +
            +
            \ No newline at end of file diff --git a/templates/parts/collection-navigator.php b/templates/parts/collection-navigator.php new file mode 100755 index 00000000..cd97465d --- /dev/null +++ b/templates/parts/collection-navigator.php @@ -0,0 +1,29 @@ + +
            +
            +
            + + + +
            + +
            +
            + +
            +
            + +
            +
            +
            +
            diff --git a/templates/parts/featured-label.php b/templates/parts/featured-label.php new file mode 100755 index 00000000..811b64ff --- /dev/null +++ b/templates/parts/featured-label.php @@ -0,0 +1,9 @@ +is_featured() ) { + return; +} +?> + + diff --git a/templates/parts/has-warning.php b/templates/parts/has-warning.php new file mode 100755 index 00000000..889a034e --- /dev/null +++ b/templates/parts/has-warning.php @@ -0,0 +1,5 @@ +
            +

            + +

            +

            diff --git a/templates/parts/membership-pricing-info.php b/templates/parts/membership-pricing-info.php new file mode 100755 index 00000000..be8261f6 --- /dev/null +++ b/templates/parts/membership-pricing-info.php @@ -0,0 +1,27 @@ + +
            +
            + + + + + + + +
            +
            + + + + + + + +
            +
            \ No newline at end of file diff --git a/templates/parts/membership-warning.php b/templates/parts/membership-warning.php new file mode 100755 index 00000000..1f38b640 --- /dev/null +++ b/templates/parts/membership-warning.php @@ -0,0 +1,6 @@ + +
            +

            +

            +
            + diff --git a/templates/parts/modules/carousel.php b/templates/parts/modules/carousel.php new file mode 100755 index 00000000..ca0b991c --- /dev/null +++ b/templates/parts/modules/carousel.php @@ -0,0 +1,39 @@ + $item, + 'spaceBetween' => 30, + 'slidesPerGroup' => $item, + 'loop' => false, +]; + +$template_style = isset( $args['style'] ) && $args['style'] ? sanitize_text_field( $args['style'] ) : 'content-property-grid'; +?> + diff --git a/templates/parts/mortgage-calculator.php b/templates/parts/mortgage-calculator.php new file mode 100755 index 00000000..26fc2e46 --- /dev/null +++ b/templates/parts/mortgage-calculator.php @@ -0,0 +1,180 @@ + admin_url( 'admin-ajax.php' ), + 'currency' => esc_attr__( $currency ), + 'loan_amount_text' => esc_html__( 'Loan Amount', 'opalestate-pro' ), + 'your_payment_text' => esc_html__( 'Your payment', 'opalestate-pro' ), + ] +); + +$max_price = intval( $property && $property->get_price() ) ? $property->get_price() : opalestate_options( 'search_max_price', 10000000 ); +$max_price = str_replace( ",", "", $max_price ); +$max_price = str_replace( ".", "", $max_price ); + +$start_price = $max_price; + +$max_price = $max_price + ( $max_price * 20 / 100 ); + + +$rate_start = 10; +$interest_rate_start = $rate_start / 100; +$years_start = 2; +$deposit_start = $max_price / 2; +$loan_amount = $max_price - $deposit_start; +$interest_rate_month = $interest_rate_start / 12; +$number_of_payments_month = $years_start * 12; +$monthly = round( ( $loan_amount * $interest_rate_month ) / ( 1 - pow( 1 + $interest_rate_month, -$number_of_payments_month ) ), 2 ); + +$total = $deposit_start + ( $monthly * $number_of_payments_month ); +$price_percent = $loan_amount / $total * 100; +$deposit_percent = $deposit_start / $total * 100; + +$deposit_color = apply_filters( 'opalestate_deposit_color', '#2f73e9' ); + +$data_sale_price = [ + 'id' => 'sale_price', + 'decimals' => opalestate_get_price_decimals(), + 'unit' => $currency, + 'ranger_min' => 0, + 'ranger_max' => $max_price, + 'input_min' => 0, + 'input_max' => $max_price, + 'mode' => 1, + 'start' => $start_price, +]; + +$data_deposit = [ + 'id' => 'deposit', + 'decimals' => opalestate_get_price_decimals(), + 'unit' => $currency, + 'ranger_min' => 0, + 'ranger_max' => $max_price, + 'input_min' => 0, + 'input_max' => $max_price, + 'mode' => 1, + 'start' => $deposit_start, +]; + +$data_interest_rate = [ + 'id' => 'interest_rate', + 'unit' => '%', + 'ranger_min' => 0, + 'ranger_max' => 100, + 'input_min' => 0, + 'input_max' => 100, + 'mode' => 1, + 'start' => $rate_start, +]; + +$data_years = [ + 'id' => 'years', + 'ranger_min' => 0, + 'ranger_max' => 30, + 'input_min' => 0, + 'input_max' => 30, + 'mode' => 1, + 'start' => $years_start, +]; + +if ( opalestate_options( 'currency_position', 'before' ) == 'before' ) { + $data_sale_price['unit_position'] = 'prefix'; + $data_deposit['unit_position'] = 'prefix'; +} + +?> +
            +

            +
            + +
            +
            +
            +
            +
            + + + + + + +
            +
            +
            +
            +
            +
            + + + + / + +
            +
            + + + + +
            +
            +
              +
            • +
            • +
            • +
            +
            +
            +
            +
            +
            + +
            +
            +
            + +
            +
            +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            + +
            +
            +
            +
            +
            +
            diff --git a/templates/parts/not-allowed.php b/templates/parts/not-allowed.php new file mode 100755 index 00000000..193e8329 --- /dev/null +++ b/templates/parts/not-allowed.php @@ -0,0 +1,9 @@ + + +
            + +
            diff --git a/templates/parts/pagination.php b/templates/parts/pagination.php new file mode 100755 index 00000000..bed4d891 --- /dev/null +++ b/templates/parts/pagination.php @@ -0,0 +1,23 @@ +max_num_pages <= 1 ) { + return; +} + +$args = apply_filters( 'opalestate_pagination_args', [ + 'prev_text' => __( '«' ), + 'next_text' => __( '»' ), + 'type' => 'list', +] ); + +?> + + + + diff --git a/templates/parts/property-categories.php b/templates/parts/property-categories.php new file mode 100755 index 00000000..81485e83 --- /dev/null +++ b/templates/parts/property-categories.php @@ -0,0 +1,6 @@ +get_id(), 'property_category', '
            ' . esc_html__( 'Categories:', 'opalestate-pro' + ) . + '', ', ', '
            ' ); diff --git a/templates/parts/property-label.php b/templates/parts/property-label.php new file mode 100755 index 00000000..adb20380 --- /dev/null +++ b/templates/parts/property-label.php @@ -0,0 +1,19 @@ +get_labels(); + +if ( is_wp_error( $labels ) || ! $labels ) { + return; +} +?> + +
              + $value ) : ?> +
            • + name ); ?> +
            • + +
            diff --git a/templates/parts/property-loop-price.php b/templates/parts/property-loop-price.php new file mode 100755 index 00000000..a2b455fa --- /dev/null +++ b/templates/parts/property-loop-price.php @@ -0,0 +1,36 @@ + + +
            + get_price_oncall() ): ?> +
            + get_price() ): ?> + get_before_price_label() ): ?> + get_before_price_label() ); ?> + + + get_sale_price() ): ?> + + get_price() ); ?> + + get_sale_price() ); ?> + + get_price() ); ?> + + + get_price_label() ): ?> + get_price_label() ); ?> + + +
            + +
            diff --git a/templates/parts/property-loop-short-meta.php b/templates/parts/property-loop-short-meta.php new file mode 100755 index 00000000..7180e27f --- /dev/null +++ b/templates/parts/property-loop-short-meta.php @@ -0,0 +1,33 @@ +get_meta_shortinfo(); + ?> +
            +
              + + $info ) : ?> + +
            • + + + +
            • + + + +
            +
            + get_status(); + +if ( is_wp_error( $statuses ) || ! $statuses ) { + return; +} + +?> +
              + $value ) : ?> +
            • + name ); ?> +
            • + +
            diff --git a/templates/parts/property-types.php b/templates/parts/property-types.php new file mode 100755 index 00000000..43dd5b00 --- /dev/null +++ b/templates/parts/property-types.php @@ -0,0 +1,5 @@ +get_id(), 'opalestate_types', '
            ' . esc_html__( 'Types:', 'opalestate-pro' ) . '', + ', ', '
            ' ); diff --git a/templates/parts/search-agency-form-address.php b/templates/parts/search-agency-form-address.php new file mode 100755 index 00000000..1685466d --- /dev/null +++ b/templates/parts/search-agency-form-address.php @@ -0,0 +1,44 @@ + +
            + +
            +
            +

            +
            + +
            + +
            +
            + +
            +
            + + +
            + + +
            + + +
            + + + +
            +
            \ No newline at end of file diff --git a/templates/parts/search-agency-form.php b/templates/parts/search-agency-form.php new file mode 100755 index 00000000..a767ef1e --- /dev/null +++ b/templates/parts/search-agency-form.php @@ -0,0 +1,32 @@ + +
            + +
            +
            + +
            +
            + + +
            + +
            + + +
            +
            +
            diff --git a/templates/parts/search-agents-form-address.php b/templates/parts/search-agents-form-address.php new file mode 100755 index 00000000..25bd7e86 --- /dev/null +++ b/templates/parts/search-agents-form-address.php @@ -0,0 +1,40 @@ + +
            + +
            +
            +

            +
            + +
            + +
            +
            + +
            +
            + +
            + + +
            + + +
            +
            +
            diff --git a/templates/parts/search-agents-form.php b/templates/parts/search-agents-form.php new file mode 100755 index 00000000..fa32d2be --- /dev/null +++ b/templates/parts/search-agents-form.php @@ -0,0 +1,59 @@ + +
            + +
            +
            +

            +
            + +
            + +
            +
            + +
            +
            + +
            + +
            + 'price', + 'unit' => '$ ', + 'ranger_min' => opalestate_options( 'search_agent_min_price',0 ), + 'ranger_max' => opalestate_options( 'search_agent_max_price',10000000 ), + 'input_min' => $search_min_price, + 'input_max' => $search_max_price + ); + opalesate_property_slide_ranger_template( esc_html__("Price:",'opalestate-pro'), $data ); + + ?> +
            + +
            + + +
            +
            +
            diff --git a/templates/rating/opalestate-ratings.php b/templates/rating/opalestate-ratings.php new file mode 100755 index 00000000..a0468f6c --- /dev/null +++ b/templates/rating/opalestate-ratings.php @@ -0,0 +1,294 @@ + 0, + 4 => 0, + 3 => 0, + 2 => 0, + 1 => 0, +]; + +$average_stats = []; +if ( $features ) { + foreach ( $features as $feature_slug => $feature_title ) { + $average_stats[ $feature_slug ] = '0.00'; + } +} + +$count = $object->get_rating_counts(); +$counts = $object->get_rating_count_stats() ? $object->get_rating_count_stats() : $counts; +$average = $object->get_average_rating(); +$average_stats = $object->get_rating_average_stats() ? $object->get_rating_average_stats() : $average_stats; +?> +
            +

            + +

            +
            +
            +
            +
            + + $value ) : ?> + get_rating_counts() ) * 100 ); ?> +
            + + +
            +
            + % +
            +
            + + % + +
            + + +
            + +
            +
            +
            +

            + get_average_rating() ? $object->get_average_rating() : '0.00' ); ?> +

            +
            + +
            +
            + +
            + + + + + + + + + + + +
            +
            + + +
            + $average_stars ) : ?> + $feature_slug, + 'post_type' => $cpt_feature, + 'post_status' => 'publish', + 'numberposts' => 1, + ]; + + $feature = get_posts( $args ); + if ( ! $feature || ! isset( $feature[0] ) ) { + continue; + } + ?> +
            + + +
            + % +
            +
            + +
            + +
            +
            + +
            + get_review_count() ), + 'review numbers', + 'opalestate-pro' + ), + number_format_i18n( absint( $object->get_review_count() ) ) + ); + ?> +
            + + +
              + 'opalestate_comments' ] ) ); ?> +
            + + 1 && get_option( 'page_comments' ) ) : + echo ''; + endif; + ?> + +

            + +
            + + + + post_author ) ) : ?> + $current_user_id, + 'post_id' => $object->get_id(), + 'status' => 'approve', + 'count' => true, + ] ); + ?> + +
            +
            + have_comments() ? esc_html__( 'Add a review', 'opalestate-pro' ) : sprintf( esc_html__( 'Be the first to review “%s”', 'opalestate-pro' ), get_the_title() ), + /* translators: %s is property title */ + 'title_reply_to' => esc_html__( 'Leave a Reply to %s', 'opalestate-pro' ), + 'title_reply_before' => '
            ', + 'title_reply_after' => '
            ', + 'comment_notes_after' => '', + 'fields' => [ + 'author' => '

            ' . + '

            ', + 'email' => '', + ], + 'label_submit' => esc_html__( 'Submit', 'opalestate-pro' ), + 'logged_in_as' => '', + 'comment_field' => '', + ]; + + if ( $features ) { + $feature_inputs = ''; + foreach ( $features as $feature_slug => $feature_title ) { + $feature_inputs .= '
            '; + } + + $comment_form['comment_field'] = $feature_inputs; + } else { + $comment_form['comment_field'] = '
            '; + } + + $comment_form['comment_field'] .= '

            '; + + comment_form( apply_filters( 'opalestate_property_review_comment_form_args', $comment_form ) ); + ?> +
            +
            + +

            + + +

            + + + + + +
            +
            +
            diff --git a/templates/rating/review-meta.php b/templates/rating/review-meta.php new file mode 100755 index 00000000..7d6a5f91 --- /dev/null +++ b/templates/rating/review-meta.php @@ -0,0 +1,27 @@ +comment_approved ) { ?> + +

            + + + +

            + + + +

            + + +

            + + + +
            +
            + +
            + +
            +
              + $feature_title ) : $feature_key = $cpt_feature . '_' . $feature_slug; ?> +
            • + + +
            • + +
            +
            +
            + + + diff --git a/templates/rating/review.php b/templates/rating/review.php new file mode 100755 index 00000000..7c642546 --- /dev/null +++ b/templates/rating/review.php @@ -0,0 +1,53 @@ + +
          • id="li-comment-"> + +
            + + + +
            + + + +
            +
            diff --git a/templates/search-box/advanced-v2.php b/templates/search-box/advanced-v2.php new file mode 100755 index 00000000..641a776c --- /dev/null +++ b/templates/search-box/advanced-v2.php @@ -0,0 +1,89 @@ + 12, + 1 => 0, + ]; +} else { + $grid = [ + 0 => 10, + 1 => 2, + ]; +} + +$display_country = isset( $display_country ) ? $display_country : true; +$display_state = isset( $display_state ) ? $display_state : false; +$display_city = isset( $display_city ) ? $display_city : false; +$display_more_options = isset( $display_more_options ) ? $display_more_options : true; + +$form_classes = [ + 'opalestate-search-form', + 'opalestate-search-form--advanced-2', + isset( $hidden_labels ) && $hidden_labels ? 'hidden-labels' : '', +]; + +?> +
            +
            +
            +
            +
            + +
            + + +
            + +
            + + + +
            + +
            + + + +
            + +
            + + + + +
            + +
            + +
            + +
            +
            + + +
            + + +
            + +
            + +
            + + +
            diff --git a/templates/search-box/advanced-v3.php b/templates/search-box/advanced-v3.php new file mode 100755 index 00000000..55704d41 --- /dev/null +++ b/templates/search-box/advanced-v3.php @@ -0,0 +1,73 @@ + +
            +
            +
            + +
            + + +
            + +
            + + + +
            + +
            + + + +
            + +
            + + + + +
            + +
            + +
            + +
            + + +
            + +
            + +
            + + + + +
            diff --git a/templates/search-box/advanced-v4.php b/templates/search-box/advanced-v4.php new file mode 100755 index 00000000..73ab689b --- /dev/null +++ b/templates/search-box/advanced-v4.php @@ -0,0 +1,83 @@ + +
            +
            +
            + +
            + +
            + +
            + +
            + +
            + +
            + +
            + + +
            + +
            + + + +
            + +
            + + + +
            + +
            + + + + +
            + + + +
            + + +
            + +
            + +
            + + + + +
            diff --git a/templates/search-box/advanced-v5.php b/templates/search-box/advanced-v5.php new file mode 100755 index 00000000..e7d76535 --- /dev/null +++ b/templates/search-box/advanced-v5.php @@ -0,0 +1,70 @@ + 3, + 1 => 3, + 2 => 3, + 3 => 3, + 4 => 0, + ]; +} else { + $grid = [ + 0 => 3, + 1 => 3, + 2 => 3, + 3 => 2, + 4 => 1, + ]; +} + +$display_more_options = isset( $display_more_options ) ? $display_more_options : false; + +$form_classes = [ + 'opalestate-search-form', + 'opalestate-search-form--advanced-5', + isset( $hidden_labels ) && $hidden_labels ? 'hidden-labels' : '', +]; + +?> +
            +
            +
            + +
            + +
            + +
            + +
            + 1 ] ); ?> +
            + +
            + +
            + + +
            + +
            + + + +
            + +
            + +
            + + +
            diff --git a/templates/search-box/advanced-v6.php b/templates/search-box/advanced-v6.php new file mode 100755 index 00000000..18896d40 --- /dev/null +++ b/templates/search-box/advanced-v6.php @@ -0,0 +1,42 @@ + + +
            +
            + +
            + +
            + +
            + + + + + + + + +
            diff --git a/templates/search-box/collapse-city.php b/templates/search-box/collapse-city.php new file mode 100755 index 00000000..8c834cf2 --- /dev/null +++ b/templates/search-box/collapse-city.php @@ -0,0 +1,87 @@ + 7, + 1 => 4, + 2 => 1, + 3 => 0, + ]; +} else { + $grid = [ + 0 => 6, + 1 => 3, + 2 => 1, + 3 => 2, + ]; +} + +$display_more_options = isset( $display_more_options ) ? $display_more_options : true; + +$form_classes = [ + 'opalestate-search-form', + 'opalestate-search-form--collapse-city', + isset( $hidden_labels ) && $hidden_labels ? 'hidden-labels' : '', +]; + +?> + +
            +
            +
            + +
            + +
            + +
            + +
            + +
            + + +
            + +
            + +
            + +
            +
            +
            + +
            + + + +
            + +
            + +
            + +
            +
            + + +
            + + +
            diff --git a/templates/search-box/collapse-keyword.php b/templates/search-box/collapse-keyword.php new file mode 100755 index 00000000..7214393f --- /dev/null +++ b/templates/search-box/collapse-keyword.php @@ -0,0 +1,109 @@ + 5, + 1 => 3, + 2 => 3, + 3 => 1, + 4 => 0, + ]; +} else { + $grid = [ + 0 => 5, + 1 => 2, + 2 => 2, + 3 => 1, + 4 => 2, + ]; +} + +$display_country = isset( $display_country ) ? $display_country : true; +$display_state = isset( $display_state ) ? $display_state : false; +$display_city = isset( $display_city ) ? $display_city : false; +$display_more_options = isset( $display_more_options ) ? $display_more_options : true; + +$form_classes = [ + 'opalestate-search-form', + 'opalestate-search-form--collapse-keyword', + isset( $hidden_labels ) && $hidden_labels ? 'hidden-labels' : '', +]; + +?> + +
            +
            +
            + +
            + +
            + +
            + +
            + +
            + +
            + +
            + + +
            + +
            + +
            + +
            +
            + +
            + +
            + + + +
            + +
            + + + +
            + +
            + + + + +
            + +
            + +
            + +
            +
            + + +
            + + +
            diff --git a/templates/search-box/fields/areasize.php b/templates/search-box/fields/areasize.php new file mode 100755 index 00000000..47ee4d45 --- /dev/null +++ b/templates/search-box/fields/areasize.php @@ -0,0 +1 @@ + diff --git a/templates/search-box/fields/city-select.php b/templates/search-box/fields/city-select.php new file mode 100755 index 00000000..f8005b29 --- /dev/null +++ b/templates/search-box/fields/city-select.php @@ -0,0 +1,3 @@ + $label ): ?> + +
            + +
            + + diff --git a/templates/search-box/fields/location.php b/templates/search-box/fields/location.php new file mode 100755 index 00000000..3d43d415 --- /dev/null +++ b/templates/search-box/fields/location.php @@ -0,0 +1,2 @@ + + diff --git a/templates/search-box/fields/more-options.php b/templates/search-box/fields/more-options.php new file mode 100755 index 00000000..c297e8df --- /dev/null +++ b/templates/search-box/fields/more-options.php @@ -0,0 +1,33 @@ + +
            + + +
            +
            + +
            + +
            + +
            +
            +
            diff --git a/templates/search-box/fields/price.php b/templates/search-box/fields/price.php new file mode 100755 index 00000000..d8b6aabf --- /dev/null +++ b/templates/search-box/fields/price.php @@ -0,0 +1,20 @@ + 'price', + 'decimals' => opalestate_get_price_decimals(), + 'unit' => opalestate_currency_symbol() . ' ', + 'ranger_min' => opalestate_options( 'search_min_price', 0 ), + 'ranger_max' => opalestate_options( 'search_max_price', 10000000 ), + 'input_min' => $search_min_price, + 'input_max' => $search_max_price, +]; + +if ( opalestate_options( 'currency_position', 'before' ) == 'before' ) { + $data['unit_position'] = 'prefix'; +} + +?> + diff --git a/templates/search-box/fields/radius.php b/templates/search-box/fields/radius.php new file mode 100755 index 00000000..bc807e83 --- /dev/null +++ b/templates/search-box/fields/radius.php @@ -0,0 +1,15 @@ + 'radius', + 'unit' => 'miles', + 'ranger_min' => opalestate_options( 'search_min_radius', 0 ), + 'ranger_max' => opalestate_options( 'search_max_radius', 10000000 ), + 'input_min' => $search_min_radius, + 'input_max' => $search_max_radius, +]; + +opalesate_property_slide_ranger_template( esc_html__( 'Radius:', 'opalestate-pro' ), $data ); +?> diff --git a/templates/search-box/fields/search-city-text.php b/templates/search-box/fields/search-city-text.php new file mode 100755 index 00000000..a77ca7a3 --- /dev/null +++ b/templates/search-box/fields/search-city-text.php @@ -0,0 +1,44 @@ + 'geo_radius', + 'decimals' => 0, + 'unit' => $unit, + 'ranger_min' => 0, + 'ranger_max' => $max_price, + 'input_min' => 0, + 'input_max' => $max_price, + 'mode' => 1, + 'start' => $max_geo_radius, +]; + +?> +
            + + + + +
            +
            + + + +
            +
            diff --git a/templates/search-box/fields/search-text.php b/templates/search-box/fields/search-text.php new file mode 100755 index 00000000..631dacaa --- /dev/null +++ b/templates/search-box/fields/search-text.php @@ -0,0 +1,2 @@ + + diff --git a/templates/search-box/fields/state-select.php b/templates/search-box/fields/state-select.php new file mode 100755 index 00000000..708c2693 --- /dev/null +++ b/templates/search-box/fields/state-select.php @@ -0,0 +1,3 @@ + + +
            +
              + +
            • + +
            • + + + +
            • + name ); ?> +
            • + +
            + +
            diff --git a/templates/search-box/fields/status.php b/templates/search-box/fields/status.php new file mode 100755 index 00000000..fb64c6ee --- /dev/null +++ b/templates/search-box/fields/status.php @@ -0,0 +1,4 @@ + diff --git a/templates/search-box/fields/submit-button.php b/templates/search-box/fields/submit-button.php new file mode 100755 index 00000000..ba997687 --- /dev/null +++ b/templates/search-box/fields/submit-button.php @@ -0,0 +1,3 @@ + diff --git a/templates/search-box/fields/types.php b/templates/search-box/fields/types.php new file mode 100755 index 00000000..0da24748 --- /dev/null +++ b/templates/search-box/fields/types.php @@ -0,0 +1,9 @@ + diff --git a/templates/search-box/search-form-h.php b/templates/search-box/search-form-h.php new file mode 100755 index 00000000..36aac049 --- /dev/null +++ b/templates/search-box/search-form-h.php @@ -0,0 +1,77 @@ + + +
            +
            + 2 ] ); ?> +
            + +
            + +
            + +
            + + + +
            + +
            + + + +
            + +
            + + +
            +
            + +
            +
            + +
            + +
            + +
            + +
            + +
            + +
            + +
            + +
            + +
            + + + +
            diff --git a/templates/search-box/search-form-v.php b/templates/search-box/search-form-v.php new file mode 100755 index 00000000..e6913ac1 --- /dev/null +++ b/templates/search-box/search-form-v.php @@ -0,0 +1,58 @@ + + +
            + + + + + 'input' ] ); ?> + + + + + + + + + + +
            + diff --git a/templates/search-box/search-form-v2.php b/templates/search-box/search-form-v2.php new file mode 100755 index 00000000..248cc36f --- /dev/null +++ b/templates/search-box/search-form-v2.php @@ -0,0 +1,63 @@ + + +
            +
            +
            + +
            + +
            +
            + true ) ); ?> +
            + +
            +
            + 'input' ) ); ?> +
            + +
            +
            + +
            + +
            +
            + +
            + + + + +
            + +
            + +
            + + +
            + diff --git a/templates/search-box/search-form-v3.php b/templates/search-box/search-form-v3.php new file mode 100755 index 00000000..23e7000f --- /dev/null +++ b/templates/search-box/search-form-v3.php @@ -0,0 +1,80 @@ + + +
            +
            + +
            +
            + +
            + + +
            +
            + true ] ); ?> +
            + +
            +
            + 'input' ] ); ?> +
            + +
            +
            + +
            + +
            +
            + +
            + + + + +
            + +
            + +
            + + +
            + diff --git a/templates/search-box/simple-city.php b/templates/search-box/simple-city.php new file mode 100755 index 00000000..5537749f --- /dev/null +++ b/templates/search-box/simple-city.php @@ -0,0 +1,64 @@ + 6, + 1 => 3, + 2 => 3, + 3 => 3, + ]; +} else { + $grid = [ + 0 => 6, + 1 => 2, + 2 => 2, + 3 => 2, + ]; +} + +$display_more_options = isset( $display_more_options ) ? $display_more_options : false; + +$form_classes = [ + 'opalestate-search-form', + 'opalestate-search-form--simple-city', + isset( $hidden_labels ) && $hidden_labels ? 'hidden-labels' : '', +]; + +?> + +
            +
            +
            + +
            + +
            + +
            + +
            + +
            + + +
            + +
            + +
            + + + + +
            diff --git a/templates/search-box/simple-keyword.php b/templates/search-box/simple-keyword.php new file mode 100755 index 00000000..c445afe6 --- /dev/null +++ b/templates/search-box/simple-keyword.php @@ -0,0 +1,64 @@ + 6, + 1 => 3, + 2 => 3, + 3 => 3, + ]; +} else { + $grid = [ + 0 => 6, + 1 => 2, + 2 => 2, + 3 => 2, + ]; +} + +$display_more_options = isset( $display_more_options ) ? $display_more_options : false; + +$form_classes = [ + 'opalestate-search-form', + 'opalestate-search-form--simple-keyword', + isset( $hidden_labels ) && $hidden_labels ? 'hidden-labels' : '', +]; + +?> + +
            +
            +
            + +
            + +
            + +
            + +
            + +
            + + +
            + +
            + +
            + + + + +
            diff --git a/templates/shortcodes/ajax-map-quick-search.php b/templates/shortcodes/ajax-map-quick-search.php new file mode 100755 index 00000000..ae9fa437 --- /dev/null +++ b/templates/shortcodes/ajax-map-quick-search.php @@ -0,0 +1,53 @@ + + diff --git a/templates/shortcodes/ajax-map-search-result.php b/templates/shortcodes/ajax-map-search-result.php new file mode 100755 index 00000000..3935eb7a --- /dev/null +++ b/templates/shortcodes/ajax-map-search-result.php @@ -0,0 +1,75 @@ + +
            +
            +
            +
            +
            + found_posts ): ?> + found_posts ); ?> + +
            +
            +
            +
            + +
            + +
            + +
            +
            +
            + +
            + have_posts() ): ?> +
            + + have_posts() ) : $query->the_post(); ?> +
            + +
            + + + have_posts() ) : $query->the_post(); + $cls = ''; + if ( $cnt++ % $column == 0 ) { + $cls .= ' first-child'; + } + ?> +
            + +
            + + +
            + + + + +
            +
            +max_num_pages > 1 ): ?> +
            max_num_pages ); ?>
            + + + diff --git a/templates/shortcodes/search-agents.php b/templates/shortcodes/search-agents.php new file mode 100755 index 00000000..2cf3e17e --- /dev/null +++ b/templates/shortcodes/search-agents.php @@ -0,0 +1,44 @@ + +
            + + have_posts() ): ?> +
            + +
            +
            +

            ' . $query->found_posts . '' ) ?>

            +
            + +
            + +
            +
            + +
            + have_posts() ): $query->the_post(); ?> +
            + +
            + +
            + max_num_pages ): ?> +
            + max_num_pages ); ?> +
            + +
            + + +
            + +
            + +
            + diff --git a/templates/shortcodes/search-map-properties.php b/templates/shortcodes/search-map-properties.php new file mode 100755 index 00000000..033d49bd --- /dev/null +++ b/templates/shortcodes/search-map-properties.php @@ -0,0 +1,8 @@ + +
            +
            + +
            +
            diff --git a/templates/shortcodes/search-properties-result.php b/templates/shortcodes/search-properties-result.php new file mode 100755 index 00000000..b8d148e9 --- /dev/null +++ b/templates/shortcodes/search-properties-result.php @@ -0,0 +1,73 @@ + +
            +
            +
            +
            + +
            + +
            +
            + +
            +
            +
            +
            + +
            + +
            + found_posts ); ?> +
            +
            +
            + +
            +
            + +
            + have_posts() ): ?> +
            + + have_posts() ) : $query->the_post(); ?> +
            + +
            + + + have_posts() ) : $query->the_post(); + $cls = ''; + $layout = isset( $style ) ? 'content-property-' . $style : $grid_layout; + + if ( $cnt++ % $column == 0 ) { + $cls .= ' first-child'; + } + ?> +
            + +
            + + +
            + + + +
            +
            +max_num_pages > 1 ): ?> +
            max_num_pages ); ?>
            + + +
            + +
            +
          • diff --git a/templates/shortcodes/search-properties.php b/templates/shortcodes/search-properties.php new file mode 100755 index 00000000..28453fa8 --- /dev/null +++ b/templates/shortcodes/search-properties.php @@ -0,0 +1,20 @@ + +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            + +
            +
            +
            diff --git a/templates/shortcodes/submission-form.php b/templates/shortcodes/submission-form.php new file mode 100755 index 00000000..84c74be3 --- /dev/null +++ b/templates/shortcodes/submission-form.php @@ -0,0 +1,61 @@ + +
            +
            +
            + + +
            + + + + +
            + +
            + + +
            + + +
            + +

            + +

            + +
            + + + +
            +
            + $value ): ?> + + + + + + +
            +
            + '
            %3$s'.$nonce.'
            ', + 'save_button' => esc_html__( 'Save property', 'opalestate-pro' ), + ] ); ?> +
            +
            + + + +
            +
            +
            diff --git a/templates/single-agency/author-box.php b/templates/single-agency/author-box.php new file mode 100755 index 00000000..0175093a --- /dev/null +++ b/templates/single-agency/author-box.php @@ -0,0 +1,162 @@ +get_meta( 'address' ); ?> +
            + +
            +
            +
            +
            + +
            +
            + + + + + + + +
            + is_featured() ): ?> +
            + + + +
            + + + get_trusted() ): ?> + + + + +
            + +
            +
            + +
            +
            + +
            +

            +

            + +

            +
            +
            +
            +
            +
            +
            +
            + + +
            + +
            +
            + ', '' ); ?> + +

            +
            + +
            + + +
            + + + +
            + + + + +
            + + + + + +
            + +
            + + + + +
            + +
            + + + + +
            + +
            + + + + +
            + + + + +
            + + +
            + + +
            + +
            + + + + + + + + + + + + + + + + + + + + + +
            +
            +
            +
            + + diff --git a/templates/single-agency/gallery.php b/templates/single-agency/gallery.php new file mode 100755 index 00000000..9b289547 --- /dev/null +++ b/templates/single-agency/gallery.php @@ -0,0 +1,17 @@ +get_gallery(); + +if ( ! $gallery ) { + return; +} +?> + + diff --git a/templates/single-agency/index.html b/templates/single-agency/index.html new file mode 100755 index 00000000..dcaf7169 --- /dev/null +++ b/templates/single-agency/index.html @@ -0,0 +1 @@ +index.html diff --git a/templates/single-agency/properties.php b/templates/single-agency/properties.php new file mode 100755 index 00000000..7d129c70 --- /dev/null +++ b/templates/single-agency/properties.php @@ -0,0 +1,39 @@ +have_posts() ) : + $id = rand(); +?> +
            +
            +

            found_posts );?>

            +
            +
            + have_posts() ) : $query->the_post(); ?> +
            + +
            + +
            + max_num_pages > 1 ): ?> +
            max_num_pages; // opalestate_pagination( $query->max_num_pages ); ?>
            +
            + + +
            +
            + +
            + +
            + + + diff --git a/templates/single-agency/summary.php b/templates/single-agency/summary.php new file mode 100755 index 00000000..badd962b --- /dev/null +++ b/templates/single-agency/summary.php @@ -0,0 +1,53 @@ +
            + +
            +
            +
            + +
            + + + +
            + + +
            + + + +
            + + + +
            + + + + +
            + +
            + + + + +
            + + + +
            + +
            +
            + +
            +
            +
            +

            + +

            +
            + +
            +
            +
            \ No newline at end of file diff --git a/templates/single-agency/tabs.php b/templates/single-agency/tabs.php new file mode 100755 index 00000000..e91a49c7 --- /dev/null +++ b/templates/single-agency/tabs.php @@ -0,0 +1,40 @@ + +
            + +
            +
            + +
            + + +
            + +
            + + +
            + +
            + +
            + +
            + diff --git a/templates/single-agency/team.php b/templates/single-agency/team.php new file mode 100755 index 00000000..81248482 --- /dev/null +++ b/templates/single-agency/team.php @@ -0,0 +1,26 @@ + +
            + +
            + +
            + $user_id ] ); ?> +
            + +
            + + + + +
            + + diff --git a/templates/single-agent/author-box.php b/templates/single-agent/author-box.php new file mode 100755 index 00000000..e0787999 --- /dev/null +++ b/templates/single-agent/author-box.php @@ -0,0 +1,130 @@ + +
            +
            +
            + +
            + + + + render_level(); ?> + is_featured() ): ?> + + + + + + + + get_trusted() ): ?> + + + + +
            + +
            +
            +

            + +

            + + get_meta( 'job' ); ?> +

            + + get_meta( 'email' ); ?> + +
            + + + + +
            + + + get_meta( 'phone' ); ?> + +
            + + + + +
            + + + get_meta( 'mobile' ); ?> + +
            + + + + +
            + + + get_meta( 'fax' ); ?> + +
            + +
            + + + get_meta( 'web' ); ?> + +
            + + + + +
            + + + get_socials(); ?> + + +
            + + + + + + + + + + + + + + + + + + + + + + + +
            + +
            + + + +
            + +
            +

            + + + +

            + +
            +
            diff --git a/templates/single-agent/box.php b/templates/single-agent/box.php new file mode 100755 index 00000000..6d540e54 --- /dev/null +++ b/templates/single-agent/box.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/single-agent/featured-properties.php b/templates/single-agent/featured-properties.php new file mode 100755 index 00000000..c1740645 --- /dev/null +++ b/templates/single-agent/featured-properties.php @@ -0,0 +1,33 @@ +have_posts() ) : + + $data = [ + 'slidesPerView' => 1, + 'spaceBetween' => 0, + 'effect' => 'slide', + 'loop' => true, + 'breakpoints' => [ 1024 => [ "slidesPerView" => 1 ] ], + ]; + ?> + + + get_the_ID() ); + + if( isset($author_id) && $author_id ){ + + $args = array( + 'post_id' => get_the_ID(), + 'id' => $author_id, + 'email' => $email, + 'message' => '', + 'type' => 'user', + ); + echo opalestate_load_template_path( 'messages/contact-form', $args ); + }else { + $email = get_post_meta( get_the_ID(), OPALESTATE_AGENT_PREFIX . 'email', true ); + $args = array( + 'post_id' => get_the_ID(), + 'id' => get_the_ID(), + 'email' => $email, + 'message' => '', + 'type' => 'agent', + ); + + echo opalestate_load_template_path( 'messages/contact-form', $args ); + } \ No newline at end of file diff --git a/templates/single-agent/properties.php b/templates/single-agent/properties.php new file mode 100755 index 00000000..cc681382 --- /dev/null +++ b/templates/single-agent/properties.php @@ -0,0 +1,29 @@ +have_posts() ) : +?> +
            +
            +

            found_posts );?>

            +
            +
            +
            + have_posts() ) : $query->the_post(); ?> +
            + +
            + +
            +
            + max_num_pages > 1 ): ?> +
            max_num_pages ); ?>
            + +
            +
            + diff --git a/templates/single-agent/summary.php b/templates/single-agent/summary.php new file mode 100755 index 00000000..8d1e8135 --- /dev/null +++ b/templates/single-agent/summary.php @@ -0,0 +1,54 @@ +
            + +
            +
            +
            + +
            + + + +
            + + +
            + + + +
            + + + + +
            + + + + +
            + +
            + + + + +
            + + + +
            + +
            +
            + +
            +
            +
            +

            + +

            +
            + +
            +
            +
            \ No newline at end of file diff --git a/templates/single-opalestate_agency.php b/templates/single-opalestate_agency.php new file mode 100755 index 00000000..5237431d --- /dev/null +++ b/templates/single-opalestate_agency.php @@ -0,0 +1,25 @@ + +
            + +
            +
            +
            + + + + + + + + + + +
            +
            + + diff --git a/templates/single-opalestate_agent.php b/templates/single-opalestate_agent.php new file mode 100755 index 00000000..58f7eb0d --- /dev/null +++ b/templates/single-opalestate_agent.php @@ -0,0 +1,32 @@ + +
            +
            +
            +
            +
            + ', '' ); ?> +
            +
            +
            +
            +
            +
            + + + + + + + + + + +
            +
            + + diff --git a/templates/single-opalestate_property.php b/templates/single-opalestate_property.php new file mode 100755 index 00000000..a818fefd --- /dev/null +++ b/templates/single-opalestate_property.php @@ -0,0 +1,33 @@ + + +
            +
            +
            + + + + + +
            +
            + +
            +
            + + + + +
            +
            +
            + + diff --git a/templates/single-property/amenities.php b/templates/single-property/amenities.php new file mode 100755 index 00000000..d44fddc7 --- /dev/null +++ b/templates/single-property/amenities.php @@ -0,0 +1,25 @@ +get_amenities(); + +?> +get_block_setting( 'amenities' ) && $amenities ): ?> +
            +
            +
            +
            + +
            + term_id, 'opalestate_amt_image_id', true )) { + echo wp_get_attachment_image( $image_id ); + } + ?> + name ); ?> +
            + +
            +
            +
            + diff --git a/templates/single-property/apartments.php b/templates/single-property/apartments.php new file mode 100755 index 00000000..6fa46331 --- /dev/null +++ b/templates/single-property/apartments.php @@ -0,0 +1,55 @@ +get_block_setting( 'apartments' ) ) { + return; +} + +$apartments = $property->get_apartments(); +if ( ! $apartments ) { + return; +} + +?> +
            +

            +
            +
            +
            +
            + + + + + + + + + + + + + + $apartment ) : ?> + + + + + + + + + + + +
            + + + + + +
            +
            +
            +
            +
            +
            diff --git a/templates/single-property/attachments.php b/templates/single-property/attachments.php new file mode 100755 index 00000000..f90784e5 --- /dev/null +++ b/templates/single-property/attachments.php @@ -0,0 +1,27 @@ +get_block_setting( 'attachments' ) ) { + return; +} + +$attachments = $property->get_attachments(); +?> + +
            +
            +
            +
            + $attachment ) : + $attachment_title = get_the_title( $id ); + ?> +
            + + + +
            + +
            +
            +
            + diff --git a/templates/single-property/author-v2.php b/templates/single-property/author-v2.php new file mode 100755 index 00000000..39b26974 --- /dev/null +++ b/templates/single-property/author-v2.php @@ -0,0 +1,51 @@ +get_author_type(); +$data = get_userdata( $post->post_author ); +$layout = ''; +switch ( $type ) { + case 'hide': + return ; + break; + case 'agent' : + $agent_id = $property->get_metabox_value( 'agent' ); + + $author_info = opalestate_load_template_path( 'single-property/user/author-member-box', + array( 'author' => $data, + 'id' => $agent_id , + 'prefix' => OPALESTATE_AGENT_PREFIX, + 'picture' => '', + 'type' => 'agent', + 'hide_description' => true ) ); + break; + case 'agency' : + $agency_id = $property->get_metabox_value( 'agency' ); + $author_info = opalestate_load_template_path( 'single-property/user/author-member-box', + array( 'author' => $data, + 'id' => $agency_id , + 'picture' => '', + 'type' => 'agency', + 'hide_description' => true ) ); + break; + default: + + $author_info = opalestate_load_template_path( 'single-property/user/author-user-box', array('author' => $data , 'hide_description' => true ), $layout ); + + break; +} +?> +
            +
            +
            +
            + +
            +
            +
            +
            + + diff --git a/templates/single-property/author-v3.php b/templates/single-property/author-v3.php new file mode 100755 index 00000000..18392991 --- /dev/null +++ b/templates/single-property/author-v3.php @@ -0,0 +1,50 @@ +get_author_type(); +$data = get_userdata( $post->post_author ); +$layout = 'list'; +switch ( $type ) { + case 'hide': + return ; + break; + case 'agent' : + $agent_id = $property->get_metabox_value( 'agent' ); + + $author_info = opalestate_load_template_path( 'single-property/user/author-member-box', + array( 'author' => $data, + 'id' => $agent_id , + 'prefix' => OPALESTATE_AGENT_PREFIX, + 'picture' => '', + 'type' => 'agent', + 'hide_description' => true ) ); + break; + case 'agency' : + $agency_id = $property->get_metabox_value( 'agency' ); + $author_info = opalestate_load_template_path( 'single-property/user/author-member-box', + array( 'author' => $data, + 'id' => $agency_id , + 'picture' => '', + 'type' => 'agency', + 'hide_description' => true ) ); + break; + default: + + $author_info = opalestate_load_template_path( 'single-property/user/author-user-box', array('author' => $data , 'hide_description' => true ), $layout ); + + break; +} +?> +
            +
            +
            +
            + +
            +
            + true) ); ?> +
            +
            diff --git a/templates/single-property/author.php b/templates/single-property/author.php new file mode 100755 index 00000000..7555ecf0 --- /dev/null +++ b/templates/single-property/author.php @@ -0,0 +1,60 @@ +get_author_type(); +$data = get_userdata( $post->post_author ); +$layout = 'list'; +switch ( $type ) { + case 'hide': + return; + break; + case 'agent' : + $agent_id = $property->get_metabox_value( 'agent' ); + + $author_info = opalestate_load_template_path( 'single-property/user/author-member-box', + [ + 'author' => $data, + 'id' => $agent_id, + 'prefix' => OPALESTATE_AGENT_PREFIX, + 'picture' => '', + 'type' => 'agent', + 'hide_description' => true, + ] ); + break; + case 'agency' : + $agency_id = $property->get_metabox_value( 'agency' ); + $author_info = opalestate_load_template_path( 'single-property/user/author-member-box', + [ + 'author' => $data, + 'id' => $agency_id, + 'picture' => '', + 'type' => 'agency', + 'hide_description' => true, + ] ); + break; + default: + + $author_info = opalestate_load_template_path( 'single-property/user/author-user-box', [ 'author' => $data, 'hide_description' => true ], $layout ); + + break; +} +?> +
            +
            +
            +
            +
            +
            + +
            +
            +
            + true ] ); ?> +
            +
            +
            +
            +
            diff --git a/templates/single-property/content.php b/templates/single-property/content.php new file mode 100755 index 00000000..7de5db14 --- /dev/null +++ b/templates/single-property/content.php @@ -0,0 +1,17 @@ +
            +
            + ', '', false ) + ) ); + + wp_link_pages( array( + 'before' => '', + 'link_before' => '', + 'link_after' => '', + ) ); + ?> +
            \ No newline at end of file diff --git a/templates/single-property/facilities.php b/templates/single-property/facilities.php new file mode 100755 index 00000000..8fa1d5ab --- /dev/null +++ b/templates/single-property/facilities.php @@ -0,0 +1,26 @@ +get_facilities(); + +?> + +get_block_setting( 'facilities' ) && $facilities && isset( $facilities[0] ) && ! empty( $facilities[0] ) ): ?> +
            +
            +
            +
            + +
            + + + : + + + +
            + +
            +
            +
            + diff --git a/templates/single-property/features.php b/templates/single-property/features.php new file mode 100755 index 00000000..aede7b7e --- /dev/null +++ b/templates/single-property/features.php @@ -0,0 +1,51 @@ +get_metabox_info(); + +$types = $property->get_types(); +$status = $property->get_status(); + +?> +ha cong +
            +

            +
            + +
            +
            diff --git a/templates/single-property/floor-plans.php b/templates/single-property/floor-plans.php new file mode 100755 index 00000000..3eade2e9 --- /dev/null +++ b/templates/single-property/floor-plans.php @@ -0,0 +1,86 @@ +get_block_setting( 'floor_plans' ) ) { + return; +} + +$floor_plans = $property->get_floor_plans(); +if ( ! $floor_plans ) { + return; +} + +?> +
            +

            +
            +
            +
            +
            + $plan ) : ?> + + + + +
            + +
            + $plan ) : ?> +
            + +

            + +

            + +
              + +
            • + + +
            • + + + +
            • + + +
            • + + + +
            • + + +
            • + + + +
            • + + +
            • + +
            + + +
            + +
            + + + +
            + +
            + +
            + +
            +
            +
            +
            +
            diff --git a/templates/single-property/information.php b/templates/single-property/information.php new file mode 100755 index 00000000..cacc6889 --- /dev/null +++ b/templates/single-property/information.php @@ -0,0 +1,36 @@ +get_meta_fullinfo(); +$taxs = $property->get_types_tax(); + +?> +
            +
            +
            +
              + +
            • +
              +
              + + name ); ?> + +
              +
            • + + + $info ) : ?> + +
            • +
              +
              :
              + +
              +
            • + + + +
            +
            +
            diff --git a/templates/single-property/location.php b/templates/single-property/location.php new file mode 100755 index 00000000..dccb0fd6 --- /dev/null +++ b/templates/single-property/location.php @@ -0,0 +1,19 @@ +getLocations(); + +if ( !empty($locations) ) : +?> + + + + name ); ?> + + + + diff --git a/templates/single-property/map-v2.php b/templates/single-property/map-v2.php new file mode 100755 index 00000000..83f3a7fe --- /dev/null +++ b/templates/single-property/map-v2.php @@ -0,0 +1,95 @@ +get_block_setting( 'map' ) ) { + return; +} + +$maps = $property->get_map(); + +if ( empty( $maps ) ) { + return; +} +?> +
            + +
            +
            +
            + +
            + +
            +
            + +
            +
            +
            +
            +
            +
            +
            + +
            +
            + +
            +
            + +
            +
            + + +
            + +
            + +
            +
            + +
            +
            +
            +
            +
            + enable_google_mapview() ) : ?> +
            +
            + +
            +
            +
            +
            diff --git a/templates/single-property/map.php b/templates/single-property/map.php new file mode 100755 index 00000000..32ee32b7 --- /dev/null +++ b/templates/single-property/map.php @@ -0,0 +1,98 @@ +get_block_setting( 'map' ) ) { + return; +} + +$maps = $property->get_map(); + +if ( empty( $maps ) ) { + return; +} +$id = time(); +?> +
            +

            +
            +
            + + +
            +
            + + +
            +
            +
            +
            +
            + + +
            + + +
            +
            +
            + +
            +
            + +
            +
            + +
            +
            + + +
            + +
            + +
            +
            + +
            +
            +
            +
            +
            + + enable_google_mapview() ) : ?> +
            +
            +
            +
            + +
            +
            +
            +
            + + diff --git a/templates/single-property/meta.php b/templates/single-property/meta.php new file mode 100755 index 00000000..ac048cd5 --- /dev/null +++ b/templates/single-property/meta.php @@ -0,0 +1,37 @@ +get_meta_shortinfo(); +?> +
            +
            +
            +
            + get_price() ); ?> + + get_sale_price() ): ?> + get_sale_price() ); ?> + + + get_price_label() ): ?> + get_price_label() ); ?> + +
            +
            +
            +
              + + $info ) : ?> +
            • + + +
            • + + +
            +
            +
            +
            diff --git a/templates/single-property/nearby.php b/templates/single-property/nearby.php new file mode 100755 index 00000000..863b7aa2 --- /dev/null +++ b/templates/single-property/nearby.php @@ -0,0 +1,53 @@ +get_block_setting( 'nearby' ) ) { + return; +} + +if ( ! Opalestate_Yelp::get_client_id() || ! Opalestate_Yelp::get_app_key() ) { + return; +} + +$categories = Opalestate_Yelp::get_categories(); +if ( ! $categories ) { + return; +} + +$map = $property->get_map(); + +$latitude = $map['latitude']; +$longitude = $map['longitude']; +if ( ! $latitude || ! $longitude ) { + return; +} + +?> +
            +

            +
            +
            +
            + +
            +
            +
            \ No newline at end of file diff --git a/templates/single-property/preview.php b/templates/single-property/preview.php new file mode 100755 index 00000000..0d4f4409 --- /dev/null +++ b/templates/single-property/preview.php @@ -0,0 +1,100 @@ +
            + get_gallery(); + $image_size = opalestate_get_option( 'opalestate_thumbnail_size', 'medium' ); + if ( isset( $galleries ) && $galleries ): + ?> + 1, + 'spaceBetween' => 0, + 'loop' => true, + 'autoHeight' => 1, + 'pagination' => 0, + 'effect' => 'slide', + 'breakpoints' => [ 1024 => [ "slidesPerView" => 1 ] ], + 'thumbnails_nav' => "#swiper-pagination-images", + ]; + + $columns = apply_filters( 'opalestate_thumbnail_nav_column', 5 ); + + $datanav = [ + 'slidesPerView' => $columns, + 'spaceBetween' => 10, + 'effect' => 'slide', + + 'slideToClickedSlide' => true, + 'touchRatio' => 0.2, + 'loop' => false, + 'breakpoints' => [ 1024 => [ "slidesPerView" => 5 ], 768 => [ "slidesPerView" => 3 ] ], + 'navigation' => [ + 'nextEl' => '.swiper-button-next', + 'prevEl' => '.swiper-button-prev', + ], + ]; + ?> + +
            +
            + +
            + +
            + + $columns ) : ?> +
            +
            + + +
            + +
            +
            +
            + + + + $src ): ?> +
            +
            +
            + + +
            +
            +
            + + +
            + +
            + + +
            diff --git a/templates/single-property/preview/gallery-metro.php b/templates/single-property/preview/gallery-metro.php new file mode 100755 index 00000000..dfbaf1d1 --- /dev/null +++ b/templates/single-property/preview/gallery-metro.php @@ -0,0 +1,87 @@ +
            + get_gallery(); + + + $image_size = opalestate_get_option( 'opalestate_thumbnail_size' ); + if ( ! empty( $galleries ) && isset( $galleries ) ): + ?> + 1, + 'spaceBetween' => 0, + 'effect' => 'fade', + 'loop' => true, + 'pagination' => 0, + 'breakpoints' => [ 1024 => [ "slidesPerView" => 1 ] ], + ]; + + $columns = apply_filters( 'opalestate_thumbnail_nav_column', 5 ); + $src = wp_get_attachment_url( get_post_thumbnail_id() ); + + $show = 9; + $items = array_chunk( $galleries, $show ); + + if ( count( $items[0] ) < $show ) { + for ( $i = count( $items[0] ); $i < $show; $i++ ) { + $items[0][ $i ] = 'none'; + } + $hasMore = false; + } else { + $hasMore = true; + } + + // echo '
            ' . print_r( $items,1 );die;
            +		?>
            +
            +
            +        
            +
            +	
            +
            +		
            +            
            + +
            + + + + +
            diff --git a/templates/single-property/preview/gallery-slider.php b/templates/single-property/preview/gallery-slider.php new file mode 100755 index 00000000..b9e6804c --- /dev/null +++ b/templates/single-property/preview/gallery-slider.php @@ -0,0 +1,78 @@ +
            + +
            diff --git a/templates/single-property/preview/map.php b/templates/single-property/preview/map.php new file mode 100755 index 00000000..747d0477 --- /dev/null +++ b/templates/single-property/preview/map.php @@ -0,0 +1,56 @@ +get_map(); + +if ( !empty($maps) ): +$id = time(); +?> +
            + +
            + +
            +
            +
            + +
            +
            + +
            +
            + +
            +
            + + +
            + +
            + +
            +
            + +
            +
            +
            + +
            + diff --git a/templates/single-property/preview/mark-picture.php b/templates/single-property/preview/mark-picture.php new file mode 100755 index 00000000..917af35a --- /dev/null +++ b/templates/single-property/preview/mark-picture.php @@ -0,0 +1,32 @@ + +
            + + +
            + +
            + +
            +
            +
            + ', '' ); ?> + + +
            +
            +
            + latitude && $property->longitude ) : ?> + + + + + get_address() ); ?> +
            +
            +
            +
            + +
            +
            +
            +
            diff --git a/templates/single-property/preview/tabs.php b/templates/single-property/preview/tabs.php new file mode 100755 index 00000000..a6a114d5 --- /dev/null +++ b/templates/single-property/preview/tabs.php @@ -0,0 +1,97 @@ +get_map(); + +if ( ! empty( $maps ) ): + + $id = time(); + + ?> +
            +
            +
            + + +
            + +
            + + +
            +
            + +
            + + +
            +
            + +
            + +
            +
            + +
            +
            + +
            +
            + + +
            + +
            + +
            +
            + +
            +
            +
            + +
            +
            + enable_google_mapview() ) : ?> + +
            +
            +
            +
            + + +
            +
            +
            + + diff --git a/templates/single-property/preview/virtualtour.php b/templates/single-property/preview/virtualtour.php new file mode 100755 index 00000000..620bb114 --- /dev/null +++ b/templates/single-property/preview/virtualtour.php @@ -0,0 +1,15 @@ +get_virtual_tour(); +?> + +
            + +
            + + +
            + +
            + + diff --git a/templates/single-property/price.php b/templates/single-property/price.php new file mode 100755 index 00000000..932dd269 --- /dev/null +++ b/templates/single-property/price.php @@ -0,0 +1,13 @@ +get_format_price(); +?> +
            + get_price() ); ?> +
            +
            + get_sale_price() ); ?> +
            diff --git a/templates/single-property/sameagent.php b/templates/single-property/sameagent.php new file mode 100755 index 00000000..9572f468 --- /dev/null +++ b/templates/single-property/sameagent.php @@ -0,0 +1,21 @@ +ID); +$properties = Opalestate_Query::get_agent_property( get_the_ID(), $agent_id, 3 ); +if( $properties->have_posts() ) : +?> +
            +

            +
            +
            + have_posts() ) : $properties->the_post(); ?> +
            + +
            + +
            +
            +
            + + + diff --git a/templates/single-property/sharebox.php b/templates/single-property/sharebox.php new file mode 100755 index 00000000..45eeae05 --- /dev/null +++ b/templates/single-property/sharebox.php @@ -0,0 +1,81 @@ + + * @copyright Copyright (C) 2015 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ +/** + * Enable/distable share box + */ + +global $post; +$args = array( 'position' => 'top', 'animation' => 'true' ); +?> +
            +
            +
            + + +
            +
            diff --git a/templates/single-property/short-meta.php b/templates/single-property/short-meta.php new file mode 100755 index 00000000..e46869e8 --- /dev/null +++ b/templates/single-property/short-meta.php @@ -0,0 +1,31 @@ +get_meta_shortinfo(); + ?> + +
              + + $info ) : ?> + +
            • +
              + +
              +
              + + + + +
              +
            • + + + +
            + + +
            + +
            +
            + +
            + + + + + + + + + + + +
            + +
            + +
            + +
            +
            +

            + + post_title ); ?> + +

            + + + + +
            + + + + +
            + + + + + +
            + +
            + + + + +
            + +
            + + + + +
            + +
            + + + + +
            + + + + +
            + + +
            + + + + + + + + + + + + + + + + + + + + + +
            + +
            +
            +
            diff --git a/templates/single-property/user/author-user-box-list.php b/templates/single-property/user/author-user-box-list.php new file mode 100755 index 00000000..719cc9be --- /dev/null +++ b/templates/single-property/user/author-user-box-list.php @@ -0,0 +1,110 @@ + +
            + ID; + $is_sticky = get_user_meta( $user_id, $prefix . 'sticky', true ); + $picture = OpalEstate_User::get_author_picture( $user_id ); + + $desciption = get_user_meta( $user_id, 'description', true ); + + + $roles = opalestate_user_roles_by_user_id( $user_id ); + + if ( ! is_array( $roles ) ) { + $roles = [ $roles ]; + } + + $related = get_user_meta( $user_id, $prefix . 'related_id', true ); + $trusted = false; + if ( in_array( 'opalestate_agency', $roles ) || in_array( 'opalestate_agent', $roles ) ) { + $link = get_permalink( $related ); + $author_name = get_the_title( $related ); + $trusted = get_post_meta( $related, $prefix . 'trusted', true ); + } elseif ( $related ) { + + $link = get_permalink( $related ); + $author_name = get_the_title( $related ); + $trusted = get_user_meta( $user_id, $prefix . 'trusted', true ); + + } else { + $link = get_author_posts_url( $user_id ); + $author_name = $author->display_name; + $trusted = get_user_meta( $user_id, $prefix . 'trusted', true ); + } + + ?> +
            +
            +
            + + + +
            +
            +

            + + + + + + + +

            + + +

            + + +
            + +
            + +
            + + + + +
            + +
            + + + + + + + + + + + + + + + + + + + + +
            + + +
            +
            + diff --git a/templates/single-property/user/author-user-box.php b/templates/single-property/user/author-user-box.php new file mode 100755 index 00000000..c2e9759d --- /dev/null +++ b/templates/single-property/user/author-user-box.php @@ -0,0 +1,153 @@ + +
            + ID; + $is_sticky = get_user_meta( $user_id, $prefix . 'sticky', true ); + + + $desciption = get_user_meta( $user_id, 'description', true ); + + $roles = opalestate_user_roles_by_user_id( $user_id ); + + if ( ! is_array( $roles ) ) { + $roles = [ $roles ]; + } + + $related = get_user_meta( $user_id, $prefix . 'related_id', true ); + $trusted = false; + if ( in_array( 'opalestate_agency', $roles ) || in_array( 'opalestate_agent', $roles ) ) { + $post = get_post( $related ); + $link = get_permalink( $related ); + $author_name = $post->post_title; + + if ( $post->post_type == 'opalestate_agency' ) { + $prefixs = OPALESTATE_AGENCY_PREFIX; + $picture = OpalEstate_Agency::get_avatar_url( $post->ID ); + } else { + $prefixs = OPALESTATE_AGENT_PREFIX; + $picture = OpalEstate_Agent::get_avatar_url( $post->ID ); + } + + $trusted = get_post_meta( $related, $prefixs . 'trusted', true ); + } elseif ( $related ) { + $post = get_post( $related ); + $link = get_permalink( $related ); + $author_name = $post->post_title; + + if ( $post->post_type == 'opalestate_agency' ) { + $prefixs = OPALESTATE_AGENCY_PREFIX; + $picture = OpalEstate_Agency::get_avatar_url( $post->ID ); + } else { + $prefixs = OPALESTATE_AGENT_PREFIX; + $picture = OpalEstate_Agent::get_avatar_url( $post->ID ); + } + + $trusted = get_post_meta( $related, $prefixs . 'trusted', true ); + } else { + $link = get_author_posts_url( $user_id ); + $author_name = $author->display_name; + $trusted = get_user_meta( $user_id, $prefix . 'trusted', true ); + $picture = OpalEstate_User::get_author_picture( $user_id ); + } + + ?> +
            + +
            +
            + + + + + + + + + +
            +
            + + +
            +

            + +

            + + +

            + + + +
            + + + + +
            + + + + +
            + +
            + + + + +
            + + + + +
            + + + + +
            + + + + + + + + + + + + + + + + + + + + + +
            + +
            + +
            +
            + diff --git a/templates/single-property/video.php b/templates/single-property/video.php new file mode 100755 index 00000000..ccf3a903 --- /dev/null +++ b/templates/single-property/video.php @@ -0,0 +1,19 @@ +get_block_setting( 'video' ) ) { + return; +} + +$videoURL = $property->get_video_url(); +?> + +
            +

            +
            +
            + +
            +
            +
            + diff --git a/templates/single-property/views-statistics.php b/templates/single-property/views-statistics.php new file mode 100755 index 00000000..2f1b537b --- /dev/null +++ b/templates/single-property/views-statistics.php @@ -0,0 +1,83 @@ +get_block_setting( 'views_statistics' ) ) { + return; +} + +$limit = opalestate_get_option( 'single_views_statistics_limit', 8 ); + +$stats = new Opalestate_View_Stats( $property->get_id(), $limit ); +$array_label = json_encode( $stats->get_traffic_labels() ); +$array_values = json_encode( $stats->get_traffic_data_accordion() ); + +?> +
            +

            +
            +
            + +
            +
            +
            + diff --git a/templates/single-property/virtualtour.php b/templates/single-property/virtualtour.php new file mode 100755 index 00000000..af49dc23 --- /dev/null +++ b/templates/single-property/virtualtour.php @@ -0,0 +1,15 @@ +get_virtual_tour(); +?> + +
            +

            +
            +
            + +
            +
            +
            + diff --git a/templates/single-property/walkscore.php b/templates/single-property/walkscore.php new file mode 100755 index 00000000..1b9293e9 --- /dev/null +++ b/templates/single-property/walkscore.php @@ -0,0 +1,56 @@ +get_block_setting( 'walkscores' ) ) { + return; +} + +$walkscore = opalestate_get_property_walkscore_results( $property ); + +?> +
            +

            + +
            +
            + walkscore ) ) : ?> +
            +
            +

            walkscore ); ?>

            +
            +
            +
            + description ); ?> +
            + +
            + + + transit ) && $walkscore->transit->score ) : ?> +
            +
            +

            transit->score ); ?>

            +
            +
            +
            + transit->description ); ?> +
            + +
            + + + bike ) ) : ?> +
            +
            +

            bike->score ); ?>

            +
            +
            +
            + bike->description ); ?> +
            + +
            + +
            +
            +
            diff --git a/templates/submission/completed.php b/templates/submission/completed.php new file mode 100755 index 00000000..43f0780a --- /dev/null +++ b/templates/submission/completed.php @@ -0,0 +1,27 @@ +session->get( 'submission' ); +?> +
            +
            + +
            +
            + ', '', + '', '' + ); ?> +
            + +
            + + ', '', + '', '' + ); ?> +
            + +
            +
            +session->set( 'submission', null ); ?> \ No newline at end of file diff --git a/templates/submission/require-login.php b/templates/submission/require-login.php new file mode 100755 index 00000000..2b146f20 --- /dev/null +++ b/templates/submission/require-login.php @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/templates/submission/submission-completed.php b/templates/submission/submission-completed.php new file mode 100755 index 00000000..9a2f4254 --- /dev/null +++ b/templates/submission/submission-completed.php @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/templates/submission/submission-form.php b/templates/submission/submission-form.php new file mode 100755 index 00000000..c5a793ab --- /dev/null +++ b/templates/submission/submission-form.php @@ -0,0 +1,49 @@ + +
            +
            +
            + + +
            + +

            +

            + +

            +

            + +
            + + + +
            +
            + $value ): ?> + + + + + + +
            +
            + '
            %3$s'.$nonce.'
            ', + 'save_button' => esc_html__( 'Save property', 'opalestate-pro' ), + ] ); ?> +
            +
            + + + +
            +
            +
            diff --git a/templates/user-management.php b/templates/user-management.php new file mode 100755 index 00000000..48e81e68 --- /dev/null +++ b/templates/user-management.php @@ -0,0 +1,125 @@ + + +
            +
            + + +
            + + +
            +
            +
            + +
            +
            +
            +
            +
            + + +
            + +
            +
            + +
            + +
            +
            +
            + +
            + + + + + + + + +
            +
            +
            +
            +
            + + +
            +
            +
            +
            +

            +

            +
            + +
            +
            +
            + + diff --git a/templates/user-search/content-savedsearch.php b/templates/user-search/content-savedsearch.php new file mode 100755 index 00000000..ea694e08 --- /dev/null +++ b/templates/user-search/content-savedsearch.php @@ -0,0 +1,43 @@ +get_list(); +// echo '
            '.print_r( $data,  1 );die;
            +?>
            +
            +
            +
            +	
            +
            +
            +

            +

            +
            +
            +
            + + \ No newline at end of file diff --git a/templates/user-search/render-form.php b/templates/user-search/render-form.php new file mode 100755 index 00000000..fd87314b --- /dev/null +++ b/templates/user-search/render-form.php @@ -0,0 +1,41 @@ + +
            + + + + + + +
            + diff --git a/templates/user/agency/agency-team.php b/templates/user/agency/agency-team.php new file mode 100755 index 00000000..48f3ff51 --- /dev/null +++ b/templates/user/agency/agency-team.php @@ -0,0 +1,79 @@ +get_members(); + +$sender_id = ''; +$prefix = ''; + +$fields = array( + + array( + 'id' => "sender_id", + 'name' => esc_html__( 'Sender ID', 'opalestate-pro' ), + 'type' => 'hidden', + 'default' => "", + 'description' => "", + ), + array( + 'id' => "{$prefix}user_id", + 'name' => esc_html__( 'Name', 'opalestate-pro' ), + 'type' => 'select', + 'class' => 'form-control opalesate-find-user', + 'default' => "", + 'required' => 'required', + 'description' => "", + ), + + + ); +$form = OpalEstate()->html->render_form( $fields ); +$id = 'agency-add-member'; +?> +
            + +

            +
            +
            +
            +

            +

            +
            + + + +
            +
            +
            + +
            +
            + + + + + + + ' . print_r( $user, 1);die; ?> + + + + + + +
            +
            + +
            ( )
            +
            +
            + "> + + +
            +
            +
            + +
            +
            diff --git a/templates/user/agency/profile-agency.php b/templates/user/agency/profile-agency.php new file mode 100755 index 00000000..cb0617d5 --- /dev/null +++ b/templates/user/agency/profile-agency.php @@ -0,0 +1,40 @@ + +
            + + + +
            + + + + +
            + +
            + + +
            + + + +
            + +
            +

            + + '.print_r( $metaboxes ,1 );die; + + if ( function_exists( 'cmb2_get_metabox_form' ) ) { + echo cmb2_get_metabox_form( $metaboxes[OPALESTATE_AGENCY_PREFIX.'front'], $post_id, array( + 'form_format' => '
            %3$s
            ', + 'save_button' => esc_html__( 'Save Change', 'opalestate-pro' ), + ) ); + } + + do_action( 'opalestate_profile_agency_form_after' ); + ?> +
            +
            +
            diff --git a/templates/user/agent/profile-agent.php b/templates/user/agent/profile-agent.php new file mode 100755 index 00000000..a187bceb --- /dev/null +++ b/templates/user/agent/profile-agent.php @@ -0,0 +1,27 @@ + +
            + +
            + +
            +

            + + + '
            %3$s
            ', + 'save_button' => esc_html__( 'Save Change', 'opalestate-pro' ), + ] ); + } + + do_action( 'opalestate_profile_agency_form_after' ); + ?> + +
            + +
            +
            +
            diff --git a/templates/user/content-property.php b/templates/user/content-property.php new file mode 100755 index 00000000..565d70db --- /dev/null +++ b/templates/user/content-property.php @@ -0,0 +1,100 @@ +get_meta_shortinfo(); +?> +
            > +
            +
            +
            + + featured != 1 ): ?> + + +
            + + +
            + +
            +
            +
            +
            + + + ', '' ); ?> + +
            + get_address(); ?> +
            + +
            + get_price() ); ?> + + get_sale_price() ): ?> + get_sale_price() ); ?> + + + get_price_label() ): ?> + get_price_label() ); ?> + +
            + +
            + +
            +
            +
              + + $info ) : ?> +
            • + + + +
            • + + +
            +
            +
            +
            + featured != 1 ): ?> + + + + + + + + + + ID, '', true ); + if ( ! empty( $delete_post_link ) ) { + ?> + + + + + +
            +
            + + +
            +
            diff --git a/templates/user/dashboard.php b/templates/user/dashboard.php new file mode 100755 index 00000000..5d4e5699 --- /dev/null +++ b/templates/user/dashboard.php @@ -0,0 +1,146 @@ +
            +
            + + + 'fa fa-list', + 'count' => $statistics->get_count_properties(), + 'label' => esc_html__( 'My Properties', 'opalestate-pro' ), + 'class' => 'bg-primary text-white', + ]; + + $properties_count[] = [ + 'icon' => 'fa fa-star', + 'count' => $statistics->get_count_featured(), + 'label' => esc_html__( 'Featured Properties', 'opalestate-pro' ), + 'class' => 'bg-info text-white', + ]; + + $properties_count[] = [ + 'icon' => 'fa fa-file', + 'count' => $statistics->get_count_pending_properties(), + 'label' => esc_html__( 'Pending Properties', 'opalestate-pro' ), + 'class' => 'bg-warning text-white', + ]; + ?> + + +
            +
            +

            +
            +
            +
            + + + + [ $current_user_id ], + 'status' => 'approve', + 'type' => 'property_review', + 'number' => 2, + ]; + + $comments = get_comments( $args ); + ?> + +
            +
            +

            + + +

            + +
            +
              + +
            1. +
              +
              + + +
              + +
              +

              + comment_author ); ?> + + +

              + + + +
              +
              + +
              + +
              +
                + $feature_title ) : $feature_key = $cpt_feature . '_' . $feature_slug; ?> +
              • + + comment_ID, $feature_key, true ) ); ?> +
              • + +
              +
              +
              + + + +
              + +
              +

              comment_content ); ?>

              +
              +
              +
              + +
              + comment_post_ID ); ?> + +
              + + + +
              + + +
              + + + +
              +
              +
              +
            2. + +
            +
            + + +
            +
            + + +
            +
            diff --git a/templates/user/favorite-button.php b/templates/user/favorite-button.php new file mode 100755 index 00000000..82499ee7 --- /dev/null +++ b/templates/user/favorite-button.php @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/templates/user/favorite-properties.php b/templates/user/favorite-properties.php new file mode 100755 index 00000000..77c77f6d --- /dev/null +++ b/templates/user/favorite-properties.php @@ -0,0 +1,29 @@ +have_posts() ): ?> +
            +
            + +
            +
            + have_posts() ) : $loop->the_post(); global $post; ?> + +
            + +
            + + +
            +
            + max_num_pages ); ?> +
            +
            + +
            +
            +
            +

            No Item In Favorite

            +

            +
            +
            +
            + + \ No newline at end of file diff --git a/templates/user/login-form.php b/templates/user/login-form.php new file mode 100755 index 00000000..fac0ffab --- /dev/null +++ b/templates/user/login-form.php @@ -0,0 +1,63 @@ + + +
            + +

            + + + +

            + + + +
            diff --git a/templates/user/messages.php b/templates/user/messages.php new file mode 100755 index 00000000..23d1f045 --- /dev/null +++ b/templates/user/messages.php @@ -0,0 +1,46 @@ + isset( $_GET['cpage'] ) ? abs( (int) $_GET['cpage'] ) : 1, + 'items_per_page' => 10 +); +$messages = opalestate_get_message_by_user( $args ); +?> +
            +

            +
            +
            + + + + + + + + + +
            + <?php esc_attr_e( 'User Avatar', 'opalestate-pro' ); ?> + sender_id ); ?> + + +
            subject ); ?>
            +

            message ); ?>

            +
            +
            created ); ?>
            +
            + +
            + add_query_arg( 'cpage', '%#%' ), + 'format' => '', + 'prev_text' => esc_html__('«'), + 'next_text' => esc_html__('»'), + 'total' => ceil( $messages['total'] / $args['items_per_page'] ), + 'current' => $args['cpage'] + )); + ?> +
            +
            +
            diff --git a/templates/user/my-account-popup.php b/templates/user/my-account-popup.php new file mode 100755 index 00000000..0e65432f --- /dev/null +++ b/templates/user/my-account-popup.php @@ -0,0 +1,30 @@ +
            +
            + +
            +
            + '', + 'redirect' => '', + 'hide_title' => false + ); + echo opalestate_load_template_path( 'user/login-form', $atts ); + ?> +
            +
            + '', + 'redirect' => '', + 'hide_title' => false + ); + echo opalestate_load_template_path( 'user/register-form', $atts ); + ?> +
            +
            +
            +
            \ No newline at end of file diff --git a/templates/user/my-account.php b/templates/user/my-account.php new file mode 100755 index 00000000..a8a3fa18 --- /dev/null +++ b/templates/user/my-account.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/templates/user/my-properties.php b/templates/user/my-properties.php new file mode 100755 index 00000000..eff4dfa1 --- /dev/null +++ b/templates/user/my-properties.php @@ -0,0 +1,54 @@ + esc_html__( 'All' ,'opalestate-pro' ), + 'published' => esc_html__( 'Published' ,'opalestate-pro' ), + 'pending' => esc_html__( 'Pending' ,'opalestate-pro' ), + 'expired' => esc_html__( 'Expired' ,'opalestate-pro' ), + ); + + $gstatus = isset( $_GET['status'] )? $_GET['status']:'all'; +?> + +
            + +
            +
            +
              + $label ): ?> +
            • class="active" > + +
            • + +
            +
            +
            + +
            + +
            + + have_posts() ): ?> +
            +
            + have_posts() ) : $loop->the_post(); global $post; ?> + + +
            + +
            + + +
            +
            + max_num_pages ); ?> + + +
            + +
            + +
            +
            +
            + + \ No newline at end of file diff --git a/templates/user/profile.php b/templates/user/profile.php new file mode 100755 index 00000000..fbc48578 --- /dev/null +++ b/templates/user/profile.php @@ -0,0 +1,60 @@ +
            + + + +
            + + + + +
            + +
            + + +
            + + + +
            + +
            +

            + + '
            %3$s
            ', + 'save_button' => esc_html__( 'Save Change', 'opalestate-pro' ), + ) ); + } + + do_action( 'opalestate_profile_form_after' ); + ?> +
            +
            + +
            +
            +

            + + + '
            %3$s
            ', + 'save_button' => esc_html__( 'Save Change', 'opalestate-pro' ), + ] ); + } + + do_action( 'opalestate_profile_form_after' ); + ?> + + +
            +
            +
            diff --git a/templates/user/property-ratings.php b/templates/user/property-ratings.php new file mode 100755 index 00000000..37cdc78c --- /dev/null +++ b/templates/user/property-ratings.php @@ -0,0 +1,99 @@ +' . esc_html__( 'You have not written any reviews yet.', 'opalestate-pro' ) . '

            '; + + return; +} + +wp_enqueue_style( "tooltipster" ); +wp_enqueue_script( "tooltipster" ); +?> + +
            +
              + +
            1. +
              +
              + + +
              + +
              +

              + comment_author ); ?> + + +

              + + + +
              +
              + +
              + +
              +
                + $feature_title ) : $feature_key = $cpt_feature . '_' . $feature_slug; ?> +
              • + + comment_ID, $feature_key, true ) ); ?> +
              • + +
              +
              +
              + + + +
              + +
              +

              comment_content ); ?>

              +
              +
              +
              + +
              + comment_post_ID ); ?> + +
              + + + +
              + + +
              + + + +
              +
              +
              +
            2. + +
            +
            diff --git a/templates/user/read-messages.php b/templates/user/read-messages.php new file mode 100755 index 00000000..6c84c868 --- /dev/null +++ b/templates/user/read-messages.php @@ -0,0 +1,50 @@ +html->render_form( $fields ); +$id = 'message-reply'; +?> +
            + +
            / + subject ); ?> +
            + +
            +
            + +
            +
            + <?php esc_attr_e( 'User Avatar', 'opalestate-pro' ); ?> +
            +
            +
            created ); ?>
            + message ); ?> +
            +
            + + + +
            +
            + <?php esc_attr_e( 'User Avatar', 'opalestate-pro' ); ?> +
            +
            +
            created; ?>
            + message; ?> +
            +
            + + + +
            +
            +
            + + +
            + + +
            +
            +
            + + diff --git a/templates/user/register-form.php b/templates/user/register-form.php new file mode 100755 index 00000000..ef1f3407 --- /dev/null +++ b/templates/user/register-form.php @@ -0,0 +1,98 @@ + + * @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/support/forum.html + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; // Exit if accessed directly +} + +opalestate_print_notices(); + +if ( is_user_logged_in() ) { + _e( 'You are currently logged in.', 'opalestate-pro' ); + + return; +} + +$types = OpalEstate_User::get_user_types(); +?> +
            + +

            + + + +

            + + +
            + + + +

            + + +

            + + + +

            + + +

            + +

            + + +

            + + + +

            + + +

            + + + +

            + + + +

            + + + + +

            + + + + + +

            + + +
            +
            diff --git a/templates/user/share-search-form.php b/templates/user/share-search-form.php new file mode 100755 index 00000000..28ad0826 --- /dev/null +++ b/templates/user/share-search-form.php @@ -0,0 +1,58 @@ + + +
            + + + + +
            + diff --git a/templates/user/social-login/facebook-button.php b/templates/user/social-login/facebook-button.php new file mode 100755 index 00000000..da4ceae6 --- /dev/null +++ b/templates/user/social-login/facebook-button.php @@ -0,0 +1,21 @@ + + + diff --git a/templates/user/social-login/google-button.php b/templates/user/social-login/google-button.php new file mode 100755 index 00000000..6715d45d --- /dev/null +++ b/templates/user/social-login/google-button.php @@ -0,0 +1,21 @@ + + diff --git a/templates/user/social-login/social-login.php b/templates/user/social-login/social-login.php new file mode 100755 index 00000000..5580215b --- /dev/null +++ b/templates/user/social-login/social-login.php @@ -0,0 +1,22 @@ + + + diff --git a/templates/widgets/featured-properties.php b/templates/widgets/featured-properties.php new file mode 100755 index 00000000..660afbbb --- /dev/null +++ b/templates/widgets/featured-properties.php @@ -0,0 +1,73 @@ + + * @copyright Copyright (C) 2015 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +$query = Opalestate_Query::get_featured_properties_query( [ "posts_per_page" => $num ] ); + +if ( $query->have_posts() ): + + echo trim( $before_widget ); + //Our variables from the widget settings. + $title = apply_filters( 'widget_title', esc_attr( $instance['title'] ) ); + if ( $title ) { + echo ( $before_title ) . trim( $title ) . $after_title; + } + ?> + +
            + have_posts() ): $query->the_post(); + $property = opalesetate_property( get_the_ID() ); + $meta = $property->get_meta_shortinfo(); + ?> +
            > +
            +
            + +
            + + + +
            + +
            + +
            +
            + ', '' ); ?> + +
            + get_price() ); ?> + + get_sale_price() ): ?> + + get_sale_price() ); ?> + + + + get_price_label() ): ?> + + get_price_label(); ?> + + +
            +
            +
            +
            +
            + +
            + + + diff --git a/templates/widgets/sameprice-properties.php b/templates/widgets/sameprice-properties.php new file mode 100755 index 00000000..46f4502b --- /dev/null +++ b/templates/widgets/sameprice-properties.php @@ -0,0 +1,126 @@ + + * @copyright Copyright (C) 2015 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + + +$args = [ + 'post_type' => 'opalestate_property', + 'posts_per_page' => $num, + 'post__not_in' => [ get_the_ID() ], +]; +$price = get_post_meta( get_the_ID(), OPALESTATE_PROPERTY_PREFIX . 'price', true ); + +$status = wp_get_post_terms( get_the_ID(), 'opalestate_status' ); + +$args['meta_query'] = []; + +$tax_query = []; + +if ( ! is_wp_error( $status ) && $status ) { + + $tax_query[] = + [ + 'taxonomy' => 'opalestate_status', + 'field' => 'slug', + 'terms' => $status[0]->slug, + ]; +} + +if ( $tax_query ) { + $args['tax_query'] = [ 'relation' => 'AND' ]; + $args['tax_query'] = array_merge( $args['tax_query'], $tax_query ); +} + +$search_min_price = floatval( $price ) - floatval( $range_price ); +$search_max_price = floatval( $price ) + floatval( $range_price ); + +if ( $search_min_price != '' && $search_min_price != '' && is_numeric( $search_min_price ) && is_numeric( $search_max_price ) ) { + array_push( $args['meta_query'], [ + 'key' => OPALESTATE_PROPERTY_PREFIX . 'price', + 'value' => [ $search_min_price, $search_max_price ], + 'compare' => 'BETWEEN', + 'type' => 'NUMERIC', + ] ); +} elseif ( $search_min_price != '' && is_numeric( $search_min_price ) ) { + array_push( $args['meta_query'], [ + 'key' => OPALESTATE_PROPERTY_PREFIX . 'price', + 'value' => $search_min_price, + 'compare' => '>=', + 'type' => 'NUMERIC', + ] ); +} elseif ( $search_max_price != '' && is_numeric( $search_max_price ) ) { + array_push( $args['meta_query'], [ + 'key' => OPALESTATE_PROPERTY_PREFIX . 'price', + 'value' => $search_max_price, + 'compare' => '<=', + 'type' => 'NUMERIC', + ] ); +} +$query = Opalestate_Query::get_property_query( $args ); +if ( $query->have_posts() ): + echo str_replace( 'widget-style', 'widget-style widget-danger', trim( $before_widget ) ); + //Our variables from the widget settings. + $title = apply_filters( 'widget_title', $title ); + + if ( $title ) { + echo ( $before_title ) . trim( $title ) . $after_title; + } + ?> +
            + have_posts() ): $query->the_post(); + $property = opalesetate_property( get_the_ID() ); + $meta = $property->get_meta_shortinfo(); + ?> +
            > +
            +
            + +
            + + + +
            + +
            +
            +
            + + ', '' ); ?> + +
            + get_price() ); ?> + + get_sale_price() ): ?> + + get_sale_price() ); ?> + + + + get_price_label() ): ?> + + get_price_label(); ?> + + +
            +
            +
            +
            +
            + +
            + + + + diff --git a/templates/widgets/similar-properties.php b/templates/widgets/similar-properties.php new file mode 100755 index 00000000..fc295084 --- /dev/null +++ b/templates/widgets/similar-properties.php @@ -0,0 +1,111 @@ + + * @copyright Copyright (C) 2015 wpopal.com. All Rights Reserved. + * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html + * + * @website http://www.wpopal.com + * @support http://www.wpopal.com/questions/ + */ +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + + +$args = [ + 'post_type' => 'opalestate_property', + 'posts_per_page' => $num, + 'post__not_in' => [ get_the_ID() ], +]; + +$terms = wp_get_post_terms( get_the_ID(), 'opalestate_types' ); + +$tax_query = []; +if ( $terms ) { + $tax_query[] = [ + [ + 'taxonomy' => 'opalestate_types', + 'field' => 'slug', + 'terms' => $terms[0]->slug, + ], + ]; +} + +$status = wp_get_post_terms( get_the_ID(), 'opalestate_status' ); +if ( ! is_wp_error( $status ) && $status ) { + $tax_query[] = + [ + 'taxonomy' => 'opalestate_status', + 'field' => 'slug', + 'terms' => $status[0]->slug, + + ]; +} + + +if ( $tax_query ) { + $args['tax_query'] = [ 'relation' => 'AND' ]; + $args['tax_query'] = array_merge( $args['tax_query'], $tax_query ); +} +$query = Opalestate_Query::get_property_query( $args ); + +if ( $query->have_posts() ): + + echo trim( $before_widget ); + //Our variables from the widget settings. + $title = apply_filters( 'widget_title', esc_attr( $instance['title'] ) ); + + if ( $title ) { + echo ( $before_title ) . trim( $title ) . $after_title; + } + ?> + +
            + have_posts() ): $query->the_post(); + $property = opalesetate_property( get_the_ID() ); + $meta = $property->get_meta_shortinfo(); + ?> +
            > +
            +
            + +
            + + + +
            + +
            +
            +
            + ', '' ); ?> + +
            + get_price() ); ?> + + get_sale_price() ): ?> + + get_sale_price() ); ?> + + + + get_price_label() ): ?> + + get_price_label(); ?> + + +
            +
            +
            +
            +
            + +
            + + + + diff --git a/uninstall.php b/uninstall.php new file mode 100755 index 00000000..19fd3b34 --- /dev/null +++ b/uninstall.php @@ -0,0 +1,10 @@ + + + opalestate_property + opalestate_agency + opalestate_agent + + + property_category + opalestate_amenities + opalestate_label + opalestate_location + opalestate_state + opalestate_city + opalestate_status + opalestate_types + opalestate_rating_ft + opalestate_agency_ft + opalestate_agent_ft + + + opalestate_ppt_featured + opalestate_ppt_sku + opalestate_ppt_map + opalestate_ppt_zipcode + opalestate_ppt_enablemapview + opalestate_ppt_video + opalestate_ppt_builtyear + opalestate_ppt_parking + opalestate_ppt_bedrooms + opalestate_ppt_bathrooms + opalestate_ppt_plotsize + opalestate_ppt_areasize + opalestate_ppt_orientation + opalestate_ppt_kitchens + opalestate_ppt_livingrooms + opalestate_ppt_amountrooms + opalestate_ppt_gallery + opalestate_ppt_virtual + +